比较每个索引中每个列表的项目

时间:2019-08-28 11:18:15

标签: java list compare

我有一个String列表的arrayList

ArrayList<List<String>> temp = new ArrayList<List<String>>();

现在,假设我们有3个列表,或者更多:

  • 列表1:[3,8,15,98]
  • 列表2:[3,4,21,98]
  • 列表3:[5,4,76,90]

我只想打印最小的列表。我的意思是列表的升序最小。例如,如果我们将三个列表都删除:

  • 在索引0处:
  

列表1和2的项目= 3

     

列表3的项目= 5

3 <5,所以我不会打印列表3

  • 在索引1处:
  

list1的项目= 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);
                }
            }

但是该方法似乎不是最佳方法。你有什么主意吗? THK

3 个答案:

答案 0 :(得分:1)

任何比较算法都可以使用Java比较器轻松编写。但是首先让我们假设您正在比较一个Integers列表而不是Strings列表,因为这就是您正在做的事情。如果原始数据以字符串格式显示,那么显然您必须将数据转换为数字类型,以将它们作为数字进行比较。

您可以拥有一个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
    }

答案 1 :(得分:1)

这是使用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(),因此自然不会有“最小”列表。

sort函数执行以下操作。它遍历列表的所有索引,并将两个列表中该位置的元素相互比较。它一直走,直到比较结果返回非零值。这意味着该位置的元素不同。如果所有位置的比较结果均返回0,则表示列表之间没有差异(假设所有列表的长度相等)。


如果要处理长度不等的列表,则可以相应地重写sort函数。它遍历两个列表中有效的所有索引。如果所有元素都相等,则选择最短列表。

(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

答案 2 :(得分:0)

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)
        );
    }