【问题标题】:How to compare two ArrayList and get list1 with filter using java streams如何使用java流比较两个ArrayList并使用过滤器获取list1
【发布时间】:2019-12-03 07:07:02
【问题描述】:

我有两个 List 类型的列表 list1 和 list2

Term{
long sId;
int rowNum;
long psid;
String name;
}

List<Term> list1 = new ArrayList<>();
List<Term> list2 = new ArrayList<>();

我想返回 list1 where (list1.psid != list2.psid) 中的所有项目。

我试过了,但它不起作用

public List<Term> getFilteredRowNum(List<Term> list1, List<Term> list2) {
        List<Long> psid = list2.stream().map(x -> x.getPsid()).collect(Collectors.toList());

        return list1.stream().filter(x -> !psid.contains(x.getPsid())).map(x -> x.getRowNum()+1).collect(Collectors.toList());

    }

我想获取 list1 中满足休闲条件的所有记录 if(list1.psid != list2.psid)

Sample Date:
List1: rowNum     psId    name    sid
       1         1288     home    101
       1         9012     home    101
       2         1296     office  150
       3         1290     park    161

List2: rowNum     psId    name    sid
       1          9012    home    101
       2         1296     office  150
       3         1290     park    161

List1 psId not in list2 so I am expecting fallowing list as result from list1

Expected: List1
 rowNum     psId    name    sid
 1         1288     home    101

【问题讨论】:

    标签: java collections java-8 java-stream


    【解决方案1】:

    您正在过滤谓词中寻找内部anyMatch

    public List<Term> getFilteredRowNum(List<Term> termList1, List<Term> termList2) {
        return termList1.stream()
                .filter(term1 -> termList2.stream()
                        .anyMatch(term2 -> term1.getSId() == term2.getSId()
                                && term1.getPsid() != term2.getPsid()))
                .collect(Collectors.toList());
    }
    

    解决此问题的另一种方法是使用groupingBymapping 在任何列表中创建Mapsidpsids 的Set

    Map<Long, Set<Long>> sIdToPsIdsMap = termList2.stream()
            .collect(Collectors.groupingBy(Term::getSId, 
                    Collectors.mapping(Term::getPsid, Collectors.toSet())));
    

    并进一步将其用于filter 条件

    return termList1.stream()
            .filter(term1 -> sIdToPsIdsMap.containsKey(term1.getSId())
                    && !sIdToPsIdsMap.get(term1.getSId()).contains(term1.getPsid()))
            .collect(Collectors.toList());
    

    【讨论】:

    • 我只是想添加您的第二个解决方案,因为它可以提高语言列表的性能。您还可以使用 Map.getOrDefault(): !sIdToPsIdsMap.getOrDefault(term1.getSId(), new HashSet&lt;&gt;()).contains(term1.getPsid()) 来使用单个条件。
    • @SamuelPhilipp 但尽管没有key,但它不会总是执行contains 检查吗?
    • 我根据您的解决方案尝试了这个,但它没有过滤。我什至尝试只寻找一个条件,即 list1 psId(不在)list2 psId。 public List getFilteredSBDRowNum(List list1, List list2) { return list1.stream().filter(term1 -> list2.stream().anyMatch(term2 -> term1.getPsid() != term2.getPsid())).collect(Collectors.toList()); }
    • @Sruthi 你能用你得到的样本输入、预期输出和当前输出更新问题吗?将进一步澄清我们缺少什么。
    • @Naman 好的,肯定会发布差异问题。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 2013-05-24
    • 2019-11-27
    • 2011-03-27
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多