2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import java.util.AbstractSet;
24 import java.util.Iterator;
25 import java.util.LinkedHashMap;
28 * Order preserving Set based on System.identityHashCode() for an object, which
29 * also supports Object->index lookup.
31 * @author Jim Procter (2016) based on Evgeniy Dorofeev's response: via
32 * https://stackoverflow.com/questions/17276658/linkedidentityhashset
35 public class LinkedIdentityHashSet<E> extends AbstractSet<E>
37 LinkedHashMap<IdentityWrapper, IdentityWrapper> set = new LinkedHashMap<>();
39 static class IdentityWrapper
45 IdentityWrapper(Object obj, int p)
52 public boolean equals(Object obj)
54 return this.obj == ((IdentityWrapper) obj).obj;
60 return System.identityHashCode(obj);
65 public boolean add(E e)
67 IdentityWrapper el = (new IdentityWrapper(e, set.size()));
68 // Map.putIfAbsent() from Java 8
69 // return set.putIfAbsent(el, el) == null;
70 return putIfAbsent(el, el) == null;
74 * If the specified key is not already associated with a value (or is mapped
75 * to null) associates it with the given value and returns null, else returns
78 * Method added for Java 7 (can remove for Java 8)
84 * ://docs.oracle.com/javase/8/docs/api/java/util/Map.html#putIfAbsent
87 private IdentityWrapper putIfAbsent(IdentityWrapper key,
88 IdentityWrapper value)
90 IdentityWrapper v = set.get(key);
93 v = set.put(key, value);
99 public Iterator<E> iterator()
101 return new Iterator<E>()
103 final Iterator<IdentityWrapper> se = set.keySet().iterator();
106 public boolean hasNext()
111 @SuppressWarnings("unchecked")
115 return (E) se.next().obj;
121 // Java 8 default behaviour
122 throw new UnsupportedOperationException();
134 * Lookup the index for e in the set
137 * @return position of e in the set when it was added.
139 public int indexOf(E e)