我有多个并行的ArrayList,我正在对其中一个(即索引(进行排序。
ArrayList<Integer> indexes = {2,3,1};
ArrayList<String> names = {"two","three","one"};
ArrayList<String> upper = {"TWO","THREE","ONE"};
我想将ArrayList"索引"的排序与其他ArrayList同步。我想知道在Collections.sort(list)
会给我一个线索吗?
听起来像是要根据一个数组的值对其进行排序,然后重新排列另外两个数组,使其值的排列与第一个数组的排序顺序相匹配。
一种简单的方法是将一个索引数组按所需顺序排序,然后使用此方法将其他数组按相同顺序重新排列。由于您的一个数组已经被称为";索引";我将把这个新数组称为";置换";。
首先,通过生成从0到size-1的索引值,然后对它们进行排序,创建排列数组。它们最终不是根据自己的值排序,而是根据索引数组中的值进行排序:
List<Integer> indexes = List.of(2,3,1);
List<String> names = List.of("two","three","one");
List<String> upper = List.of("TWO","THREE","ONE");
List<Integer> permutation = IntStream.range(0, indexes.size())
.boxed()
.sorted(comparing(indexes::get))
.collect(toCollection(ArrayList::new));
(到目前为止,这与厄立特里亚的回答中的技术相似。(
现在,我们需要根据排列数组中的排列来重新排列一些数据数组。由于我们多次这样做,这里有一个函数可以做到这一点:
static <T> List<T> permute(List<Integer> permutation, List<T> list) {
return IntStream.range(0, permutation.size())
.mapToObj(i -> list.get(permutation.get(i)))
.toList();
}
现在,将其应用于每个数据阵列很简单:
System.out.println(permute(permutation, indexes));
System.out.println(permute(permutation, names));
System.out.println(permute(permutation, upper));
结果是
[1, 2, 3]
[one, two, three]
[ONE, TWO, THREE]
请注意,这将按所需排列创建新列表。可以在适当的位置排列数据数组,但这需要做更多的工作,尽管并不棘手。(搜索"[java]置换数组就位"以获取想法。(
从indexes
创建一个优先级列表,并使用元素的索引作为排序标准:
public static void main(String args[]) {
List<Integer> indexes = new ArrayList<>(List.of(2,3,1));
List<String> names = new ArrayList<>(List.of("two","three","one"));
List<String> upper = new ArrayList<>(List.of("TWO","THREE","ONE"));
List<Integer> priority = IntStream.range(0, indexes.size())
.boxed()
.sorted(Comparator.comparingInt(indexes::get))
.collect(Collectors.toList());
names.sort(Comparator.comparingInt(i -> priority.indexOf(names.indexOf(i))));
upper.sort(Comparator.comparingInt(i -> priority.indexOf(upper.indexOf(i))));
indexes.sort(Comparator.comparingInt(i -> priority.indexOf(indexes.indexOf(i))));
System.out.println(indexes);
System.out.println(names);
System.out.println(upper);
}
您可以使用容器作为中间步骤(不过,修改您的代码以简单地使用容器而不是3个单独的列表可能会更好(:
public class Container {
final int id;
final String name;
final String upper;
... // constructor + getters (or create a record if you're using j14+)
}
public static void main(String args[]) {
List<Container> values = indexes.stream()
.sorted()
.map(index -> new Container(index, names.get(index), upper.get(index)))
.collect(Collectors.toList());
List<String> sortedNames = values.stream()
.map(value -> value.getName())
.collect(Collectors.toList());
List<String> sortedUpper = values.stream()
.map(value -> value.getUpper())
.collect(Collectors.toList());
}