【问题标题】:How to compare multiple items of an arraylist into another arraylist at specific position?如何将arraylist的多个项目与特定位置的另一个arraylist进行比较?
【发布时间】:2018-12-07 05:40:36
【问题描述】:

背景:有产品列表页面,我必须抓取所有产品名称(包括缺货产品),然后必须验证所有缺货产品到底是什么。

问题:我已经浏览了所有页面并将产品名称存储在 ArrayList 中。

让我们说list1,内容是 -

[instant bcaa, vegan bcaa, complete bcaa energy™, branched chain amino acid (bcaa) tablets 1000mg, endure™, branched chain amino acids (bcaa), instant leucine, leucine tablets 1000mg, complete intra-workout™, leucine, bcaa jelly mix, complete hydration drink™, informed bcaa™, instant bcaa cocktail bundle]

现在我有另一个列表,其中只有缺货产品

list2 和内容是 -

[informed bcaa™, instant bcaa cocktail bundle]

我必须确定 list1 的所有 list2 项是否都以相同的顺序排列

【问题讨论】:

  • 假设列表没有重复项(每个都单独):找到两者上的所有元素(例如使用retainAll());删除所有这些元素 (removeAll) 并在最后再次添加它们 (addAll()) - 最终使用第一个列表的副本。或者,流式:对于 list2 上的每个元素,如果它也在 list1 上,则将其从 list1 中删除并将其添加到 list1 的末尾...

标签: java arraylist collections


【解决方案1】:

这个问题本质上是试图验证给定列表 A 是否以第二个列表 B 结尾。

您可以通过确定列表 B 的长度,从列表 A 的末尾回溯那么多空格,然后对两个列表进行成对比较来实现这一点:

public static boolean listEndsWith(List<?> A, List<?> B) {
    if (B.size() > A.size()) {
        return false;
    }

    for (int i = A.size() - B.size(), j = 0; i < A.size(); i++, j++) {
        if (!A.get(i).equals(B.get(j))) {
            return false;
        }
    }

    return true;
}

【讨论】:

    【解决方案2】:

    Java 8+ 中,您可以使用stream().skip() 跳过初始的list1.size() - list2.size() 对象,然后与list2 进行比较。

        if (list1.size() > list2.size()) {
            AtomicInteger ordinal = new AtomicInteger(0);
            boolean matched = list1.stream().skip(list1.size() - list2.size())
                    .allMatch(item -> item == list2.get(ordinal.getAndIncrement()));
    
            System.out.println(matched);
        }
    

    【讨论】:

      【解决方案3】:

      生成一个新列表,即list1的最后n项,其中n为列表2的长度。然后将列表3与列表1进行比较。

      第三个列表可以这样传递:

      ArrayList list3 = new ArrayList(list1.subList(list1.size() - list2.size(), list2.size())
      

      【讨论】:

      • 好主意,虽然如果list2list1 长,这会抛出IndexOutOfBoundsException,所以你需要先检查一下。
      • 是的,你是对的。在这方面我更喜欢你的方法
      【解决方案4】:

      要检查 list1 是否包含来自特定位置的 list2,您可以使用函数:

       public static boolean compareArrsFromPosition(List<?> list1, List<?> list2, int fromPosition) {
          if (list1.size()-fromPosition < list2.size()) return false;
          return list1.subList(fromPosition,fromPosition+list2.size()).equals(list2);
      }
      

      要检查 list1 的结尾,您可以这样调用

      compareArrsFromPosition(list1, list2, list1.size()-list2.size());
      

      【讨论】:

      • 您可以将其作为单个语句执行,return list1.size()-fromPosition &gt;= list2.size() &amp;&amp; list1.subList(fromPosition,fromPosition+list2.size()).equals(list2);
      【解决方案5】:

      或者,您可以反转您的两个Lists(线性时间虽然可能需要空间来存储副本)并匹配所有基于列表大小迭代的元素B(假设它的大小会更小) 为:

      public static boolean listEndsWith(List<?> A, List<?> B) {
          Collections.reverse(B); // modifies B, so you can choose to clone and reverse
          Collections.reverse(A);
          return IntStream.range(0, B.size())
                  .allMatch(i -> A.get(i).equals(B.get(i)));
      }
      

      【讨论】:

        猜你喜欢
        • 2014-12-07
        • 2011-06-27
        • 1970-01-01
        • 2012-04-12
        • 1970-01-01
        • 2019-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多