[Java] TreeSet Contains Problem

Accname

2D-Graphics enthusiast
Reaction score
1,462
Hi guys.
I am desperate. This piece of shit is driving me CRAZY.

I have a TreeSet with this custom comparator:

Code:
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;
        }
    });
And then I have this:

Code:
    public void containTest(Layer obj) {
        for (Layer a : layers) {
            if (a.equals(obj)) {
                System.out.println(obj+" is contained.");
            }
        }
        System.out.println("Contains "+obj+" = "+layers.contains(obj));
    }
Guess what the outcome is...
Layer(0) is contained.
Contains Layer(0) = false

By the way, the equals method is NOT changed at all for these classes. Its still the default equals from Object.


Heres the official documentation from oracle.
http://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html#contains(java.lang.Object)
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
Here is an example program:
Code:
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;
        }
       
    }
   
}

And this is the outcome I get:
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
The important part is underlined.
 

camelCase

The Case of the Mysterious Camel.
Reaction score
362
For what it's worth, C# has this issue, too, with one of their container classes. It drove me nuts till I coded my own.
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
In case anybody wants to know, the problem is, that a TreeSet can not store 2 objects with the same value.
In my case, once 2 Layers have the same Z-coordinate, the set just assumes that they are both equal.
So I go with an ArrayList now and sort with the Collections method.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top