HashMap gets wrong size
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
|
show 2 more comments
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
You probably have a collision on keys. You can check it by checking the return value ofput
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 addingif(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 usingbyte
as a key ... so duplicates are possible.
– Stephen C
Nov 22 '18 at 23:55
|
show 2 more comments
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
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
java hashmap set
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 ofput
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 addingif(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 usingbyte
as a key ... so duplicates are possible.
– Stephen C
Nov 22 '18 at 23:55
|
show 2 more comments
You probably have a collision on keys. You can check it by checking the return value ofput
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 addingif(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 usingbyte
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
|
show 2 more comments
3 Answers
3
active
oldest
votes
The probability of a hash collision is (as can be seen here):
The average number of collisions for a set of size n
given k
inputs is:
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);
}
Very interesting, but how do I avoid the collision?
– user8231110
Nov 22 '18 at 23:30
Even with hash collisionHashSet
andHashMap
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 inpossibleKeySet
!
– Stephen C
Nov 22 '18 at 23:56
|
show 8 more comments
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
}
}
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 yourgenerateDesKey
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
|
show 4 more comments
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
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 ofequals
. 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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
The probability of a hash collision is (as can be seen here):
The average number of collisions for a set of size n
given k
inputs is:
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);
}
Very interesting, but how do I avoid the collision?
– user8231110
Nov 22 '18 at 23:30
Even with hash collisionHashSet
andHashMap
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 inpossibleKeySet
!
– Stephen C
Nov 22 '18 at 23:56
|
show 8 more comments
The probability of a hash collision is (as can be seen here):
The average number of collisions for a set of size n
given k
inputs is:
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);
}
Very interesting, but how do I avoid the collision?
– user8231110
Nov 22 '18 at 23:30
Even with hash collisionHashSet
andHashMap
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 inpossibleKeySet
!
– Stephen C
Nov 22 '18 at 23:56
|
show 8 more comments
The probability of a hash collision is (as can be seen here):
The average number of collisions for a set of size n
given k
inputs is:
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);
}
The probability of a hash collision is (as can be seen here):
The average number of collisions for a set of size n
given k
inputs is:
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);
}
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 collisionHashSet
andHashMap
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 inpossibleKeySet
!
– Stephen C
Nov 22 '18 at 23:56
|
show 8 more comments
Very interesting, but how do I avoid the collision?
– user8231110
Nov 22 '18 at 23:30
Even with hash collisionHashSet
andHashMap
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 inpossibleKeySet
!
– 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
|
show 8 more comments
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
}
}
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 yourgenerateDesKey
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
|
show 4 more comments
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
}
}
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 yourgenerateDesKey
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
|
show 4 more comments
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
}
}
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
}
}
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 yourgenerateDesKey
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
|
show 4 more comments
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 yourgenerateDesKey
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
|
show 4 more comments
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
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 ofequals
. 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
add a comment |
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
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 ofequals
. 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
add a comment |
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
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
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 ofequals
. 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
add a comment |
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 ofequals
. 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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 addingif(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