我编写了一段代码来了解有关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 ?
答案 0 :(得分:3)
我不确定你发现什么是奇怪的。
您有两个 TreeSet实例,每个实例都有自己的CompareID
实例作为Comparator
,每个CompareID
实例都维护它自己的计数器。
因此,看到每个计数器值(0,1,2等等)出现两次并不奇怪。
至于计数器值的出现顺序,这取决于TreeSet
的内部实现。
至于
树的等号//是正确的输出吗?
是的,两个集都包含相同的元素。订单无关紧要。
为了澄清 - contains
的方法containsAll
和TreeSet
考虑将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