comparison 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
comparison
equal deleted inserted replaced
67:9d0fefce6985 68:00520880ad02
1 package fschmidt.util.java;
2
3 import java.lang.ref.Reference;
4 import java.lang.ref.ReferenceQueue;
5 import java.lang.ref.WeakReference;
6 import java.util.concurrent.ConcurrentMap;
7 import java.util.concurrent.ConcurrentHashMap;
8
9
10 public final class Interner<T> {
11
12 private static final class MyReference<T> extends WeakReference<T> {
13 private final int hash;
14
15 MyReference(T t,ReferenceQueue<T> q) {
16 super(t,q);
17 hash = t.hashCode();
18 }
19
20 public boolean equals(Object obj) {
21 if( this==obj )
22 return true;
23 if( !(obj instanceof MyReference) )
24 return false;
25 MyReference ref = (MyReference)obj;
26 T t = this.get();
27 if( t==null )
28 return false;
29 return t.equals(ref.get());
30 }
31
32 public int hashCode() {
33 return hash;
34 }
35 }
36
37 private final ConcurrentMap<MyReference<T>,MyReference<T>> map = new ConcurrentHashMap<MyReference<T>,MyReference<T>>();
38 private ReferenceQueue<T> queue = new ReferenceQueue<T>();
39
40 private void sweep() {
41 while(true) {
42 Reference<? extends T> ref = queue.poll();
43 if( ref == null )
44 return;
45 map.remove(ref);
46 }
47 }
48
49 public T intern(T t) {
50 MyReference<T> ref = new MyReference<T>(t,queue);
51 while(true) {
52 MyReference<T> ref2 = map.putIfAbsent(ref,ref);
53 if( ref2 == null ) {
54 sweep();
55 return t;
56 }
57 T t2 = ref2.get();
58 if( t2 != null ) {
59 ref.clear();
60 return t2;
61 }
62 }
63 }
64
65 }