我有一个清单:
List<List<Item>> = [["a", "one", 3], ["b", "one", 2], ["c", "one", 4], ["d", "two", 2],["e", "one", 1], ["f", "two", 1]]
我想用子数组中的第二个值对它进行排序,如果有两个类似的那么它应该按第三个值排序,如果它从那里找到两个像那么它应该按第一个元素排序它们。 所以最终结果应该是这样的:
[["e", "one", 1], ["b", "one", 2], ["a", "one", 3], ["c", "one", 4], ["f", "two", 1], ["d", "two", 2]]
有人能告诉我一些好方法吗?
谢谢!
答案 0 :(得分:3)
["a", "one", 3]
应该是您的类的实例,如
class Item{
private String val1;
private String val2;
private int val3;
//getters and setters
}
这样您的列表就是List<Item>
。现在您只需使用Collections.sort(list, yourComparator)
或者使用Java 8 list.sort(yourComparator)
。
作为yourComparator
,您可以传递实现Comparator
接口的类的实例,例如以某种方式
Comparator<Item> yourComparator = new Comparator<Item>() {
@Override
public int compare(Item o1, Item o2) {
//comapre val2
int result = o1.getVal2().compareTo(o2.getVal2());
if (result != 0) return result;
//if we are here val2 in both objects ware equal (result was 0)
result = Integer.compare(o1.getVal3(), o2.getVal3());
if (result != 0) return result;
return o1.getVal1().compareTo(o2.getVal1());
}
};
但可能更具可读性和可能更简单的方法是为每个字段创建单独的比较器并将它们组合起来。如果您使用的是Java 8,则代码可能如下所示:
Comparator<Item> val1Comparator = Comparator.comparing(Item::getVal1);
Comparator<Item> val2Comparator = Comparator.comparing(Item::getVal2);
Comparator<Item> val3Comparator = Comparator.comparingInt(Item::getVal3);
list.sort(val2Comparator
.thenComparing(val3Comparator)
.thenComparing(val1Comparator));
答案 1 :(得分:2)
这样做的好方法?不是你想的那种方式。列表清单太原始了;自定义对象列表会更好。
为您要运行的案例编写自定义比较器。
答案 2 :(得分:2)
假设"one"
小于"two"
(自"o" < "t"
起),我在这里看不到任何其他“字符串数字”*,可以写一个简单的比较器:
Comparator<List<Item>> c = new Comparator<List<Item>>() {
int[] order = new int[]{1, 2, 0}; // order to compare: 2nd, then 3rd, finally 1st
@Override
public int compare(List<Item> l1, List<Item> l2) {
for (int i = 0; i < order.length - 1; i++) {
int result = l1.get(i).compareTo(l2.get(i));
if (result != 0) // means that i-th elements are not the same
return result;
}
return l1.get(order.length - 1).compareTo(l2.get(order.length - 1));
}
}
然后使用这个比较器排序:
Collections.sort(list, c);
*对于其他“字符串数字”,如“三”,“四”等,如果你需要通过意义进行比较,而不是通过词汇表,你需要定义特殊的映射,这将转换其“意义” “到Integer
号。但这超出了这个问题的范围;发布一个新的程序员让不那么繁忙的程序员练习虚拟速度编码。
答案 3 :(得分:0)
正如duffymo建议的那样,使用一个对象列表。一个简单的结构将会:
class Triple implements Comparable<Triple> {
Item first;
Item second;
Item third;
int compareTo(Triple other) {
int second = compare(this.second, other.second);
if (second == 0) {
int third = compare(this.third, other.third);
if (third == 0) {
return compare(this.first, other.first);
}
return third;
}
return second;
}
static int compare(Item lhs, Item rhs) {
/* Do your compare here! */
}
}
List<Triple> list;
由于struct实现了Comparable,你只需排序:不需要Comparator。
Collections.sort(list);