Fixed CollectionSupportImpl.ResourceList iteration order 75/1275/6
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Thu, 30 Nov 2017 17:48:29 +0000 (19:48 +0200)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Thu, 7 Dec 2017 07:04:37 +0000 (10:04 +0300)
Implemented CollectionSupportImpl.ResourceList#listIterator methods.

Removed use of the deprecated Callback interface in
org.simantics.db.ResourceMap.

refs #7654

Change-Id: I22ee6da55326bf884b24e63eb2d9ed30fc242771

bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/CollectionSupportImpl.java
bundles/org.simantics.db/src/org/simantics/db/ResourceMap.java

index 37c89ff5f4dee3d0ac0a8fd0abd6b2a21207702b..15bbffad859b880f19d545cfa8a9a2207ee605de 100644 (file)
@@ -10,7 +10,9 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.Set;
+import java.util.function.Consumer;
 
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
@@ -20,7 +22,6 @@ import org.simantics.db.impl.ResourceImpl;
 import org.simantics.db.impl.graph.ReadGraphImpl;
 import org.simantics.db.impl.query.IntSet;
 import org.simantics.db.service.CollectionSupport;
-import org.simantics.utils.datastructures.Callback;
 
 import gnu.trove.impl.Constants;
 import gnu.trove.iterator.TIntIterator;
@@ -35,38 +36,38 @@ import gnu.trove.procedure.TObjectProcedure;
 import gnu.trove.set.hash.TIntHashSet;
 
 public class CollectionSupportImpl implements CollectionSupport {
-       
+
        final private SessionImplSocket session;
-       
+
        CollectionSupportImpl(SessionImplSocket session) {
                this.session = session;
        }
-       
+
        static final class IntResourceMap {
-       
+
                final private SessionImplSocket session;
                final private TIntIntHashMap backend = new TIntIntHashMap(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, -1, 0);
-               
+
                IntResourceMap(SessionImplSocket session) {
                        this.session = session;
                }
-               
+
                public int size() {
                        return backend.size();
                }
-               
+
                public boolean isEmpty() {
                        return backend.isEmpty();
                }
-               
+
                public boolean containsKey(int key) {
                        return backend.containsKey(key);
                }
-               
+
                public boolean containsValue(int value) {
                        return backend.containsValue(value);
                }
-               
+
                public Resource get(int key) {
                        try {
                                return session.getResourceByKey(backend.get(key));
@@ -75,7 +76,7 @@ public class CollectionSupportImpl implements CollectionSupport {
                        }
                        return null;
                }
-               
+
                public Resource put(int key, Resource value) {
                        ResourceImpl impl = (ResourceImpl) value;
                        int i = backend.put(key, impl.id);
@@ -89,7 +90,7 @@ public class CollectionSupportImpl implements CollectionSupport {
                                }
                        return null;
                }
-               
+
                public Resource remove(int key) {
                        throw new UnsupportedOperationException("remove not supported");
                }
@@ -111,16 +112,16 @@ public class CollectionSupportImpl implements CollectionSupport {
                        return session == other.session && backend.equals(other.backend);
                }
        }
-       
+
        public IntResourceMap createIntResourceMap() {
                return new IntResourceMap(session);
        }
 
        static final class ObjectResourceMap<T> implements Map<T, Resource> {
-               
+
                final private SessionImplSocket session;
                final private TObjectIntHashMap<T> backend;
-               
+
                ObjectResourceMap(SessionImplSocket session) {
                        this.session = session;
                        backend = new TObjectIntHashMap<T>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, 0);
@@ -130,7 +131,7 @@ public class CollectionSupportImpl implements CollectionSupport {
                        this.session = session;
                        backend = new TObjectIntHashMap<T>(capacity, Constants.DEFAULT_LOAD_FACTOR, 0);
                }
-               
+
                @Override
                public int size() {
                        return backend.size();
@@ -139,18 +140,18 @@ public class CollectionSupportImpl implements CollectionSupport {
                public boolean isEmpty() {
                        return backend.isEmpty();
                }
-               
+
                @Override
                public boolean containsKey(Object key) {
                        return backend.contains(key);
                }
-               
+
                @Override
                public boolean containsValue(Object value) {
                        ResourceImpl impl = (ResourceImpl) value;
                        return backend.containsValue(impl.id);
                }
-               
+
                @Override
                public Resource get(Object key) {
                        try {
@@ -163,7 +164,7 @@ public class CollectionSupportImpl implements CollectionSupport {
                        }
                        return null;
                }
-               
+
                @Override
                public Resource put(T key, Resource value) {
                        ResourceImpl impl = (ResourceImpl) value;
@@ -178,12 +179,12 @@ public class CollectionSupportImpl implements CollectionSupport {
                                }
                        return null;
                }
-               
+
                @Override
                public Resource remove(Object key) {
                        throw new UnsupportedOperationException("remove not supported, structure is immutable");
                }
-               
+
                @Override
                public void putAll(Map<? extends T, ? extends Resource> map) {
                        @SuppressWarnings("unchecked")
@@ -197,12 +198,12 @@ public class CollectionSupportImpl implements CollectionSupport {
                                }
                        });
                }
-               
+
                @Override
                public void clear() {
                        throw new UnsupportedOperationException("clear not supported, structure is immutable");
                }
-               
+
                @Override
                public Set<T> keySet() {
                        final Set<T> result = new HashSet<T>();
@@ -216,7 +217,7 @@ public class CollectionSupportImpl implements CollectionSupport {
                        });
                        return result;
                }
-               
+
                @Override
                public Collection<Resource> values() {
                        ArrayList<Resource> result = new ArrayList<Resource>();
@@ -229,7 +230,7 @@ public class CollectionSupportImpl implements CollectionSupport {
                        }
                        return result;
                }
-               
+
                @Override
                public Set<java.util.Map.Entry<T, Resource>> entrySet() {
                        final HashSet<java.util.Map.Entry<T, Resource>> result = new HashSet<java.util.Map.Entry<T, Resource>>();
@@ -253,7 +254,7 @@ public class CollectionSupportImpl implements CollectionSupport {
                                                public Resource setValue(Resource value) {
                                                        throw new UnsupportedOperationException("Map.Entry.setValue not supported, structure is immutable");
                                                }
-                                               
+
                                        });
                                }
                        });
