HashMap gets wrong size












4















I am trying to export some keys as byte from a HashSet to a HashMap and use the HashMap do store pairs of data. However, I am running into a problem, which is that the size om the set is larger than the size of the HashMap, for some reason. I would like to know what causes this as the HashMap is within a foreach which iterates from 0 to the size of the HashSet, namely 2^20. So, I am also expecting the size of the HashMap also to be 2^20.



So, what I am trying to store in the HashMap is two byte arrays. I am currently working with the meet-in-the-middle attack on 2DES. My encryption are properly implemented. In addition, my DES key generator is also properly implemented, so I am able to generate 2^20 keys (only 20 bits of the keys are effective). However, I when I try to put the keys in the HashMap the size is not the same as the HashSet, which doesn't make any sense.



for (int i = 0; i < Math.pow(2, 20); i++) {
possibleKeySet.add(generateDesKey());
}

for (byte key : possibleKeySet) {
intermediateCipher.put((encrypt(key, plainText)).toString(), key);
}


Output:
Set size: 1048576
Map size: 1048295



PS: intermediateCipher is my HashMap.



Update:
I have tried to implement hashcode and equals, but i'm not sure how to implement hashcode.



class ByteArray {

private byte key;

ByteArray(byte key) {
this.key = key;
}

byte getKey() {
return key;
}

public boolean equals(Object obj) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(obj);
oos.writeObject(obj);
oos.flush();
byte data = bos.toByteArray();
return key.equals(data);
}

public int hashCode() {
// what should I write here?
}

}









share|improve this question

























  • You probably have a collision on keys. You can check it by checking the return value of put method. If no collision occurs it will return null.

    – ByeBye
    Nov 22 '18 at 22:51













  • But a set doesn't allow duplicates? so, that should not be any collision?

    – user8231110
    Nov 22 '18 at 22:53













  • (encrypt(key, plainText) this will probably produce duplicates. You can check it by adding if(putReturn != null) sysout(putReturn)

    – ByeBye
    Nov 22 '18 at 22:55











  • I tried with if (intermediateCipher.get(key) != null) {System.out.println("NULL");} but it did never print "NULL"

    – user8231110
    Nov 22 '18 at 23:01






  • 1





    He is using byte as a key ... so duplicates are possible.

    – Stephen C
    Nov 22 '18 at 23:55
















4















I am trying to export some keys as byte from a HashSet to a HashMap and use the HashMap do store pairs of data. However, I am running into a problem, which is that the size om the set is larger than the size of the HashMap, for some reason. I would like to know what causes this as the HashMap is within a foreach which iterates from 0 to the size of the HashSet, namely 2^20. So, I am also expecting the size of the HashMap also to be 2^20.



So, what I am trying to store in the HashMap is two byte arrays. I am currently working with the meet-in-the-middle attack on 2DES. My encryption are properly implemented. In addition, my DES key generator is also properly implemented, so I am able to generate 2^20 keys (only 20 bits of the keys are effective). However, I when I try to put the keys in the HashMap the size is not the same as the HashSet, which doesn't make any sense.



for (int i = 0; i < Math.pow(2, 20); i++) {
possibleKeySet.add(generateDesKey());
}

for (byte key : possibleKeySet) {
intermediateCipher.put((encrypt(key, plainText)).toString(), key);
}


Output:
Set size: 1048576
Map size: 1048295



PS: intermediateCipher is my HashMap.



Update:
I have tried to implement hashcode and equals, but i'm not sure how to implement hashcode.



class ByteArray {

private byte key;

ByteArray(byte key) {
this.key = key;
}

byte getKey() {
return key;
}

public boolean equals(Object obj) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(obj);
oos.writeObject(obj);
oos.flush();
byte data = bos.toByteArray();
return key.equals(data);
}

public int hashCode() {
// what should I write here?
}

}









