【问题标题】:Filter contents of list with entries matching entire contents of another list Java streams使用与另一个列表 Java 流的全部内容匹配的条目过滤列表的内容
【发布时间】:2020-08-28 13:13:33
【问题描述】:

我可能无法正确搜索,但这是一个理论上很简单的查询。我有包含数字的数组列表。我想过滤与另一个列表中的所有条目匹配的列表。

说以下是我的清单 {1,2,3},{1,2},{1},{2},{3}, {2,3}

现在如果我的条件列表是 {1,2} 我应该得到以下结果 {1,2,3},{1,2}

基本上我正在寻找标准列表的所有匹配项。我尝试在谓词中使用包含,但它的返回类似于或条件

//internally it creates array 
products.add(new ProdData(344, 766));
products.add(new ProdData(344,123));
products.add(new ProdData(344,766,123));

List<Integer> matchingVolumes = new ArrayList<>();
    matchingVolumes.add(344);
    matchingVolumes.add(766);
    
products.stream()
    .map(ProdData::getChemVolume)
    .filter(p -> {return matchingVolumes.contains(p);})
    .collect(Collectors.toList());

我想匹配记录 #1 和 3

products 是 ProdData 对象的列表,其中 chemVolume 是我试图匹配标准的字段。条目顺序无关紧要。

【问题讨论】:

  • 你能发布你的代码吗?数组是字面意思 数组,例如int[] 还是列表?
  • 贴出代码,方便我们在本地测试尝试使用
  • 条目的顺序是否重要,或者如果条目存在于数组中的某处就足够了?
  • @niteen22 请在问题中编辑附加信息,您可以在那里很好地格式化代码
  • 您能否编辑问题以包含创建“包含数字的数组列表”的代码?

标签: java java-stream


【解决方案1】:

如果您的意思是您想要一个代码,每次您的条件列表与另一个列表中的参数进行比较(如果不匹配则打印它)。 我建议你使用 Streams(for Java 8)

static Boolean x = false ;
public static void main(String[] args) {
    
    List<List<Integer>> list1 = new ArrayList<>(Arrays.asList(Arrays.asList(1,2,3),Arrays.asList(1),Arrays.asList(1,2),Arrays.asList(2),Arrays.asList(3),Arrays.asList(3,2)));
    List<Integer> list2 = new ArrayList<>(Arrays.asList(1,2));
     
    
    Consumer<List<Integer>> check = list->{if(list.equals(list2)) x = true ;};
    Consumer<List<Integer>> printList =  ListPrinted ->{if(x==false){ System.out.print(ListPrinted); }} ;

    list1.stream().peek(check).forEach(printList);
    
     
}

成功了,我编译了

你可能会问,为什么是布尔 x !!?您可以将其视为停止打字的条件! 为什么我将其设为静态和全局变量? : 因为在 lambda 表达式中,所有局部变量都必须是最终的(我们不希望这样!),并且我们在一个类下工作(我们没有几个对象可以使用)所以我使用静态(一个变量是static:它是一个类变量)。

希望你能理解。

【讨论】:

    【解决方案2】:

    我想你想要这样的东西。如果您的底层数组是对象,这是最简单的,这样您就可以用它们创建列表。如果它们是原语,您可能希望在过滤器中使用 Arrays.binarySearch,但是您必须在过滤器之前的流中执行 Arrays.sort:

    Integer[][] values = {{1,5,3},{1,3},{5,1},{3,5}};
    Integer[] filter = {3,5};
    
    Arrays.stream(values)
          .map (x -> List.of(x))
          .filter( x -> Arrays.stream(filter)
                              .allMatch(y -> x.indexOf(y)>=0))
          .forEach(System.out::println);
    
    // output:
    // [1, 5, 3]
    // [3, 5]
    

    【讨论】:

      【解决方案3】:

      您似乎正在寻找的是:

      .filter(p -> p.getAllChemVolumes().containsAll(matchingVolumes))
      

      您需要在ProductData 中定义getAllChemVolumes 方法以根据您寻求的效率返回Collection&lt;Integer&gt;

      【讨论】:

        【解决方案4】:

        您可以创建 List 并尝试迭代您的主列表并检查过滤器列表中的所有元素是否与 mainList 的子列表匹配。

        class Sample {
            public static void main(String[] args) {
                List<List<Integer>> mainList = List.of(List.of(1, 2, 3), List.of(1, 2), List.of(2));
                List<Integer> filter = List.of(1, 2);
                System.out.println("  " + mainList.stream().filter(integerList -> isListContains(filter, integerList)).collect(Collectors.toList()));
            }
        
            public static boolean isListContains(List<Integer> filter, List<Integer> mainList) {
                return filter.stream()
                        .allMatch(
                                mainList.stream()
                                        .collect(Collectors.toSet())
                                        ::contains);
            }
        
        }
        

        您可以通过使用上面的流和过滤条件来实现相同的功能。 对于过滤,您可以使用 filter.stream()allMatch( 您可以从这里了解更多关于 allMatch 的信息。

        【讨论】:

          猜你喜欢
          • 2015-11-07
          • 1970-01-01
          • 2018-10-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多