@@ -271,14 +272,40 @@ public class CollectionSupportImpl implements CollectionSupport {
                                return true;
                        if (obj == null)
                                return false;
-                       if (getClass() != obj.getClass())
+                       if (getClass() != obj.getClass()) {
+                               if (obj instanceof Map) {
+                                       // Nonoptimal fallback for comparing against generic Map
+                                       Map<?,?> m = (Map<?,?>) obj;
+                                       if (m.size() != size())
+                                               return false;
+                                       try {
+                                               Iterator<Entry<T,Resource>> i = entrySet().iterator();
+                                               while (i.hasNext()) {
+                                                       Entry<T,Resource> e = i.next();
+                                                       T key = e.getKey();
+                                                       Resource value = e.getValue();
+                                                       if (value == null) {
+                                                               if (!(m.get(key)==null && m.containsKey(key)))
+                                                                       return false;
+                                                       } else {
+                                                               if (!value.equals(m.get(key)))
+                                                                       return false;
+                                                       }
+                                               }
+                                       } catch (ClassCastException unused) {
+                                               return false;
+                                       } catch (NullPointerException unused) {
+                                               return false;
+                                       }
+                               }
                                return false;
+                       }
                        ObjectResourceMap<?> other = (ObjectResourceMap<?>) obj;
                        return session == other.session && backend.equals(other.backend);
                }
 
        }
