我有包含{3,10,17,9,20,15,40,30,55}的arraylist所以我想对这个方法进行排序,以便所有可被10个整除的值在排序后的列表中排在最后排序列表。 即o / p应该是这样的:{3,9,15,17,55,10,20,30,40}
我尝试使用以下代码,但我无法成功整理此列表,
List<Integer> list = Arrays.asList(3,10,17,9,20,55,40,30);
list.stream().sorted(((Comparator<Integer>) (v1, v2) -> Integer.compare(v1, v2))).sorted((Comparator<Integer>) (v1, v2) -> v1 % 10 == 0 ? 0 : -1).forEach(System.out::println);
以上代码的输出是: 55 17 9 3 10 20 三十 40
谢谢,
答案 0 :(得分:3)
看起来您希望将数字逻辑划分为两组,并分别对每个组进行排序。
您可以根据划分10个条件拆分列表,并分别对2个子列表执行排序,或者使用单个Comparator
检查2是否进行比较数字属于同一组:
如果他们这样做,请在他们的小组中按他们的价值进行比较
list.stream()
.sorted((v1, v2) -> {
if (v1 % 10 == 0) {
if (v2 % 10 == 0)
return Integer.compare(v1, v2); // both are divisible by 10
// sort by value
else
return 1; // only v1 is divisible by 10, should come after v2
} else {
if (v2 % 10 != 0)
return Integer.compare(v1, v2); // both are not divisible by 10
// sort by value
else
return -1; // only v2 is divisible by 10, should come after v1
}
})
.forEach(System.out::println);
输出:
3
9
17
55
10
20
30
40
答案 1 :(得分:3)
有两件事要知道。
首先,当您知道自Java 5以来Boolean
值具有可比性时,在排序时很容易按特定谓词进行分组。所以您可以使用
Comparator.comparing(i -> i%10==0)
将可分为10的数字排序到最后。
其次,您可以使用thenComparing
链接比较器,以便根据第一个比较器排列的元素将根据下一个比较器进行排序。
一起操作变为
List<Integer> list = Arrays.asList(3,10,17,9,20,55,40,30);
list.stream()
.sorted(Comparator.comparing((Integer i) -> i%10==0)
.thenComparing(Comparator.naturalOrder()))
.forEach(System.out::println);
请注意,由于类型推断的限制,完整操作需要第一个lambda表达式((Integer i)
)的显式类型参数。
你也可以写
list.stream()
.sorted(Comparator.comparing((Integer i) -> i%10==0)
.thenComparingInt(i -> i))
.forEach(System.out::println);
但是,我更愿意在适用时重复使用现有的比较器Comparator.naturalOrder()
。
答案 2 :(得分:1)
要实现这一目标,您需要:
10
,第二个与不是。{/ li>
这应该是你的代码:
List<Integer> dividedBy10 = list.stream()
.filter(p -> p % 10 == 0).collect(Collectors.toList());
Collections.sort(dividedBy10);
List<Integer> others = list.stream()
.filter(p -> p % 10 != 0).collect(Collectors.toList());
Collections.sort(others);
//Then append the first list to the sorted one
others.addAll(dividedBy10);
修改强>
或者像@yahya建议您可以对原始列表进行排序,然后将其过滤到列表中并稍后附加这两个列表:
Collections.sort(list);
List<Integer> dividedBy10 = list.stream()
.filter(p -> p % 10 == 0).collect(Collectors.toList());
List<Integer> others = list.stream()
.filter(p -> p % 10 != 0).collect(Collectors.toList());
others.addAll(dividedBy10);
答案 3 :(得分:1)
目前,你正在否定那些不能被10整除的数字作为黑客首先将它们排除在外。但这会扭转这些数字的顺序,这会影响你的输出!
在将可整除的10个数字进行比较时需要更加小心,因此比较器将它们排在低于其他数字的位置。这样的事情会起作用:
list.stream().sorted(((Comparator<Integer>) (v1, v2) -> {
if (v1 % 10 == 0 && v2 % 10 == 0) {
return Integer.compare(v1, v2);
} else if (v1 % 10 == 0) {
// v2 is effectively larger
return -1;
} else if (v2 % 10 == 0) {
// v1 is effectively larger
return 1;
}
return Integer.compare(v1, v2);
}))/*etc*/
答案 4 :(得分:0)
需要单一种类:
list.stream().sorted(((Comparator<Integer>) (v1, v2) -> {
// if both are divisible by 10, you sort them with their order natural
if (v1 % 10 == 0 && v2 % 10 == 0) {
return Integer.compare(v1, v2);
}
// if only the first argument is divisible by 10, it is always at the end
else if (v1 % 10 == 0) {
return 1;
}
// if only the second argument is divisible by 10, it is always at the end
else if (v2 % 10 == 0) {
return -1;
}
// in other cases, you sort by natural order
return Integer.compare(v1, v2);
}))
.forEach(System.out::println);
这是输出:
3 9 17 55 10 20 30 40
答案 5 :(得分:0)
(a,b) -> (a<b?-1:a==b?0:1) + (a%10==0?2:0) - (b%10==0?2:0)
这是如何运作的:
(a<b?-1:a==b?0:1)
通常比较整数(权重为1)
+ (a%10==0?2:0)
检查第一个整数是否可被10整除(权重为2)
- (b%10==0?2:0)
检查第二个整数是否可被10整除(权重为2)
只要Integer.compare
只返回-1,0,1就可以使用它(但是@Holger指出没有保证)
(a,b) -> Integer.compare(a, b) + (a%10==0?2:0) - (b%10==0?2:0)
答案 6 :(得分:0)
您只有三个返回值:
Integer.compare(a, b)
如果两个值都可以被10整除,那么它们不是> 0
如果第一个值可被10整除< 0
其他list.sort((a, b) -> {
if ((a % 10 == 0) == (b % 10 == 0)) {
return a.compareTo(b);
} else {
return a % 10 == 0 ? 1 : -1;
}
});
或者如果您更喜欢不可读的代码
list.sort((a, b) -> (a % 10 == 0) == (b % 10 == 0) ? a.compareTo(b) : a % 10 == 0 ? 1 : -1);