Hello,
I am using the class TreeSet from the java collections library and I have a little problem with the "contains(Object)" method.
I want to use the TreeSet to order a number of Layer-Objects by their Z-Coordinate in a little project of mine.
Sometimes the Z-Coordinate of a layer can change, in that case I
1). remove it from the set
2). change its Z-value
3). add it to the set again
However, my problem is that sometimes a Layer that was added to the set can not be removed anymore since the set doesnt notice, that the Layer is contained within the set.
This is how I construct the TreeSet:
For adding and removing I just use the standard functions "add(Object)" and "remove(Object)".private final TreeSet<Layer> allLayers = new TreeSet<>(new Comparator<Layer>() { public int compare(Layer o1, Layer o2) { if (o1.equals(o2)) { return 0; } if (o1.get_z() >= o2.get_z()) { return 1; } return -1; } });
The method "equals" in the Layer class is not overwritten. It is still the default inherited from Object.
I have build a little help function to test this behaviour:
The outcome of this is sometimes:public void containsTest(Layer layer) { for (Layer a : allLayers) { if (a.equals(layer)) { System.out.println(layer+" is contained."); } } System.out.println("Contains " + layer + " = " + allLayers.contains(layer)); }
If I use this class incorrectly please tell me so. Thanks in advance.Layer(0) is contained
Contains Layer(0) = false
Edit:
Here is a small test program with various debug text:
import java.util.Comparator; import java.util.TreeSet; public class Test { private static final TreeSet<Layer> layers = new TreeSet<>(new Comparator<Layer>() { public int compare(Layer o1, Layer o2) { if (o1.equals(o2)) { return 0; } if (o1.get_z() >= o2.get_z()) { return 1; } return -1; } }); public static void main(String[] args) { Layer layer1 = new Layer(); Layer layer2 = new Layer(); Layer layer3 = new Layer(); Layer layer4 = new Layer(); layer1.z = 0; layer2.z = 0; layer3.z = 1; layer4.z = 1; layer1.interleavedLayer = layer2; layer3.interleavedLayer = layer4; add(layer1); add(layer2); add(layer3); add(layer4); layer1.set_z(2); } public static void add(Layer l) { System.out.println("Add layer "+l+" at "+l.get_z()); layers.add(l); containsTest(l); } public static void remove(Layer l) { System.out.println("Remove layer "+l+" at "+l.get_z()); layers.remove(l); containsTest(l); } public static void containsTest(Layer l) { boolean contains = false; for (Layer a : layers) { if (a.equals(l)) { contains = true; break; } } System.out.println(l+" is contained = "+contains); System.out.println("Contains "+l+" = "+layers.contains(l)); System.out.println(); } private static class Layer { private static int num; private String name = getClass().getSimpleName()+num++; private int z; private Layer interleavedLayer; public int get_z() { return z; } public void set_z(int value) { Test.remove(this); z = value; Test.add(this); if (interleavedLayer != null) { interleavedLayer.set_z(value); } } public String toString() { return name; } } }
If I let it run I get the following output:
The important part is underlined.
Add layer Layer0 at 0
Layer0 is contained = true
Contains Layer0 = true
Add layer Layer1 at 0
Layer1 is contained = true
Contains Layer1 = true
Add layer Layer2 at 1
Layer2 is contained = true
Contains Layer2 = true
Add layer Layer3 at 1
Layer3 is contained = true
Contains Layer3 = true
Remove layer Layer0 at 0
Layer0 is contained = true
Contains Layer0 = false
Add layer Layer0 at 2
Layer0 is contained = true
Contains Layer0 = true
Remove layer Layer1 at 0
Layer1 is contained = false
Contains Layer1 = false
Add layer Layer1 at 2
Layer1 is contained = true
Contains Layer1 = true