public synchronized < U extends T > U put ( U obj ) { if ( obj == null ) { return null ; } Entry < T > [ ] entries = mEntries ; int hash = hashCode ( obj ) ; int index = ( hash & 0x7fffffff ) % entries . length ; for ( Entry < T > e = entries [ index ] , prev = null ; e != null ; e = e . mNext ) { T iobj = e . get ( ) ; if ( iobj == null ) { // Clean up after a cleared Reference. if ( prev == null ) { entries [ index ] = e . mNext ; } else { prev . mNext = e . mNext ; } mSize -- ; } else if ( e . mHash == hash && obj . getClass ( ) == iobj . getClass ( ) && equals ( obj , iobj ) ) { // Found canonical instance. return ( U ) iobj ; } else { prev = e ; } } if ( mSize >= mThreshold ) { cleanup ( ) ; if ( mSize >= mThreshold ) { rehash ( ) ; entries = mEntries ; index = ( hash & 0x7fffffff ) % entries . length ; } } entries [ index ] = new Entry < T > ( this , obj , hash , entries [ index ] ) ; mSize ++ ; return obj ; }
Pass in a candidate canonical object and get a unique instance from this set . The returned object will always be of the same type as that passed in . If the object passed in does not equal any object currently in the set it will be added to the set becoming canonical .