基于另一个列表的 1 个列表的流过滤器 [英] Stream Filter of 1 list based on another list

查看:23
本文介绍了基于另一个列表的 1 个列表的流过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在此论坛中搜索后发布了我的查询 &谷歌,但无法解决相同的问题.例如:Link1 Link2 Link3

I am posting my query after having searched in this forum & google, but was unable to resolve the same. eg: Link1 Link2 Link3

我正在尝试根据列表 1 中的值过滤列表 2(多列).

I am trying to filter List 2 (multi column) based on the values in List 1.

List1:
 - [Datsun]
 - [Volvo]
 - [BMW]
 - [Mercedes]

List2: 
 - [1-Jun-1995, Audi, 25.3, 500.4, 300]
 - [7-Apr-1996, BMW, 35.3, 250.2, 500]
 - [3-May-1996, Porsche, 45.3, 750.8, 200]
 - [2-Nov-1998, Volvo, 75.3, 150.2, 100]
 - [7-Dec-1999, BMW, 95.3, 850.2, 900]

expected o/p:
 - [7-Apr-1996, BMW, 35.3, 250.2, 500]
 - [2-Nov-1998, Volvo, 75.3, 150.2, 100]
 - [7-Dec-1999, BMW, 95.3, 850.2, 900]

代码

// List 1 in above eg
List<dataCarName> listCarName = new ArrayList<>(); 
// List 2 in above eg
List<dataCar> listCar = new ArrayList<>(); 

// Values to the 2 lists are populated from excel

List<dataCar> listOutput = listCar.stream().filter(e -> e.getName().contains("BMW")).collect(Collectors.toList());

在上面的代码中,如果我提供了可以过滤的特定值,但不确定如何检查列表 2 中的汽车名称是否存在于列表 1 中.

In the above code if I provide a specific value I can filter, but not sure how to check if Car Name in List 2 exits in List 1.

希望我面临的问题很清楚,等待指导(我对 Java 还比较陌生,因此如果上述查询非常基本,请原谅).

Hope the issue I face is clear, await guidance (Am still relatively new to Java, hence forgive if the above query is very basic).

编辑我相信上面提供的 link-3 应该可以解决,但在我的情况下它不起作用.也许是因为 list-1 中的值填充为org.gradle04.Main.Cars.dataCarName@4148db48 .. 等只有当我通过调用 getName 方法在 List 1 上执行 forEach 时,我才能以人类可读的格式获取值.

Edit I believe the link-3 provided above should resolve, but in my case it is not working. Maybe because the values in list-1 are populated as org.gradle04.Main.Cars.dataCarName@4148db48 .. etc. I am able to get the value in human readable format only when I do a forEach on List 1 by calling the getName method.

推荐答案

不清楚为什么您首先使用 List 而不是 List/Set.

It's not clear why you have a List<DataCarName> in first place instead of a List/Set<String>.

您必须提供的谓词必须检查相应数据汽车实例的名称是否在列表中.

The predicate you have to provide must check if for the corresponding data car instance, there's its name in the list.

e ->e.getName().contains("BMW") 只会检查数据车的名称是否包含不是您想要的 BMW.您的第一次尝试可能是

e -> e.getName().contains("BMW") will only check if the name of the data car contains BMW which is not what you want. Your first attempt then may be

e -> listCarName.contains(e.getName())

但是由于 listCarName 是一个 Liste.getName() 一个字符串(我假设),你会得到结果是一个空列表.

but since listCarName is a List<DataCarName> and e.getName() a string (I presume), you'll get an empty list as a result.

您拥有的第一个选项是更改谓词,以便您从数据汽车名称列表中获取流,将它们映射到它们的字符串表示形式,并检查这些名称中的任何一个是否与您当前的数据汽车实例名称相对应当前过滤:

The first option you have is to change the predicate so that you get a stream from the list of data car names, map them to their string representation and check that any of these names corresponds to the current data car instance's name you are currently filtering:

List<DataCar> listOutput =
    listCar.stream()
           .filter(e -> listCarName.stream().map(DataCarName::getName).anyMatch(name -> name.equals(e.getName())))
           .collect(Collectors.toList());

现在这是非常昂贵的,因为您为数据汽车流管道中的每个实例创建一个流.更好的方法是预先构建一个带有汽车名称的 Set,然后简单地使用 contains 作为该集合的谓词:

Now this is very expensive because you create a stream for each instance in the data car stream pipeline. A better way would be to build a Set<String> with the cars' name upfront and then simply use contains as a predicate on this set:

Set<String> carNames = 
    listCarName.stream()
               .map(DataCarName::getName)
               .collect(Collectors.toSet());

List<DataCar> listOutput =
     listCar.stream()
            .filter(e -> carNames.contains(e.getName()))
            .collect(Collectors.toList());

这篇关于基于另一个列表的 1 个列表的流过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