比较器java中计数器变量的奇怪输出

时间:2016-09-08 08:45:40

标签: java oop collections comparator

我编写了一段代码来了解有关java集合Comparator函数的更多信息。我有两组,每组有3个元素。我想比较一下。 我在下面发布我的代码并输出计数器变量。谁能解释为什么变量i给出了这个奇怪的输出?我无法理解流程。

public class TestProductBundle {
public static void main(String args[]) {

    TestProductBundle productBundle = new TestProductBundle();

    Set<ClassA> hashSetA = new HashSet<ClassA>() {
        {
            add(new ClassA("name", 1, "desc"));
            add(new ClassA("name", 2, "desc"));
            add(new ClassA("name", 3, "desc"));
        }
    };

    Set<ClassA> hashSetB = new HashSet<ClassA>() {
        {
            add(new ClassA("name1", 2, "desc1"));      //"name" & "desc" are different than previous 
            add(new ClassA("name2", 1, "desc2"));
            add(new ClassA("name3", 3, "desc3"));
        }
    };

    if (productBundle.compareCollection(hashSetA, hashSetB)) {
        System.out.println("Equal set of tree");
    } else {
        System.out.println("Unequal set of tree");
    }
}

@SuppressWarnings("serial")
public boolean compareCollection(Set<ClassA> collection1, Set<ClassA> collection2) {

    TreeSet<ClassA> treeSetA = new TreeSet<ClassA>(new CompareID()) {
        {
            addAll(collection1);
        }
    };

    TreeSet<ClassA> treeSetB = new TreeSet<ClassA>(new CompareID()) {
        {
            addAll(collection2);
        }
    };

    if (treeSetA.containsAll(treeSetB) && treeSetB.containsAll(treeSetA))
        return true;
    else
        return false;
    }
}

ClassA的代码和实现Comparator的类。

class ClassA {
String name;
int id;
String desc;

public ClassA(String name, int id, String desc) {
    this.name = name;
    this.id = id;
    this.desc = desc;
}

int getId() {
    return id;
    }
}

&安培;

class CompareID implements Comparator<ClassA> {
    int i = 0;

    @Override
    public int compare(ClassA o1, ClassA o2) {
        System.out.println(i++);                   // Counter variable
        if (o1.getId() > o2.getId())
            return 1;
        else if (o1.getId() < o2.getId())
            return -1;
        else
            return 0;

    }
}

输出(也在调试器中交叉验证)

0
1
2
3
0   // why started from 0 again ?
1      
2
3
4
5
6
7
8
4   // What the hell !!!
5
6
7
8
Equal set of tree  // is that correct output ?

3 个答案:

答案 0 :(得分:3)

我不确定你发现什么是奇怪的。 您有两个 TreeSet实例,每个实例都有自己的CompareID实例作为Comparator,每个CompareID实例都维护它自己的计数器。

因此,看到每个计数器值(0,1,2等等)出现两次并不奇怪。 至于计数器值的出现顺序,这取决于TreeSet的内部实现。

至于

  

树的等号//是正确的输出吗?

是的,两个集都包含相同的元素。订单无关紧要。 为了澄清 - contains的方法containsAllTreeSet考虑将x包含在TreeSet if compare(x,y)==0中的某个元素{ {1}}的{​​1}},其中y是所提供的TreeSet的{​​{1}}方法。因此,在您的示例中,只有compare属性确定两个元素是否相等。

以下方案解释了输出:

compare

编辑:首先,您要向第一个Comparator添加元素(因此连续多次调用第一个id的{​​{1}}),然后您将元素添加到第二个0 // compare method of 1st CompareID object executed 1 // compare method of 1st CompareID object executed 2 // compare method of 1st CompareID object executed 3 // compare method of 1st CompareID object executed 0 // compare method of 2nd CompareID object executed 1 // compare method of 2nd CompareID object executed 2 // compare method of 2nd CompareID object executed 3 // compare method of 2nd CompareID object executed 4 // compare method of 1st CompareID object executed 5 // compare method of 1st CompareID object executed 6 // compare method of 1st CompareID object executed 7 // compare method of 1st CompareID object executed 8 // compare method of 1st CompareID object executed 4 // compare method of 2nd CompareID object executed 5 // compare method of 2nd CompareID object executed 6 // compare method of 2nd CompareID object executed 7 // compare method of 2nd CompareID object executed 8 // compare method of 2nd CompareID object executed TreeSet(因此连续多次调用第二个compare的{​​{1}}),然后调用Comparator,这会导致第一个TreeSet compare Comparator要连续多次调用,最后调用treeSetA.containsAll(treeSetB),这会导致第二个compare的{​​{1}}连续多次被调用。

答案 1 :(得分:1)

这里变量i将初始化为两个比较器对象,你正在初始化i = 0,根据你的观点,这里将对两个集合执行比较方法,而不是按顺序执行,所以最新发生的是你期望序列输出但实际上它不是

0// for set1(collection1)
1
2
3  // remember this value for set 1
0   // for set2(collection2)
1      
2
3
4
5
6
7
8
4   for set1(collection1 which was 3 and now increment to 1 )
5
6
7
8

答案 2 :(得分:1)

添加到@Erans答案。

将代码更改为以下内容,您将看到

时输出的编译器
class CompareID implements Comparator<ClassA> {
    int i = 0;
    String a;
    public CompareID(String input) {
        a = input;
    }
    @Override
    public int compare(ClassA o1, ClassA o2) {
        // Output comperator "id"
        System.out.println(a+ "   "  + i++); // Counter variable
        if (o1.getId() > o2.getId())
            return 1;
        else if (o1.getId() < o2.getId())
            return -1;
        else
            return 0;

    }
}

... 

    TreeSet<ClassA> treeSetA = new TreeSet<ClassA>(new CompareID("A")) {
        {
            addAll(collection1);
        }
    };

    TreeSet<ClassA> treeSetB = new TreeSet<ClassA>(new CompareID("B")) {
        {
            addAll(collection2);
        }
    };

输出将更改为以下内容。评论包括产生输出的内容:

// This is addALL treeSetA
A   0
A   1
A   2
A   3
// this is addAll treeSetB
B   0
B   1
B   2
B   3
// this is treeSetA.containsAll(treeSetB)
A   4
A   5
A   6
A   7
A   8
// this is treeSetB.containsAll(treeSetA)
B   4
B   5
B   6
B   7
B   8

基本上两个comperators只输出

0-8
0-8