package gnu.trove.map.hash;
import gnu.trove.strategy.HashingStrategy;
import junit.framework.TestCase;
import java.io.*;
import java.util.*;
/**
*
*/
public class TCustomHashMapTest extends TestCase {
// Example from Trove overview doc
public void testArray() {
char[] foo = new char[]{ 'a', 'b', 'c' };
char[] bar = new char[]{ 'a', 'b', 'c' };
assertFalse( foo.hashCode() == bar.hashCode() );
//noinspection ArrayEquals
assertFalse( foo.equals( bar ) );
HashingStrategy<char[]> strategy = new ArrayHashingStrategy();
assertTrue( strategy.computeHashCode( foo ) ==
strategy.computeHashCode( bar ) );
assertTrue( strategy.equals( foo, bar ) );
Map<char[], String> map = new TCustomHashMap<char[], String>( strategy );
map.put( foo, "yay" );
assertTrue( map.containsKey( foo ) );
assertTrue( map.containsKey( bar ) );
assertEquals( "yay", map.get( foo ) );
assertEquals( "yay", map.get( bar ) );
Set<char[]> keys = map.keySet();
assertTrue( keys.contains( foo ) );
assertTrue( keys.contains( bar ) );
}
public void testSerialization() throws Exception {
char[] foo = new char[]{ 'a', 'b', 'c' };
char[] bar = new char[]{ 'a', 'b', 'c' };
HashingStrategy<char[]> strategy = new ArrayHashingStrategy();
Map<char[], String> map = new TCustomHashMap<char[], String>( strategy );
map.put( foo, "yay" );
// Make sure it still works after being serialized
ObjectOutputStream oout = null;
ByteArrayOutputStream bout = null;
ObjectInputStream oin = null;
ByteArrayInputStream bin = null;
try {
bout = new ByteArrayOutputStream();
oout = new ObjectOutputStream( bout );
oout.writeObject( map );
bin = new ByteArrayInputStream( bout.toByteArray() );
oin = new ObjectInputStream( bin );
map = ( Map<char[], String> ) oin.readObject();
}
finally {
if ( oin != null ) oin.close();
if ( bin != null ) bin.close();
if ( oout != null ) oout.close();
if ( bout != null ) bout.close();
}
assertTrue( map.containsKey( foo ) );
assertTrue( map.containsKey( bar ) );
assertEquals( "yay", map.get( foo ) );
assertEquals( "yay", map.get( bar ) );
Set<char[]> keys = map.keySet();
assertTrue( keys.contains( foo ) );
assertTrue( keys.contains( bar ) );
}
static class ByteArrayStrategy implements HashingStrategy<byte[]> {
// Copied from Arrays.hashCode, but applied only to the first four bytes
public int computeHashCode( byte[] bytes ) {
if ( bytes == null ) return 0;
int h = 1;
for ( int i = 0; i < 4; i++ ) h = 31 * h + bytes[ i ];
return h;
}
public boolean equals( byte[] o1, byte[] o2 ) {
return Arrays.equals( o1, o2 );
}
}
private static byte[] random( int n, Random rnd ) {
byte[] ba = new byte[ n ];
for ( int i = 0; i < ba.length; i++ ) {
ba[ i ] = ( byte ) rnd.nextInt();
}
return ba;
}
public void testBug4706479() throws Exception {
Random rnd = new Random( 1234 );
TCustomHashMap<byte[], Integer> map =
new TCustomHashMap<byte[], Integer>( new ByteArrayStrategy() );
List<byte[]> list = new ArrayList<byte[]>();
List<Integer> expected = new ArrayList<Integer>();
for ( int i = 0; i < 1000; i++ ) {
byte[] ba = random( 16, rnd );
list.add( ba );
Integer obj = Integer.valueOf( i );
expected.add( obj );
map.put( ba, obj );
}
assertEquals( list.size(), map.size() );
// Make sure all the arrays are found in the map
for( byte[] array : map.keySet() ) {
boolean found_it = false;
for( byte[] test : list ) {
if ( Arrays.equals( test, array ) ) {
found_it = true;
break;
}
}
assertTrue( "Unable to find: " + Arrays.toString( array ), found_it );
}
// Make sure all the Integers are found in the map
for( Integer obj : map.values() ) {
assertTrue( "Unable to find: " + obj, expected.contains( obj ) );
}
for ( int i = 0; i < expected.size(); i++ ) {
assertEquals( expected.get( i ), map.get( list.get( i ) ) );
}
// Remove items
for ( int i = 0; i < list.size(); i++ ) {
assertEquals( expected.get( i ), map.remove( list.get( i ) ) );
}
assertEquals( 0, map.size() );
assertTrue( map.isEmpty() );
for ( byte[] aList : list ) {
assertNull( map.get( aList ) );
}
}
}