我有一个数组字符串列表列表
ArrayList<List<String>> temp = new ArrayList<List<String>>();
现在,假设我们有 3 个列表 o 更像:
- 列表 1 : [3,8,15,98]
- 列表 2 : [3,4,21,98]
- 列表 3 : [5,4,76,90]
我只想打印最小的列表。我的意思是具有最小升序的列表。例如,如果我们取三个列表 abose :
- 在索引 0 处:
列表 1 和 2 的项目 = 3
清单 3 中的项目 = 5
3<5 所以我不会打印列表 3
- 在索引 1 :
列表1 的项 = 8
清单 2 中的项目 = 4
4<8 所以我必须打印列表 2
事实上,我尝试在每个索引上比较每个列表的项目。
ArrayList<List<String>> temp = new ArrayList<List<String>>();
//...
//...
for(int i=0; i<temp.size()-1; i++) {
for(int j=0; j<temp.get(i).size(); j++) {
int min = Integer.valueOf(temp.get(i+1).get(j));
if(Integer.valueOf(temp.get(i).get(j)) < min) {
min = Integer.valueOf(temp.get(i).get(j));
}else if(Integer.valueOf(temp.get(i).get(j)) >=min) {
temp.get(i).remove(j);
}
}
但这种方法似乎不是最好的方法。你有什么想法吗?太赫克
这是另一种使用Java Streams的方法:
List<Integer> list1 = Arrays.asList(3, 8, 15, 98);
List<Integer> list2 = Arrays.asList(3, 4, 21, 98);
List<Integer> list3 = Arrays.asList(5, 4, 76, 90);
Optional<List<Integer>> result = Stream.of(list1, list2, list3)
.sorted((a, b) -> IntStream.range(0, a.size())
.map(i -> Integer.compare(a.get(i), b.get(i)))
.filter(i -> i != 0)
.findFirst()
.orElse(0))
.findFirst();
System.out.println(result);
这就是它的工作原理。
我们流式传输列表,使用特定Comparator
对流进行排序,然后找到第一个匹配项。它返回一个Optional
,如果您不提供任何列表,则Optional.empty()
,因此自然没有"最小"。
排序函数执行以下操作。它遍历列表的所有索引,并将两个列表中该位置的元素相互比较。它一直行走,直到比较返回非零值。这意味着该位置的元素不同。如果所有仓位的比较都返回 0,则意味着列表之间没有差异(前提是所有列表的长度相等(。
如果要处理长度不等的列表,可以相应地重写排序函数。它遍历两个列表中有效的所有索引。如果所有元素相等,则选择最短的列表。
(a, b) -> IntStream.range(0, Math.min(a.size(), b.size()))
.map(i -> Integer.compare(a.get(i), b.get(i)))
.filter(i -> i != 0)
.findFirst()
.orElse(Integer.compare(a.size(), b.size()))
Ideone example.
任何比较算法都可以使用Java比较器轻松编写。但首先让我们假设您正在比较整数列表而不是字符串列表,因为这就是您正在做的事情。如果您的原始数据以字符串格式呈现,那么显然您必须将数据转换为数字类型,以将其作为数字进行比较。
您可以使用自定义比较算法拥有一个 TreeSet,它可以保留其元素的顺序。
您可以编写一个比较器,该比较器可以通过多个对象属性进行比较。这很有用,当假设您想按名字和第二个名字(按列 1 和之后按列 2(比较员工列表时。在我们的例子中,我们可以按第一个索引进行比较,然后按第二个索引进行比较,然后按第三个索引进行比较,这个链可以根据需要深入到您的列表中。
public static void main(String[] args) {
List<Integer> list1 = Arrays.asList(3,8,15,98);
List<Integer> list2 = Arrays.asList(3,4,21,98);
List<Integer> list3 = Arrays.asList(5,4,76,90);
int comparisonLength = 4;
Comparator<List<Integer>> comparator = Comparator.comparing(list -> list.get(0));
for(int i = 1; i< comparisonLength; i++) {
final int comparedIndex = i;
comparator = comparator.thenComparing(list -> list.get(comparedIndex));
}
TreeSet<List<Integer>> treeSet = new TreeSet<>(comparator);
treeSet.add(list1);
treeSet.add(list2);
treeSet.add(list3);
System.out.println(treeSet.iterator().next()); //prints the first element in the collection
}
public static void main(String[] args) {
List<String> l1 = Arrays.asList("3", "8", "15", "98");
List<String> l2 = Arrays.asList("3", "4", "21", "98");
List<String> l3 = Arrays.asList("5", "4", "76", "90");
ArrayList<List<String>> list = (ArrayList<List<String>>) Stream.of(l1, l2, l3).collect(Collectors.toList());
System.out.println(
list.stream()
.min(
(a, b) -> {
for (int i = 0; i < Math.min(a.size(), b.size()); i++) {
if (!a.get(i).equals(b.get(i))) {
return Integer.parseInt(a.get(i)) - Integer.parseInt(b.get(i));
}
}
throw new RuntimeException();
}
).orElseThrow(RuntimeException::new)
);
}