Mercurial Hosting > nabble
view src/fschmidt/util/java/Interner.java @ 68:00520880ad02
add fschmidt source
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 05 Oct 2025 17:24:15 -0600 |
parents | |
children |
line wrap: on
line source
package fschmidt.util.java; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentHashMap; public final class Interner<T> { private static final class MyReference<T> extends WeakReference<T> { private final int hash; MyReference(T t,ReferenceQueue<T> q) { super(t,q); hash = t.hashCode(); } public boolean equals(Object obj) { if( this==obj ) return true; if( !(obj instanceof MyReference) ) return false; MyReference ref = (MyReference)obj; T t = this.get(); if( t==null ) return false; return t.equals(ref.get()); } public int hashCode() { return hash; } } private final ConcurrentMap<MyReference<T>,MyReference<T>> map = new ConcurrentHashMap<MyReference<T>,MyReference<T>>(); private ReferenceQueue<T> queue = new ReferenceQueue<T>(); private void sweep() { while(true) { Reference<? extends T> ref = queue.poll(); if( ref == null ) return; map.remove(ref); } } public T intern(T t) { MyReference<T> ref = new MyReference<T>(t,queue); while(true) { MyReference<T> ref2 = map.putIfAbsent(ref,ref); if( ref2 == null ) { sweep(); return t; } T t2 = ref2.get(); if( t2 != null ) { ref.clear(); return t2; } } } }