share|improve this question

























  • You probably have a collision on keys. You can check it by checking the return value of put method. If no collision occurs it will return null.

    – ByeBye
    Nov 22 '18 at 22:51













  • But a set doesn't allow duplicates? so, that should not be any collision?

    – user8231110
    Nov 22 '18 at 22:53













  • (encrypt(key, plainText) this will probably produce duplicates. You can check it by adding if(putReturn != null) sysout(putReturn)

    – ByeBye
    Nov 22 '18 at 22:55











  • I tried with if (intermediateCipher.get(key) != null) {System.out.println("NULL");} but it did never print "NULL"

    – user8231110
    Nov 22 '18 at 23:01






  • 1





    He is using byte as a key ... so duplicates are possible.

    – Stephen C
    Nov 22 '18 at 23:55














4












4








4


0






I am trying to export some keys as byte from a HashSet to a HashMap and use the HashMap do store pairs of data. However, I am running into a problem, which is that the size om the set is larger than the size of the HashMap, for some reason. I would like to know what causes this as the HashMap is within a foreach which iterates from 0 to the size of the HashSet, namely 2^20. So, I am also expecting the size of the HashMap also to be 2^20.



So, what I am trying to store in the HashMap is two byte arrays. I am currently working with the meet-in-the-middle attack on 2DES. My encryption are properly implemented. In addition, my DES key generator is also properly implemented, so I am able to generate 2^20 keys (only 20 bits of the keys are effective). However, I when I try to put the keys in the HashMap the size is not the same as the HashSet, which doesn't make any sense.



for (int i = 0; i < Math.pow(2, 20); i++) {
possibleKeySet.add(generateDesKey());
}

for (byte key : possibleKeySet) {
intermediateCipher.put((encrypt(key, plainText)).toString(), key);
}


Output:
Set size: 1048576
Map size: 1048295



PS: intermediateCipher is my HashMap.



Update:
I have tried to implement hashcode and equals, but i'm not sure how to implement hashcode.



class ByteArray {

private byte key;

ByteArray(byte key) {
this.key = key;
}

byte getKey() {
return key;
}

public boolean equals(Object obj) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(obj);
oos.writeObject(obj);
oos.flush();
byte data = bos.toByteArray();
return key.equals(data);
}

public int hashCode() {
// what should I write here?
}

}









share|improve this question
















I am trying to export some keys as byte from a HashSet to a HashMap and use the HashMap do store pairs of data. However, I am running into a problem, which is that the size om the set is larger than the size of the HashMap, for some reason. I would like to know what causes this as the HashMap is within a foreach which iterates from 0 to the size of the HashSet, namely 2^20. So, I am also expecting the size of the HashMap also to be 2^20.



So, what I am trying to store in the HashMap is two byte arrays. I am currently working with the meet-in-the-middle attack on 2DES. My encryption are properly implemented. In addition, my DES key generator is also properly implemented, so I am able to generate 2^20 keys (only 20 bits of the keys are effective). However, I when I try to put the keys in the HashMap the size is not the same as the HashSet, which doesn't make any sense.



for (int i = 0; i < Math.pow(2, 20); i++) {
possibleKeySet.add(generateDesKey());
}

for (byte key : possibleKeySet) {
intermediateCipher.put((encrypt(key, plainText)).toString(), key);
}


Output:
Set size: 1048576
Map size: 1048295



PS: intermediateCipher is my HashMap.



Update:
I have tried to implement hashcode and equals, but i'm not sure how to implement hashcode.



class ByteArray {

private byte key;

ByteArray(byte key) {
this.key = key;
}

byte getKey() {
return key;
}

public boolean equals(Object obj) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(obj);
oos.writeObject(obj);
oos.flush();
byte data = bos.toByteArray();
return key.equals(data);
}

public int hashCode() {
// what should I write here?
}

}






java hashmap set






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 '18 at 17:39







user8231110

















asked Nov 22 '18 at 22:49









user8231110user8231110

486




