我有一个对象列表,每个对象都有一个返回字符串的方法getNumOrder。列表中的对象按字典顺序排序。大多数情况下,列表中的所有对象都具有返回整数的getNumOrder(但并非总是如此)。
如果列表中的所有元素都有整数的NumOrders,我想使用整数排序顺序对它们进行排序。否则,它们将按字典顺序排列。
我使用Java 8 Lambdas尝试过这个
try {
results.sort((r1,r2)-> {
Integer seq1= new Integer(r1.getNumOrder());
Integer seq2= new Integer(r2.getNumOrder());
seq1.compareTo(seq2);
});
}
catch (Exception e) {
// Do nothing: Defaults to lexicographical order.
}
有两个问题:
不要使用new Integer(String)
来解析数字。它一直是deprecated in Java 9。如果你坚持拳击价值(在这种情况下是浪费),请使用Integer.parseInt(String s)
或Integer.valueOf(String s)
。
你追求的lambda将是:
results.sort((r1,r2) -> Integer.compare(Integer.parseInt(r1.getNumOrder()),
Integer.parseInt(r2.getNumOrder())));
如果排序失败,这会使results
保持不变,因为sort()
方法将列表元素复制到数组,对数组进行排序,然后将元素复制回来。
如果您希望将中间值存储在变量中,例如所以你可以在调试时看到它们,你将使用一个lambda块,它需要一个return
语句。这就是你的代码中缺少的东西。
results.sort((r1,r2) -> {
int i1 = Integer.parseInt(r1.getNumOrder());
int i2 = Integer.parseInt(r2.getNumOrder());
return Integer.compare(i1, i2);
});
答案的下面部分是基于误解输入是字符串列表,但它不是,因此它不适用于问题,但我将其留给可能有类似问题的其他人,其中输入是字符串列表。
但这不是好表现。如果字符串没有需要保留的前导零,则最好解析为int
,对int
值进行排序,然后格式化回字符串。
使用流(Java 8+):
results = results.stream()
.mapToInt(Integer::parseInt)
.sorted()
.mapToObj(Integer::toString)
.collect(Collectors.toList());
或者这个非流版本(Java 1.2+):
int[] arr = new int[results.size()];
int i = 0;
for (String s : results)
arr[i++] = Integer.parseInt(s);
Arrays.sort(arr);
results.clear();
for (int v : arr)
results.add(Integer.toString(v));
为了使您的代码有效,只需返回“seq1.compareTo(seq2);”像这样:
try {
results.sort((r1,r2)-> {
Integer seq1= new Integer(r1.getNumOrder());
Integer seq2= new Integer(r2.getNumOrder());
return seq1.compareTo(seq2);
});
}
catch (Exception e) {
// Do nothing: Defaults to lexicographical order.
}
正如@Andreas在评论中所指出的那样,不应该这样做(使用装箱并使用构造函数将String解析为整数),有一种更清洁且“不那么浪费”的方法来实现它。这是代码:
try {
results.sort((r1,r2)->
Integer.compare(Integer.parseInt(r1.getNumOrder()),
Integer.parseInt(r2.getNumOrder()))
);
}
catch (Exception e) {
// Do nothing: Defaults to lexicographical order.
}
请记住,当你使用括号时,你只需要(显式地)在lambda中返回一个值,因为它的处理就像一个方法 - 在“sort”的情况下 - 应该返回一个Integer。
你刚忘了你的lambda中的“回归”:
return seq1.compareTo(seq2);
除此之外,看起来很好,即使它失败了