-       
+
        @SuppressWarnings("unchecked")
        @Override
        public <T, I> T createObjectResourceMap(Class<I> clazz) {
@@ -292,14 +319,14 @@ public class CollectionSupportImpl implements CollectionSupport {
        }
 
     static final class ResourceMap<T> implements org.simantics.db.ResourceMap<T> {
-       
+
        final private SessionImplSocket session;
        final private TIntObjectHashMap<T> backend = new TIntObjectHashMap<T>();
 
        ResourceMap(SessionImplSocket session) {
                this.session = session;
        }
-       
+
                @Override
                public void clear() {
                        throw new UnsupportedOperationException("Not implemented");
@@ -340,11 +367,11 @@ public class CollectionSupportImpl implements CollectionSupport {
                                                public T setValue(T arg0) {
                                                        throw new UnsupportedOperationException("Not supported");
                                                }
-                                               
+
                                        });
                                        return true;
                                }
-                               
+
                        });
                        return result;
                }
@@ -361,10 +388,10 @@ public class CollectionSupportImpl implements CollectionSupport {
                }
 
                public class CallbackEntry<E> implements ResourceMapEntry<E> {
-                       
+
                        int id;
                        E value;
-                       
+
                        @Override
                        public Resource getKey() {
                                return new ResourceImpl(session.resourceSupport, id);
@@ -374,29 +401,29 @@ public class CollectionSupportImpl implements CollectionSupport {
                        public E getValue() {
                                return value;
                        }
-                       
+
                }
-               
+
                @Override
-               public void iterateEntries(final Callback<ResourceMapEntry<T>> callback) {
+               public void iterateEntries(final Consumer<ResourceMapEntry<T>> callback) {
                        final CallbackEntry<T> entry = new CallbackEntry<T>();
                        backend.forEach(new TIntProcedure() {
-                               
+
                                @Override
                                public boolean execute(int value) {
                                        entry.id = value;
                                        entry.value = backend.get(value);
-                                       callback.run(entry);
+                                       callback.accept(entry);
                                        return true;
                                }
                        });
                }
-               
+
                @Override
                public Set<Resource> keySet() {
                        final ResourceSet result = new ResourceSet(session);
                        backend.forEach(new TIntProcedure() {
-                               
+
                                @Override
                                public boolean execute(int value) {
                                        result.add(value);
@@ -423,13 +450,17 @@ public class CollectionSupportImpl implements CollectionSupport {
                                        backend.put(a, b);
                                        return true;
                                }
-                               
+
                        });
                }
 
                @Override
-               public T remove(Object arg0) {
-                       throw new UnsupportedOperationException("Not implemented");
+               public T remove(Object key) {
+                       if (key instanceof ResourceImpl) {
+                               ResourceImpl impl = (ResourceImpl)key;
+                               return backend.remove(impl.id);
+                       }
+                       return null;
                }
 
                @Override
@@ -440,7 +471,7 @@ public class CollectionSupportImpl implements CollectionSupport {
                @SuppressWarnings("unchecked")
                @Override
                public Collection<T> values() {
-                       ArrayList<T> result = new ArrayList<T>();
+                       ArrayList<T> result = new ArrayList<>();
                        for(Object o : backend.values()) result.add((T)o);
                        return result;
                }
@@ -456,14 +487,40 @@ public class CollectionSupportImpl implements CollectionSupport {
                                return true;
                        if (obj == null)
                                return false;
-                       if (getClass() != obj.getClass())
+                       if (getClass() != obj.getClass()) {
+                               if (obj instanceof Map) {
+                                       // Nonoptimal fallback for comparing against generic Map
+                                       Map<?,?> m = (Map<?,?>) obj;
+                                       if (m.size() != size())
+                                               return false;
+                                       try {
+                                               Iterator<Entry<Resource,T>> i = entrySet().iterator();
+                                               while (i.hasNext()) {
+                                                       Entry<Resource,T> e = i.next();
+                                                       Resource key = e.getKey();
+                                                       T value = e.getValue();
+                                                       if (value == null) {
+                                                               if (!(m.get(key)==null && m.containsKey(key)))
+                                                                       return false;
+                                                       } else {
+                                                               if (!value.equals(m.get(key)))
+                                                                       return false;
+                                                       }
+                                               }
+                                       } catch (ClassCastException unused) {
+                                               return false;
+                                       } catch (NullPointerException unused) {
+                                               return false;
+                                       }
+                               }
                                return false;
+                       }
                        ResourceMap<?> other = (ResourceMap<?>) obj;
                        return session == other.session && backend.equals(other.backend);
                }
-       
+
     }
-    
+
        @SuppressWarnings("unchecked")
        @Override
        public <T, I> T createMap(Class<I> clazz) {
@@ -471,7 +528,7 @@ public class CollectionSupportImpl implements CollectionSupport {
        }
 
     static final class ResourceSet implements Set<Resource> {
-       
+
        final private SessionImplSocket session;
        final private TIntHashSet backend;
 
@@ -479,7 +536,7 @@ public class CollectionSupportImpl implements CollectionSupport {
                this.session = session;
                backend = new TIntHashSet();
        }
-       
+
        ResourceSet(SessionImplSocket session, int capacity) {
                this.session = session;
                backend = new TIntHashSet(capacity);
@@ -500,15 +557,15 @@ public class CollectionSupportImpl implements CollectionSupport {
                        ResourceImpl impl = (ResourceImpl)resource;
                        return backend.add(impl.id);
                }
-               
+
                boolean add(int id) {
                        return backend.add(id);
                }
 
                @Override
                public boolean addAll(Collection<? extends Resource> rs) {
-                       boolean result = true;
-                       for(Resource r : rs) result &= add(r);
+                       boolean result = false;
+                       for(Resource r : rs) result |= add(r);
                        return result;
                }
 
@@ -520,9 +577,10 @@ public class CollectionSupportImpl implements CollectionSupport {
 
                @Override
                public boolean containsAll(Collection<?> rs) {
-                       boolean result = true;
-                       for(Object r : rs) result &= contains(r);
-                       return result;
+                       for (Object r : rs)
+                               if (!contains(r))
+                                       return false;
+                       return true;
                }
 
                @Override
@@ -535,7 +593,7 @@ public class CollectionSupportImpl implements CollectionSupport {
                        return new Iterator<Resource>() {
 
                                TIntIterator it = backend.iterator();
-                               
+
                                @Override
                                public boolean hasNext() {
                                        return it.hasNext();
@@ -550,7 +608,7 @@ public class CollectionSupportImpl implements CollectionSupport {
                                public void remove() {
                                        it.remove();
                                }
-                               
+
                        };
                }
 
@@ -562,8 +620,8 @@ public class CollectionSupportImpl implements CollectionSupport {
 
                @Override
                public boolean removeAll(Collection<?> rs) {
-                       boolean result = true;
-                       for(Object r : rs) result &= remove(r);
+                       boolean result = false;
+                       for(Object r : rs) result |= remove(r);
                        return result;
                }
 
@@ -574,24 +632,26 @@ public class CollectionSupportImpl implements CollectionSupport {
 
                @Override
                public Object[] toArray() {
-                       throw new UnsupportedOperationException("Not implemented");
+                       return toArray(new Object[backend.size()]);
                }
 
                @SuppressWarnings("unchecked")
                @Override
-               public <T> T[] toArray(T[] arg0) {
-                       final T[] result = (T[])Array.newInstance(arg0.getClass().getComponentType(), backend.size());
+               public <T> T[] toArray(T[] a) {
+                       int size = backend.size();
+                       T[] r = a.length >= size ? a :
+                               (T[])Array.newInstance(a.getClass().getComponentType(), size);
                        backend.forEach(new TIntProcedure() {
-                               
+
                                int index = 0;
-                               
+
                                @Override
                                public boolean execute(int value) {
-                                       result[index++] = (T)new ResourceImpl(session.resourceSupport, value);
+                                       r[index++] = (T)new ResourceImpl(session.resourceSupport, value);
                                        return true;
                                }
                        });
-                       return result;
+                       return r;
                }
 
                @Override
@@ -605,26 +665,40 @@ public class CollectionSupportImpl implements CollectionSupport {
                                return true;
                        if (obj == null)
                                return false;
-                       if (getClass() != obj.getClass())
+                       if (getClass() != obj.getClass()) {
+                               if (obj instanceof Set) {
+                                       // Nonoptimal fallback for comparing against generic Set
+                                       Collection<?> c = (Collection<?>) obj;
+                                       if (c.size() != size())
+                                               return false;
+                                       try {
+                                               return containsAll(c);
+                                       } catch (ClassCastException unused) {
+                                               return false;
+                                       } catch (NullPointerException unused) {
+                                               return false;
+                                       }
+                               }
                                return false;
+                       }
                        ResourceSet other = (ResourceSet) obj;
                        return session == other.session && backend.equals(other.backend);
                }
-       
+
     }
-       
+
        @Override
        public Set<Resource> createSet() {
                return new ResourceSet(session);
        }
-       
+
        @Override
        public Set<Resource> createSet(int capacity) {
                return new ResourceSet(session, capacity);
        }
 
        static final class ResourceList implements List<Resource> {
-       
+
        final private SessionImplSocket session;
        final private TIntArrayList backend;
 
@@ -698,24 +772,30 @@ public class CollectionSupportImpl implements CollectionSupport {
                @Override
                public Iterator<Resource> iterator() {
                        return new Iterator<Resource>() {
-                               
-                               int index = backend.size();
-                               
+
+                               int index = 0;
+                               int max = backend.size();
+
                                @Override
                                public boolean hasNext() {
-                                       return index > 0; 
+                                       return index < max;
                                }
 
                                @Override
                                public Resource next() {
-                                       return new ResourceImpl(session.resourceSupport, backend.getQuick(--index));
+                                       int i = index;
+                                       if (i >= max)
+                                               throw new NoSuchElementException();
+                                       int id = backend.getQuick(i);
+                                       index = i + 1;
+                                       return new ResourceImpl(session.resourceSupport, id);
                                }
 
                                @Override
                                public void remove() {
-                                       throw new UnsupportedOperationException("Not supported");
+                                       throw new UnsupportedOperationException("remove not supported");
                                }
-                               
+
                        };
                }
 
@@ -746,21 +826,23 @@ public class CollectionSupportImpl implements CollectionSupport {
 
                @SuppressWarnings("unchecked")
                @Override
-               public <T> T[] toArray(T[] arg0) {
-                       final T[] result = (T[])Array.newInstance(arg0.getClass().getComponentType(), backend.size());
+               public <T> T[] toArray(T[] a) {
+                       int size = backend.size();
+                       T[] r = a.length >= size ? a :
+                               (T[])Array.newInstance(a.getClass().getComponentType(), size);
                        backend.forEach(new TIntProcedure() {
-                               
+
                                int index = 0;
-                               
+
                                @Override
                                public boolean execute(int value) {
-                                       result[index++] = (T)new ResourceImpl(session.resourceSupport, value);
+                                       r[index++] = (T)new ResourceImpl(session.resourceSupport, value);
                                        return true;
                                }
                        });
-                       return result;
+                       return r;
                }
-               
+
                void sort() {
                        backend.sort();
                }
@@ -816,14 +898,82 @@ public class CollectionSupportImpl implements CollectionSupport {
                        return backend.lastIndexOf(impl.id);
                }
 
+               private class ListItr implements ListIterator<Resource> {
+
+                       int index;
+                       int max;
+
+                       public ListItr(int index) {
+                               this.index = index;
+                               this.max = size();
+                       }
+
+                       @Override
+                       public boolean hasNext() {
+                               return index < max;
+                       }
+
+                       @Override
+                       public Resource next() {
+                               int i = index;
+                               if (i >= max)
+                                       throw new NoSuchElementException();
+                               int id = backend.getQuick(index);
+                               index = i + 1;
+                               return new ResourceImpl(session.resourceSupport, id);
+                       }
+
+                       @Override
+                       public boolean hasPrevious() {
+                               return index != 0;
+                       }
+
+                       @Override
+                       public Resource previous() {
+                               int i = index - 1;
+                               if (i < 0)
+                                       throw new NoSuchElementException();
+                               int id = backend.getQuick(index);
+                               index = i;
+                               return new ResourceImpl(session.resourceSupport, id);
+                       }
+
+                       @Override
+                       public int nextIndex() {
+                               return index;
+                       }
+
+                       @Override
+                       public int previousIndex() {
+                               return index - 1;
+                       }
+
+                       @Override
+                       public void remove() {
+                               throw new UnsupportedOperationException("remove not supported");
+                       }
+
+                       @Override
+                       public void set(Resource e) {
+                               throw new UnsupportedOperationException("set not supported");
+                       }
+
+                       @Override
+                       public void add(Resource e) {
+                               throw new UnsupportedOperationException("add not supported");
+                       }
+               }
+
                @Override
                public ListIterator<Resource> listIterator() {
-                       throw new UnsupportedOperationException("Not implemented");
+                       return new ListItr(0);
                }
 
                @Override
                public ListIterator<Resource> listIterator(int index) {
-                       throw new UnsupportedOperationException("Not implemented");
+                       if (index < 0 || index > backend.size())
+                               throw new IndexOutOfBoundsException("Index: "+index);
+                       return new ListItr(index);
                }
 
                @Override
@@ -845,8 +995,21 @@ public class CollectionSupportImpl implements CollectionSupport {
                                return true;
                        if (obj == null)
                                return false;
-                       if (getClass() != obj.getClass())
+                       if (getClass() != obj.getClass()) {
+                               if (obj instanceof List) {
+                                       // Nonoptimal fallback for comparing against generic List
+                                       ListIterator<?> e1 = listIterator();
+                                       ListIterator<?> e2 = ((List<?>) obj).listIterator();
+                                       while (e1.hasNext() && e2.hasNext()) {
+                                               Object o1 = e1.next();
+                                               Object o2 = e2.next();
+                                               if (!(o1==null ? o2==null : o1.equals(o2)))
+                                                       return false;
+                                       }
+                                       return !(e1.hasNext() || e2.hasNext());
+                               }
                                return false;
+                       }
                        ResourceList other = (ResourceList) obj;
                        return session == other.session && backend.equals(other.backend);
                }
@@ -864,14 +1027,14 @@ public class CollectionSupportImpl implements CollectionSupport {
        }
 
     static final class StatementList implements Collection<Statement> {
-       
+
        final private SessionImplSocket session;
        final private TIntArrayList backend = new TIntArrayList();
 
        StatementList(SessionImplSocket session) {
                this.session = session;
        }
-       
+
                @Override
                public void clear() {
                        throw new UnsupportedOperationException("Not implemented");
@@ -895,8 +1058,8 @@ public class CollectionSupportImpl implements CollectionSupport {
 
                @Override
                public boolean addAll(Collection<? extends Statement> rs) {
-                       boolean result = true;
-                       for(Statement r : rs) result &= add(r);
+                       boolean result = false;
+                       for(Statement r : rs) result |= add(r);
                        return result;
                }
 
@@ -921,10 +1084,10 @@ public class CollectionSupportImpl implements CollectionSupport {
 
                                int index = 0;
                                int max = backend.size();
-                               
+
                                @Override
                                public boolean hasNext() {
-                                       return index < max; 
+                                       return index < max;
                                }
 
                                @Override
@@ -936,7 +1099,7 @@ public class CollectionSupportImpl implements CollectionSupport {
                                public void remove() {
                                        throw new UnsupportedOperationException("Not supported");
                                }
-                               
+
                        };
                }
 
@@ -957,24 +1120,22 @@ public class CollectionSupportImpl implements CollectionSupport {
 
                @Override
                public Object[] toArray() {
-                       throw new UnsupportedOperationException("Not implemented");
+                       int stms = backend.size() / 3;
+                       return toArray(new Object[stms]);
                }
 
                @SuppressWarnings("unchecked")
                @Override
-               public <T> T[] toArray(T[] arg0) {
-                       final T[] result = (T[])Array.newInstance(arg0.getClass().getComponentType(), backend.size());
-                       backend.forEach(new TIntProcedure() {
-                               
-                               int index = 0;
-                               
-                               @Override
-                               public boolean execute(int value) {
-                                       result[index++] = (T)new ResourceImpl(session.resourceSupport, value);
-                                       return true;
-                               }
-                       });
-                       return result;
+               public <T> T[] toArray(T[] a) {
+                       int size = backend.size();
+                       int stms = size / 3;
+                       T[] r = a.length >= size ? a :
+                               (T[])Array.newInstance(a.getClass().getComponentType(), stms);
+                       int index = 0;
+                       for (int i = 0; i < size; i += 3) {
+                               r[index++] = (T) new DirectStatementImpl(session.resourceSupport, backend.getQuick(i), backend.getQuick(i+1), backend.getQuick(i+2));
+                       }
+                       return r;
                }
 
                @Override
@@ -988,12 +1149,25 @@ public class CollectionSupportImpl implements CollectionSupport {
                                return true;
                        if (obj == null)
                                return false;
-                       if (getClass() != obj.getClass())
+                       if (getClass() != obj.getClass()) {
+                               if (obj instanceof Collection) {
+                                       // Nonoptimal fallback for comparing against generic Collection
+                                       Iterator<?> e1 = iterator();
+                                       Iterator<?> e2 = ((Collection<?>) obj).iterator();
+                                       while (e1.hasNext() && e2.hasNext()) {
+                                               Object o1 = e1.next();
+                                               Object o2 = e2.next();
+                                               if (!(o1==null ? o2==null : o1.equals(o2)))
+                                                       return false;
+                                       }
+                                       return !(e1.hasNext() || e2.hasNext());
+                               }
                                return false;
+                       }
                        StatementList other = (StatementList) obj;
                        return session == other.session && backend.equals(other.backend);
                }
-       
+
     }
 
        @Override
@@ -1001,17 +1175,10 @@ public class CollectionSupportImpl implements CollectionSupport {
                return new StatementList(session);
        }
 
-       private static Comparator<Resource> RESOURCE_COMPARATOR = new Comparator<Resource>() {
-               @Override
-               public int compare(Resource o1, Resource o2) {
-                       ResourceImpl r1 = (ResourceImpl)o1;
-                       ResourceImpl r2 = (ResourceImpl)o2;
-                       return compare(r1.id, r2.id);
-               }
-
-               private int compare(int x, int y) {
-                       return (x < y) ? -1 : ((x == y) ? 0 : 1);
-               }
+       private static Comparator<Resource> RESOURCE_COMPARATOR = (o1, o2) -> {
+               ResourceImpl r1 = (ResourceImpl)o1;
+               ResourceImpl r2 = (ResourceImpl)o2;
+               return Integer.compare(r1.id, r2.id);
        };
 
        @Override
@@ -1022,14 +1189,14 @@ public class CollectionSupportImpl implements CollectionSupport {
                        Collections.sort(list, RESOURCE_COMPARATOR);
                }
        }
-       
+
        @Override
        public List<Resource> asSortedList(Collection<Resource> rs) {
                ResourceList result = new ResourceList(session, rs);
                result.sort();
                return result;
        }
-       
+
        @Override
        public org.simantics.db.ResourceSet getResourceSet(ReadGraph graph, Collection<Resource> resources) {
            if(resources instanceof ResourceSet) return (org.simantics.db.ResourceSet)resources;
@@ -1044,5 +1211,5 @@ public class CollectionSupportImpl implements CollectionSupport {
         for(Resource r : rs) result.add(r);
         return result;
     }
-       
+
 }
index 4201d30ec97ec8d01a2c0d1c4bceb6ff7d493dcd..6baef478336118cd7bfb699cbcf9cb84d2904885 100644 (file)
@@ -1,8 +1,7 @@
 package org.simantics.db;
 
 import java.util.Map;
-
-import org.simantics.utils.datastructures.Callback;
+import java.util.function.Consumer;
 
 public interface ResourceMap<T> extends Map<Resource,T> {
 
@@ -11,6 +10,6 @@ public interface ResourceMap<T> extends Map<Resource,T> {
                public T getValue();
        }
        
-       public void iterateEntries(final Callback<ResourceMapEntry<T>> callback);
+       public void iterateEntries(final Consumer<ResourceMapEntry<T>> callback);
 
 }