【发布时间】:2021-12-14 20:15:20
【问题描述】:
我有一个带有一组值的 Java List<Integer>,例如:
[0, 5, 2, 1, 3, 2, 6, 1, 1, 0, 10]
我想按每个元素的第一次出现对列表进行排序,新排序的列表如下:
[0, 0, 5, 2, 2, 1, 1, 1, 3, 6, 10]
我正在处理的 List 最多有 400-500 个元素,因此首选轻量级的东西,但我不太想办法。
【问题讨论】:
我有一个带有一组值的 Java List<Integer>,例如:
[0, 5, 2, 1, 3, 2, 6, 1, 1, 0, 10]
我想按每个元素的第一次出现对列表进行排序,新排序的列表如下:
[0, 0, 5, 2, 2, 1, 1, 1, 3, 6, 10]
我正在处理的 List 最多有 400-500 个元素,因此首选轻量级的东西,但我不太想办法。
【问题讨论】:
您可以直接使用indexOf的结果进行排序(返回列表中元素的第一个索引)。
List<Integer> list = Arrays.asList(0, 5, 2, 1, 3, 2, 6, 1, 1, 0, 10);
list.sort(Comparator.comparingInt(list::indexOf));
System.out.println(list);
【讨论】:
Map 来存储每个元素的第一次出现进行优化。
我认为使用 LinkedHashMap 有更简单的解决方案,它会记住放置顺序:
List<Integer> source = Arrays.asList(0, 5, 2, 1, 3, 2, 6, 1, 1, 0, 10);
List<Integer> target = new ArrayList<>();
Map<Integer, Integer> map = new LinkedHashMap<>();
source.forEach(number -> map.merge(number, 1, Integer::sum));
map.forEach((key, value) -> {
for (int i = 0; i < value; i++) {
target.add(key);
}
});
System.out.println(target);
【讨论】:
您需要 2 个数据结构:
这段代码做你想做的事:
String in = "0, 5, 2, 1, 3, 2, 6, 1, 1, 0, 10";
String[] split = in.split(", ");
List<Integer> lstIn = Arrays.stream(split).map(Integer::parseInt).collect(Collectors.toList());
Map<Integer, Integer> theMap = new HashMap<>();
List<Integer> listOccurence = new LinkedList<>();
for(Integer i:lstIn) {
theMap.compute(i, (k,v)->v==null?1:v+1);
if(!listOccurence.contains(i)) {
listOccurence.add(i);
}
}
List<Integer> out = new LinkedList<>();
for(Integer i:listOccurence) {
Integer count = theMap.get(i);
for(int j=0;j<count;j++) {
out.add(i);
}
}
System.out.println(out);
打印出来:
[0, 0, 5, 2, 2, 1, 1, 1, 3, 6, 10]
【讨论】: