我读取了一个包含六列的表,并将其传递到TreeSet
集合中。它确实工作正常,但是,我只是好奇是否有一种更有效的方法来超越compareTo()
方法。提出这个问题的原因是,我将拥有带有更多列的额外集合,而我这样做的方式看来效率如此低下且耗时。重要的是要注意,我所有的class元素都是整数。
另外,我还有一个问题。像compareTo()
在HashCode()
中所做的那样,HashMap()
方法的工作之一是否包含防止重复的内容?
下面,我演示如何定义compareTo()
方法。
public int compareTo(Network o) {
int r = this.headNode > o.headNode? 1 : this.headNode < o.headNode ? -1 : 0;
if(r==0) { r = this.headPeriod1 > o.headPeriod1? 1 : this.headPeriod1 < o.headPeriod1? -1 : 0;
if(r==0) {
r = this.headPeriod2 > o.headPeriod2? 1 : this.headPeriod2 < o.headPeriod2? -1 : 0;
if(r==0) {
r = this.tailNode > o.tailNode? 1 : this.tailNode < o. tailNode? -1 : 0;
if(r==0) {
r = this.tailPeriod1 > o.tailPeriod1 ? 1 : this.tailPeriod1 < o.tailPeriod1 ? -1 : 0;
if(r==0) {
r = this.tailPeriod2 > o.tailPeriod2 ? 1 : this.tailPeriod2 < o.tailPeriod2 ? -1 : 0;
}
}
}
}
}
答案 0 :(得分:3)
您可以创建一个Comparator使其更具可读性:
public class Test {
int age;
int money;
int id;
public Test(int age, int money, int id) {
this.age = age;
this.money = money;
this.id = id;
}
public static void main(String... args) {
Test t1 = new Test(25,200,3);
Test t2 = new Test(30,50,5);
Test t3 = new Test(15,90,9);
Comparator<Test> comp = Comparator.<Test>comparingInt(x -> x.age)
.thenComparingInt(x -> x.money)
.thenComparingInt(x -> x.id);
Set<Test> set = new TreeSet<>(comp); // Pass the comparator to the Treeset, TreeMap, etc., or use it inside of you Comparable.compareTo method.
set.add(t1);
set.add(t2);
set.add(t3);
System.out.println(set); // [Test{age=15, money=90, id=9}, Test{age=25, money=200, id=3}, Test{age=30, money=50, id=5}]
}
@Override
public String toString() {
return "Test{" + "age=" + age + ", money=" + money + ", id=" + id + '}';
}
}
如您所见,您可以使用 Comparator.comparingInt (x-> x。 headNode ) .thenComparingInt(x-> x。 headPeriod2 ) .thenComparingInt(x-> x。 tailNode )...
等,使其更有意义。 随着班级的增长,您可以继续添加更多的.thenComparingInt...。 这样将按照headNode,headPeriod2,tailNode等对它们进行排序。
((而不是x,请使用该变量的任何名称,例如(network-> network.headNode)
Comparator中有更多的静态方法和实例方法来创建可循环使用的不同Comparators。
如果您实现Comparable并想在compareTo方法中使用Comparator ,则将创建的Comparator用作实例字段,并在comparteTo内部使用比较器,如下所示:
public class Test implements Comparable<Test>{
int age;
int money;
int id;
Comparator<Test> comp = Comparator.<Test>comparingInt(x -> x.age)
.thenComparingInt(x -> x.money)
.thenComparingInt(x -> x.id);
public Test(int age, int money, int id) {
this.age = age;
this.money = money;
this.id = id;
}
public static void main(String... args) {
Test t1 = new Test(25,200,3);
Test t2 = new Test(30,50,5);
Test t3 = new Test(15,90,9);
Set<Test> set = new TreeSet<>();
set.add(t1);
set.add(t2);
set.add(t3);
System.out.println(set); // [Test{age=15, money=90, id=9}, Test{age=25, money=200, id=3}, Test{age=30, money=50, id=5}]
}
@Override
public String toString() {
return "Test{" + "age=" + age + ", money=" + money + ", id=" + id + '}';
}
@Override
public int compareTo(Test o) {
return comp.compare(this, o);
}
}
使用方法参考:
public class Test implements Comparable<Test>{
private int age;
private int money;
private int id;
private final Comparator<Test> comp = Comparator.<Test>comparingInt(Test::getId)
.thenComparingInt(Test::getMoney)
.thenComparingInt(Test::getAge);
public static void main(String... args) {
Test t1 = new Test(25, 200, 3);
Test t2 = new Test(30, 50, 5);
Test t3 = new Test(15, 90, 9);
Set<Test> set = new TreeSet<>();
set.add(t1);
set.add(t2);
set.add(t3);
System.out.println(set); // [Test{age=25, money=200, id=3}, Test{age=30, money=50, id=5}, Test{age=15, money=90, id=9}]
}
public Test(int age, int money, int id) {
this.age = age;
this.money = money;
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public int compareTo(Test o) {
return comp.compare(this, o);
}
@Override
public String toString() {
return "Test{" + "age=" + age + ", money=" + money + ", id=" + id + '}';
}
}
希望有帮助。
答案 1 :(得分:1)
这会更短/更简单:
public int compareTo(Network o) {
int r = this.headNode - o.headNode;
if (r == 0) {
r = this.headPeriod1 - o.headPeriod1;
if (r == 0) {
r = this.headPeriod2 - o.headPeriod2;
if (r == 0) {
r = this.tailNode - o.tailNode;
if (r == 0) {
r = this.tailPeriod1 - o.tailPeriod1;
if (r == 0) {
r = this.tailPeriod2 - o.tailPeriod2;
}
}
}
}
}
答案 2 :(得分:1)
但是,无论如何,我都极力避免将值相减以获得比较器的<或>结果。它可能导致错误,并且是一个坏习惯。查看以下内容:
module.SetupECSCluster.aws_launch_configuration.ecs-launch-config: 1 error(s) occurred:
* aws_launch_configuration.ecs-launch-config: Error creating launch configuration: ValidationError: Must use either use group-id or group-name for all the security groups, not both at the same time
status code: 400, request id: 12345678-768a-1234-1234-8117a0c98e5a
Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.
只需使用Comparable功能界面来整理您的要求即可。