0

How I can prove by jUnit test that HashSet handled collision. For example I can fill HashSet with 10000 elements in for loop, but which parameter should show me that I have collision, I suppose to think about collection size, but not pretty sure about it.

SecretAgentMan
  • 2,856
  • 7
  • 21
  • 41
  • How do you define *collision*? What **exactly** do you want your unit test to test? – deHaar Nov 19 '19 at 12:31
  • 1
    Put two equal items in, and assert that the size is 1. Or, if you mean *hash* collision, put in two unequal items with the same hash, and assert that the size is 2. – Andy Turner Nov 19 '19 at 12:32
  • @AndyTurner I'd make that an answer. I was about to write something similar. – Michael Berry Nov 19 '19 at 12:36
  • Collision in hashCodes. It should shown if I add items with same hash Codes, than HashSet internally fined same Hash Codes and handled it , something like that – Vova Adamenko Nov 19 '19 at 12:51
  • You are not supposed to prove that. The authors of `HashSet` already did. You should focus on testing *your* code. – Holger Nov 20 '19 at 09:40
  • Thanks. Yep, that is my problem I have not any clue how to test it. – Vova Adamenko Nov 20 '19 at 11:15
  • You test your code by considering what your code is supposed to do and check whether it does what it is supposed to do. You don’t have to care for hash collisions, the `HashSet` does handle them correctly. That’s a known fact. – Holger Nov 22 '19 at 09:55

2 Answers2

4

If you want to assert that HashSet handles collision of equal values, put in 2 equal values, and assert that only one item is in the set after:

HashSet<String> set = new HashSet<>(Arrays.asList("A", "A"));
assertEquals(1, set.size());

If you want to assert that HashSet handles collision of equal hash codes, put in unequal values with the same hash code, and assert that there are two items in the set after:

assertEquals("Aa".hashCode(), "BB".hashCode());
HashSet<String> set = new HashSet<>(Arrays.asList("Aa", "BB"));
assertEquals(2, set.size());
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
0

I don't understand what is the purpose of this test, but you can do it like this:

Set<String> mySet = new HashSet<>();
int numberOfRandomElements = 10000;

mySet.addAll(createRandomElements(numberOfRandomElements));

int diff = numberOfRandomElements - mySet.size();
System.out.println(String.format("Number of elements removed: %d", diff));
  • Thanks Rafael. Maybe I will asked dummy question, but why size is diminished? – Vova Adamenko Nov 19 '19 at 13:05
  • @VovaAdamenko HashSet store elements using its hashCode. When we try to add a element with same hashCode from another that already exists, the first is overrided. – Rafael Senna Nov 21 '19 at 11:13
  • I said that I dont understand the purporse of this test because: 1) As @Joeblade said, junit with random is not a good idea. Thats why I didnt make asserts in my response. 2) Why you are trying to test HashSet implementation? I'm sure it has been very well tested and works well – Rafael Senna Nov 21 '19 at 11:19
  • Actually, I suppose to clarify my question. I need to count number of elements in HashSet with same hashCode, to see how many collision can exist in this HashSet, and as a result, to improve hasCode computing mechanism. Something like this. And finally I can't understand how to write this Test, I mean to count same HashCodes – Vova Adamenko Nov 21 '19 at 13:26