486













  • You probably have a collision on keys. You can check it by checking the return value of put method. If no collision occurs it will return null.

    – ByeBye
    Nov 22 '18 at 22:51













  • But a set doesn't allow duplicates? so, that should not be any collision?

    – user8231110
    Nov 22 '18 at 22:53













  • (encrypt(key, plainText) this will probably produce duplicates. You can check it by adding if(putReturn != null) sysout(putReturn)

    – ByeBye
    Nov 22 '18 at 22:55











  • I tried with if (intermediateCipher.get(key) != null) {System.out.println("NULL");} but it did never print "NULL"

    – user8231110
    Nov 22 '18 at 23:01






  • 1





    He is using byte as a key ... so duplicates are possible.

    – Stephen C
    Nov 22 '18 at 23:55



















  • You probably have a collision on keys. You can check it by checking the return value of put method. If no collision occurs it will return null.

    – ByeBye
    Nov 22 '18 at 22:51













  • But a set doesn't allow duplicates? so, that should not be any collision?

    – user8231110
    Nov 22 '18 at 22:53













  • (encrypt(key, plainText) this will probably produce duplicates. You can check it by adding if(putReturn != null) sysout(putReturn)

    – ByeBye
    Nov 22 '18 at 22:55











  • I tried with if (intermediateCipher.get(key) != null) {System.out.println("NULL");} but it did never print "NULL"

    – user8231110
    Nov 22 '18 at 23:01






  • 1





    He is using byte as a key ... so duplicates are possible.

    – Stephen C
    Nov 22 '18 at 23:55

















You probably have a collision on keys. You can check it by checking the return value of put method. If no collision occurs it will return null.

– ByeBye
Nov 22 '18 at 22:51







You probably have a collision on keys. You can check it by checking the return value of put method. If no collision occurs it will return null.

– ByeBye
Nov 22 '18 at 22:51















But a set doesn't allow duplicates? so, that should not be any collision?

– user8231110
Nov 22 '18 at 22:53







But a set doesn't allow duplicates? so, that should not be any collision?

– user8231110
Nov 22 '18 at 22:53















(encrypt(key, plainText) this will probably produce duplicates. You can check it by adding if(putReturn != null) sysout(putReturn)

– ByeBye
Nov 22 '18 at 22:55





(encrypt(key, plainText) this will probably produce duplicates. You can check it by adding if(putReturn != null) sysout(putReturn)

– ByeBye
Nov 22 '18 at 22:55













I tried with if (intermediateCipher.get(key) != null) {System.out.println("NULL");} but it did never print "NULL"

– user8231110
Nov 22 '18 at 23:01





I tried with if (intermediateCipher.get(key) != null) {System.out.println("NULL");} but it did never print "NULL"

– user8231110
Nov 22 '18 at 23:01




1




1





He is using byte as a key ... so duplicates are possible.

– Stephen C
Nov 22 '18 at 23:55





He is using byte as a key ... so duplicates are possible.

– Stephen C
Nov 22 '18 at 23:55












3 Answers
3






active

oldest

votes


















3














The probability of a hash collision is (as can be seen here):



graph



The average number of collisions for a set of size n given k inputs is:



N(n,k)~=k(k-1)/(2n)



Given an n of 2^32 and a k of 2^20, the average collision is



(2^20) * (2^20 - 1) / (2 * 2^32)
~= 2^40/2^33
~= 2^7
~= 128


The number of collisions you saw was 1048576 - 1048295 = 281. Given this info I assume that the actual entropy of the value returned by encrypt(key, plainText) is roughly ~31 bits (rather than 32).





To get the desired amount of keys, you may want to just keep generating values until you reach the desired size. This may make the method take a long time to complete:



while (intermediateCipher.size() < Math.pow(2,20)) {
byte key = generateDesKey();
intermediateCipher.put((encrypt(key, plainText)).toString(), key);
}








share|improve this answer


























  • Very interesting, but how do I avoid the collision?

    – user8231110
    Nov 22 '18 at 23:30











  • Even with hash collision HashSet and HashMap is using equals for checking collision (So first hashCode bucket, then a list with equals checking). In my answer, I provide a full solution to the problem.

    – ByeBye
    Nov 22 '18 at 23:32













  • @user8231110 I added a simple way to get the desired size!

    – flakes
    Nov 22 '18 at 23:35











  • but possibleKeySet.add(generateDesKey()); is a HashSet, so I cannot store it in a byte

    – user8231110
    Nov 22 '18 at 23:42








  • 1





    "Very interesting, but how do I avoid the collision?" - You can't. You don't. You detect the collision ... and generate another key to replace it. @flakes - the collisions are in possibleKeySet!

    – Stephen C
    Nov 22 '18 at 23:56





















1














If your Set and HashMap have a different size it will probably be a collision on keys.
It looks like your function encrypt(key, plainText) return duplicates.



Try with:



for (byte key : possibleKeySet) {
Object oldValue = intermediateCipher.put((encrypt(key, plainText)).toString(), key);
if(oldValue != null) {
System.out.println("Duplicated!");
}
}


It will probably produce some errors.



Take a note also, that generateDesKey() can also produce the same values even if they are stored in Set as two arrays in Java are only equal if they are the same object.



What you can do? Create a custom object:



class ByteArray {

private byte key;

ByteArray(byte key) {
this.key = key;
}

byte getKey() {
return key;
}

public boolean equals(Object obj) {
//implement your equals logic using array members equality
}

public int hashCode() {
//implement your hashCode logic using array members equality
}

}





share|improve this answer


























  • Yes, you are right. I do have some duplicates. How do I then make sure that the keys in the Set are unique. Then using it makes no sense, if the values in the Set aren't unique

    – user8231110
    Nov 22 '18 at 23:15











  • You can use a new custom object which will store your array as a field and then override hashCode and equals to check what is INSIDE array.

    – ByeBye
    Nov 22 '18 at 23:16











  • They are unique only by design of equals of an array. Not unique in by author algorithm design - the array is not fit here to be used as part of a set.

    – ByeBye
    Nov 22 '18 at 23:19











  • I think the symptoms mean that your generateDesKey is generating non-unique keys ... as well.

    – Stephen C
    Nov 22 '18 at 23:30






  • 1





    What is your question now? I provide a solution and answer why your set size is different than HashSet size. If you have another question - in the example with helping create better function it should be a new separate question.

    – ByeBye
    Nov 22 '18 at 23:37



















0














The set itself is being implemented that way that every item inside must be unique - it does not allow duplicates. That means that when you are putting to set two equal objects in result in set there will be only one.



Probably your generateDesKey() method is returning not unique values for all of 2^20 values and in the result set the items count is less than 2^20



Basically you can check the possibleKeySet size before copying values to the HashMap like



System.out.println(possibleKeySet.size());


or just by using debugger






share|improve this answer
























  • I did that and the size is 1048576 (2^20)

    – user8231110
    Nov 22 '18 at 22:55













  • ok that's weird :)

    – m.antkowicz
    Nov 22 '18 at 23:04






  • 1





    Actually, not weird. Bytearrays (arrays in general) can't be used as keys in a HashSet or HashMap. Because of the semantics of equals. See ByeBye's answer.

    – Stephen C
    Nov 22 '18 at 23:31













  • But he is using a String as the key

    – Bab
    Nov 23 '18 at 20:31











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438795%2fhashmap-gets-wrong-size%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









3














The probability of a hash collision is (as can be seen here):



graph



The average number of collisions for a set of size n given k inputs is:



N(n,k)~=k(k-1)/(2n)



Given an n of 2^32 and a k of 2^20, the average collision is



(2^20) * (2^20 - 1) / (2 * 2^32)
~= 2^40/2^33
~= 2^7
~= 128


The number of collisions you saw was 1048576 - 1048295 = 281. Given this info I assume that the actual entropy of the value returned by encrypt(key, plainText) is roughly ~31 bits (rather than 32).





To get the desired amount of keys, you may want to just keep generating values until you reach the desired size. This may make the method take a long time to complete:



while (intermediateCipher.size() < Math.pow(2,20)) {
byte key = generateDesKey();
intermediateCipher.put((encrypt(key, plainText)).toString(), key);
}








share|improve this answer


























  • Very interesting, but how do I avoid the collision?

    – user8231110
    Nov 22 '18 at 23:30











  • Even with hash collision HashSet and HashMap is using equals for checking collision (So first hashCode bucket, then a list with equals checking). In my answer, I provide a full solution to the problem.

    – ByeBye
    Nov 22 '18 at 23:32













  • @user8231110 I added a simple way to get the desired size!

    – flakes
    Nov 22 '18 at 23:35











  • but possibleKeySet.add(generateDesKey()); is a HashSet, so I cannot store it in a byte

    – user8231110
    Nov 22 '18 at 23:42








  • 1





    "Very interesting, but how do I avoid the collision?" - You can't. You don't. You detect the collision ... and generate another key to replace it. @flakes - the collisions are in possibleKeySet!

    – Stephen C
    Nov 22 '18 at 23:56


















3














The probability of a hash collision is (as can be seen here):



graph



The average number of collisions for a set of size n given k inputs is:



N(n,k)~=k(k-1)/(2n)



Given an n of 2^32 and a k of 2^20, the average collision is



(2^20) * (2^20 - 1) / (2 * 2^32)
~= 2^40/2^33
~= 2^7
~= 128


The number of collisions you saw was 1048576 - 1048295 = 281. Given this info I assume that the actual entropy of the value returned by encrypt(key, plainText) is roughly ~31 bits (rather than 32).





To get the desired amount of keys, you may want to just keep generating values until you reach the desired size. This may make the method take a long time to complete:



while (intermediateCipher.size() < Math.pow(2,20)) {
byte key = generateDesKey();
intermediateCipher.put((encrypt(key, plainText)).toString(), key);
}








share|improve this answer


























  • Very interesting, but how do I avoid the collision?

    – user8231110
    Nov 22 '18 at 23:30











  • Even with hash collision HashSet and HashMap is using equals for checking collision (So first hashCode bucket, then a list with equals checking). In my answer, I provide a full solution to the problem.

    – ByeBye
    Nov 22 '18 at 23:32













  • @user8231110 I added a simple way to get the desired size!

    – flakes
    Nov 22 '18 at 23:35











  • but possibleKeySet.add(generateDesKey()); is a HashSet, so I cannot store it in a byte

    – user8231110
    Nov 22 '18 at 23:42








  • 1





    "Very interesting, but how do I avoid the collision?" - You can't. You don't. You detect the collision ... and generate another key to replace it. @flakes - the collisions are in possibleKeySet!

    – Stephen C
    Nov 22 '18 at 23:56
















3












3








3







The probability of a hash collision is (as can be seen here):



graph



The average number of collisions for a set of size n given k inputs is:



N(n,k)~=k(k-1)/(2n)



Given an n of 2^32 and a k of 2^20, the average collision is



(2^20) * (2^20 - 1) / (2 * 2^32)
~= 2^40/2^33
~= 2^7
~= 128


The number of collisions you saw was 1048576 - 1048295 = 281. Given this info I assume that the actual entropy of the value returned by encrypt(key, plainText) is roughly ~31 bits (rather than 32).





To get the desired amount of keys, you may want to just keep generating values until you reach the desired size. This may make the method take a long time to complete:



while (intermediateCipher.size() < Math.pow(2,20)) {
byte key = generateDesKey();
intermediateCipher.put((encrypt(key, plainText)).toString(), key);
}








share|improve this answer















The probability of a hash collision is (as can be seen here):



graph



The average number of collisions for a set of size n given k inputs is:



N(n,k)~=k(k-1)/(2n)



Given an n of 2^32 and a k of 2^20, the average collision is



(2^20) * (2^20 - 1) / (2 * 2^32)
~= 2^40/2^33
~= 2^7
~= 128


The number of collisions you saw was 1048576 - 1048295 = 281. Given this info I assume that the actual entropy of the value returned by encrypt(key, plainText) is roughly ~31 bits (rather than 32).





To get the desired amount of keys, you may want to just keep generating values until you reach the desired size. This may make the method take a long time to complete:



while (intermediateCipher.size() < Math.pow(2,20)) {
byte key = generateDesKey();
intermediateCipher.put((encrypt(key, plainText)).toString(), key);
}









share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 27 '18 at 3:38

























answered Nov 22 '18 at 23:25









flakesflakes

6,54111850




6,54111850













  • Very interesting, but how do I avoid the collision?

    – user8231110
    Nov 22 '18 at 23:30











  • Even with hash collision HashSet and HashMap is using equals for checking collision (So first hashCode bucket, then a list with equals checking). In my answer, I provide a full solution to the problem.

    – ByeBye
    Nov 22 '18 at 23:32













  • @user8231110 I added a simple way to get the desired size!

    – flakes
    Nov 22 '18 at 23:35











  • but possibleKeySet.add(generateDesKey()); is a HashSet, so I cannot store it in a byte

    – user8231110
    Nov 22 '18 at 23:42








  • 1





    "Very interesting, but how do I avoid the collision?" - You can't. You don't. You detect the collision ... and generate another key to replace it. @flakes - the collisions are in possibleKeySet!

    – Stephen C
    Nov 22 '18 at 23:56





















  • Very interesting, but how do I avoid the collision?

    – user8231110
    Nov 22 '18 at 23:30











  • Even with hash collision HashSet and HashMap is using equals for checking collision (So first hashCode bucket, then a list with equals checking). In my answer, I provide a full solution to the problem.

    – ByeBye
    Nov 22 '18 at 23:32













  • @user8231110 I added a simple way to get the desired size!

    – flakes
    Nov 22 '18 at 23:35











  • but possibleKeySet.add(generateDesKey()); is a HashSet, so I cannot store it in a byte

    – user8231110
    Nov 22 '18 at 23:42








  • 1





    "Very interesting, but how do I avoid the collision?" - You can't. You don't. You detect the collision ... and generate another key to replace it. @flakes - the collisions are in possibleKeySet!

    – Stephen C
    Nov 22 '18 at 23:56



















Very interesting, but how do I avoid the collision?

– user8231110
Nov 22 '18 at 23:30





Very interesting, but how do I avoid the collision?

– user8231110
Nov 22 '18 at 23:30













Even with hash collision HashSet and HashMap is using equals for checking collision (So first hashCode bucket, then a list with equals checking). In my answer, I provide a full solution to the problem.

– ByeBye
Nov 22 '18 at 23:32







Even with hash collision HashSet and HashMap is using equals for checking collision (So first hashCode bucket, then a list with equals checking). In my answer, I provide a full solution to the problem.

– ByeBye
Nov 22 '18 at 23:32















@user8231110 I added a simple way to get the desired size!

– flakes
Nov 22 '18 at 23:35





@user8231110 I added a simple way to get the desired size!

– flakes
Nov 22 '18 at 23:35













but possibleKeySet.add(generateDesKey()); is a HashSet, so I cannot store it in a byte

– user8231110
Nov 22 '18 at 23:42







but possibleKeySet.add(generateDesKey()); is a HashSet, so I cannot store it in a byte

– user8231110
Nov 22 '18 at 23:42






1




1





"Very interesting, but how do I avoid the collision?" - You can't. You don't. You detect the collision ... and generate another key to replace it. @flakes - the collisions are in possibleKeySet!

– Stephen C
Nov 22 '18 at 23:56







"Very interesting, but how do I avoid the collision?" - You can't. You don't. You detect the collision ... and generate another key to replace it. @flakes - the collisions are in possibleKeySet!

– Stephen C
Nov 22 '18 at 23:56















1














If your Set and HashMap have a different size it will probably be a collision on keys.
It looks like your function encrypt(key, plainText) return duplicates.



Try with:



for (byte key : possibleKeySet) {
Object oldValue = intermediateCipher.put((encrypt(key, plainText)).toString(), key);
if(oldValue != null) {
System.out.println("Duplicated!");
}
}


It will probably produce some errors.



Take a note also, that generateDesKey() can also produce the same values even if they are stored in Set as two arrays in Java are only equal if they are the same object.



What you can do? Create a custom object:



class ByteArray {

private byte key;

ByteArray(byte key) {
this.key = key;
}

byte getKey() {
return key;
}

public boolean equals(Object obj) {
//implement your equals logic using array members equality
}

public int hashCode() {
//implement your hashCode logic using array members equality
}

}





share|improve this answer


























  • Yes, you are right. I do have some duplicates. How do I then make sure that the keys in the Set are unique. Then using it makes no sense, if the values in the Set aren't unique

    – user8231110
    Nov 22 '18 at 23:15











  • You can use a new custom object which will store your array as a field and then override hashCode and equals to check what is INSIDE array.

    – ByeBye
    Nov 22 '18 at 23:16











  • They are unique only by design of equals of an array. Not unique in by author algorithm design - the array is not fit here to be used as part of a set.

    – ByeBye
    Nov 22 '18 at 23:19











  • I think the symptoms mean that your generateDesKey is generating non-unique keys ... as well.

    – Stephen C
    Nov 22 '18 at 23:30






  • 1





    What is your question now? I provide a solution and answer why your set size is different than HashSet size. If you have another question - in the example with helping create better function it should be a new separate question.

    – ByeBye
    Nov 22 '18 at 23:37
















1














If your Set and HashMap have a different size it will probably be a collision on keys.
It looks like your function encrypt(key, plainText) return duplicates.



Try with:



for (byte key : possibleKeySet) {
Object oldValue = intermediateCipher.put((encrypt(key, plainText)).toString(), key);
if(oldValue != null) {
System.out.println("Duplicated!");
}
}


It will probably produce some errors.



Take a note also, that generateDesKey() can also produce the same values even if they are stored in Set as two arrays in Java are only equal if they are the same object.



What you can do? Create a custom object:



class ByteArray {

private byte key;

ByteArray(byte key) {
this.key = key;
}

byte getKey() {
return key;
}

public boolean equals(Object obj) {
//implement your equals logic using array members equality
}

public int hashCode() {
//implement your hashCode logic using array members equality
}

}





share|improve this answer


























  • Yes, you are right. I do have some duplicates. How do I then make sure that the keys in the Set are unique. Then using it makes no sense, if the values in the Set aren't unique

    – user8231110
    Nov 22 '18 at 23:15











  • You can use a new custom object which will store your array as a field and then override hashCode and equals to check what is INSIDE array.

    – ByeBye
    Nov 22 '18 at 23:16











  • They are unique only by design of equals of an array. Not unique in by author algorithm design - the array is not fit here to be used as part of a set.

    – ByeBye
    Nov 22 '18 at 23:19











  • I think the symptoms mean that your generateDesKey is generating non-unique keys ... as well.

    – Stephen C
    Nov 22 '18 at 23:30






  • 1





    What is your question now? I provide a solution and answer why your set size is different than HashSet size. If you have another question - in the example with helping create better function it should be a new separate question.

    – ByeBye
    Nov 22 '18 at 23:37














1












1








1







If your Set and HashMap have a different size it will probably be a collision on keys.
It looks like your function encrypt(key, plainText) return duplicates.



Try with:



for (byte key : possibleKeySet) {
Object oldValue = intermediateCipher.put((encrypt(key, plainText)).toString(), key);
if(oldValue != null) {
System.out.println("Duplicated!");
}
}


It will probably produce some errors.



Take a note also, that generateDesKey() can also produce the same values even if they are stored in Set as two arrays in Java are only equal if they are the same object.



What you can do? Create a custom object:



class ByteArray {

private byte key;

ByteArray(byte key) {
this.key = key;
}

byte getKey() {
return key;
}

public boolean equals(Object obj) {
//implement your equals logic using array members equality
}

public int hashCode() {
//implement your hashCode logic using array members equality
}

}





share|improve this answer















If your Set and HashMap have a different size it will probably be a collision on keys.
It looks like your function encrypt(key, plainText) return duplicates.



Try with:



for (byte key : possibleKeySet) {
Object oldValue = intermediateCipher.put((encrypt(key, plainText)).toString(), key);
if(oldValue != null) {
System.out.println("Duplicated!");
}
}


It will probably produce some errors.



Take a note also, that generateDesKey() can also produce the same values even if they are stored in Set as two arrays in Java are only equal if they are the same object.



What you can do? Create a custom object:



class ByteArray {

private byte key;

ByteArray(byte key) {
this.key = key;
}

byte getKey() {
return key;
}

public boolean equals(Object obj) {
//implement your equals logic using array members equality
}

public int hashCode() {
//implement your hashCode logic using array members equality
}

}






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 22 '18 at 23:22

























answered Nov 22 '18 at 23:07









ByeByeByeBye

3,4733939




3,4733939













  • Yes, you are right. I do have some duplicates. How do I then make sure that the keys in the Set are unique. Then using it makes no sense, if the values in the Set aren't unique

    – user8231110
    Nov 22 '18 at 23:15











  • You can use a new custom object which will store your array as a field and then override hashCode and equals to check what is INSIDE array.

    – ByeBye
    Nov 22 '18 at 23:16











  • They are unique only by design of equals of an array. Not unique in by author algorithm design - the array is not fit here to be used as part of a set.

    – ByeBye
    Nov 22 '18 at 23:19











  • I think the symptoms mean that your generateDesKey is generating non-unique keys ... as well.

    – Stephen C
    Nov 22 '18 at 23:30






  • 1





    What is your question now? I provide a solution and answer why your set size is different than HashSet size. If you have another question - in the example with helping create better function it should be a new separate question.

    – ByeBye
    Nov 22 '18 at 23:37



















  • Yes, you are right. I do have some duplicates. How do I then make sure that the keys in the Set are unique. Then using it makes no sense, if the values in the Set aren't unique

    – user8231110
    Nov 22 '18 at 23:15











  • You can use a new custom object which will store your array as a field and then override hashCode and equals to check what is INSIDE array.

    – ByeBye
    Nov 22 '18 at 23:16











  • They are unique only by design of equals of an array. Not unique in by author algorithm design - the array is not fit here to be used as part of a set.

    – ByeBye
    Nov 22 '18 at 23:19











  • I think the symptoms mean that your generateDesKey is generating non-unique keys ... as well.

    – Stephen C
    Nov 22 '18 at 23:30






  • 1





    What is your question now? I provide a solution and answer why your set size is different than HashSet size. If you have another question - in the example with helping create better function it should be a new separate question.

    – ByeBye
    Nov 22 '18 at 23:37

















Yes, you are right. I do have some duplicates. How do I then make sure that the keys in the Set are unique. Then using it makes no sense, if the values in the Set aren't unique

– user8231110
Nov 22 '18 at 23:15





Yes, you are right. I do have some duplicates. How do I then make sure that the keys in the Set are unique. Then using it makes no sense, if the values in the Set aren't unique

– user8231110
Nov 22 '18 at 23:15













You can use a new custom object which will store your array as a field and then override hashCode and equals to check what is INSIDE array.

– ByeBye
Nov 22 '18 at 23:16





You can use a new custom object which will store your array as a field and then override hashCode and equals to check what is INSIDE array.

– ByeBye
Nov 22 '18 at 23:16













They are unique only by design of equals of an array. Not unique in by author algorithm design - the array is not fit here to be used as part of a set.

– ByeBye
Nov 22 '18 at 23:19





They are unique only by design of equals of an array. Not unique in by author algorithm design - the array is not fit here to be used as part of a set.

– ByeBye
Nov 22 '18 at 23:19













I think the symptoms mean that your generateDesKey is generating non-unique keys ... as well.

– Stephen C
Nov 22 '18 at 23:30





I think the symptoms mean that your generateDesKey is generating non-unique keys ... as well.

– Stephen C
Nov 22 '18 at 23:30




1




1





What is your question now? I provide a solution and answer why your set size is different than HashSet size. If you have another question - in the example with helping create better function it should be a new separate question.

– ByeBye
Nov 22 '18 at 23:37





What is your question now? I provide a solution and answer why your set size is different than HashSet size. If you have another question - in the example with helping create better function it should be a new separate question.

– ByeBye
Nov 22 '18 at 23:37











0














The set itself is being implemented that way that every item inside must be unique - it does not allow duplicates. That means that when you are putting to set two equal objects in result in set there will be only one.



Probably your generateDesKey() method is returning not unique values for all of 2^20 values and in the result set the items count is less than 2^20



Basically you can check the possibleKeySet size before copying values to the HashMap like



System.out.println(possibleKeySet.size());


or just by using debugger






share|improve this answer
























  • I did that and the size is 1048576 (2^20)

    – user8231110
    Nov 22 '18 at 22:55













  • ok that's weird :)

    – m.antkowicz
    Nov 22 '18 at 23:04






  • 1





    Actually, not weird. Bytearrays (arrays in general) can't be used as keys in a HashSet or HashMap. Because of the semantics of equals. See ByeBye's answer.

    – Stephen C
    Nov 22 '18 at 23:31













  • But he is using a String as the key

    – Bab
    Nov 23 '18 at 20:31
















0














The set itself is being implemented that way that every item inside must be unique - it does not allow duplicates. That means that when you are putting to set two equal objects in result in set there will be only one.



Probably your generateDesKey() method is returning not unique values for all of 2^20 values and in the result set the items count is less than 2^20



Basically you can check the possibleKeySet size before copying values to the HashMap like



System.out.println(possibleKeySet.size());


or just by using debugger






share|improve this answer
























  • I did that and the size is 1048576 (2^20)

    – user8231110
    Nov 22 '18 at 22:55













  • ok that's weird :)

    – m.antkowicz
    Nov 22 '18 at 23:04






  • 1





    Actually, not weird. Bytearrays (arrays in general) can't be used as keys in a HashSet or HashMap. Because of the semantics of equals. See ByeBye's answer.

    – Stephen C
    Nov 22 '18 at 23:31













  • But he is using a String as the key

    – Bab
    Nov 23 '18 at 20:31














0












0








0







The set itself is being implemented that way that every item inside must be unique - it does not allow duplicates. That means that when you are putting to set two equal objects in result in set there will be only one.



Probably your generateDesKey() method is returning not unique values for all of 2^20 values and in the result set the items count is less than 2^20



Basically you can check the possibleKeySet size before copying values to the HashMap like



System.out.println(possibleKeySet.size());


or just by using debugger






share|improve this answer













The set itself is being implemented that way that every item inside must be unique - it does not allow duplicates. That means that when you are putting to set two equal objects in result in set there will be only one.



Probably your generateDesKey() method is returning not unique values for all of 2^20 values and in the result set the items count is less than 2^20



Basically you can check the possibleKeySet size before copying values to the HashMap like



System.out.println(possibleKeySet.size());


or just by using debugger







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 22 '18 at 22:54









m.antkowiczm.antkowicz

8,562928




8,562928













  • I did that and the size is 1048576 (2^20)

    – user8231110
    Nov 22 '18 at 22:55













  • ok that's weird :)

    – m.antkowicz
    Nov 22 '18 at 23:04






  • 1





    Actually, not weird. Bytearrays (arrays in general) can't be used as keys in a HashSet or HashMap. Because of the semantics of equals. See ByeBye's answer.

    – Stephen C
    Nov 22 '18 at 23:31













  • But he is using a String as the key

    – Bab
    Nov 23 '18 at 20:31



















  • I did that and the size is 1048576 (2^20)

    – user8231110
    Nov 22 '18 at 22:55













  • ok that's weird :)

    – m.antkowicz
    Nov 22 '18 at 23:04






  • 1





    Actually, not weird. Bytearrays (arrays in general) can't be used as keys in a HashSet or HashMap. Because of the semantics of equals. See ByeBye's answer.

    – Stephen C
    Nov 22 '18 at 23:31













  • But he is using a String as the key

    – Bab
    Nov 23 '18 at 20:31

















I did that and the size is 1048576 (2^20)

– user8231110
Nov 22 '18 at 22:55







I did that and the size is 1048576 (2^20)

– user8231110
Nov 22 '18 at 22:55















ok that's weird :)

– m.antkowicz
Nov 22 '18 at 23:04





ok that's weird :)

– m.antkowicz
Nov 22 '18 at 23:04




1




1





Actually, not weird. Bytearrays (arrays in general) can't be used as keys in a HashSet or HashMap. Because of the semantics of equals. See ByeBye's answer.

– Stephen C
Nov 22 '18 at 23:31







Actually, not weird. Bytearrays (arrays in general) can't be used as keys in a HashSet or HashMap. Because of the semantics of equals. See ByeBye's answer.

– Stephen C
Nov 22 '18 at 23:31















But he is using a String as the key

– Bab
Nov 23 '18 at 20:31





But he is using a String as the key

– Bab
Nov 23 '18 at 20:31


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438795%2fhashmap-gets-wrong-size%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

Calculate evaluation metrics using cross_val_predict sklearn

Insert data from modal to MySQL (multiple modal on website)