使用 Java Stream 根据第二个列表中的值过滤列表

Posted

技术标签:

【中文标题】使用 Java Stream 根据第二个列表中的值过滤列表【英文标题】:Use Java Stream to filter list based on values from second list 【发布时间】:2021-07-25 03:22:18 【问题描述】:

我正在尝试根据第二个列表中的值过滤对象列表。

列表 A:

[
   
      "id":"12345",
      "name":"nameOfItem",
      "description":"descriptionOfItem"
   ,
   
      "id":"34567",
      "name":"nameOfItem",
      "description":"descriptionOfItem"
   ,
   
      "id":"56789",
      "name":"nameOfItem",
      "description":"descriptionOfItem"
   
]

列表 B:

["12345", "56789"]

现在我想删除列表 A 中具有列表 B 中可用 ID 的项目。

我正在尝试使用 JavaStream 但无法理解语法,我正在尝试 ForEach 循环但它无法正常工作。

我在 Swift 中做了类似的事情,如下所示。

            if let allModOptions = allModifersList?.first?.options 
                let excludedIDs = pObj?.excluded_ids
                if excludedIDs!.count > 0 
                   let allowedOptions = allModOptions
                   ->>>>    **.filter !excludedIDs!.contains($0.id!)** <<<<-
                        .filterc in c.deleted_at == nil.sorted 
                        $0.index ?? 0 < $1.index ?? 0
                       
                
                    allModsList?.first?.options = allowedOptions
                
                
               modisList.append(contentsOf: allModsList!)
            

感谢任何帮助

【问题讨论】:

请发布您的代码并解释您的问题 我正在尝试使用 JavaStream ... - 这是一个非常基本的问题。发布您的代码,以便我们了解您的确切位置。 我从 Swift 添加了我的单行解决方案,但无法理解相同的 Java Stream 语法。 【参考方案1】:

你应该在主集合上使用过滤器,在列表集合上使用 !contains

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class Scratch 
    static class Element 
        int id;
        String name;
        String description;

        public Element(int id, String name, String description) 
            this.id = id;
            this.name = name;
            this.description = description;
        

        @Override
        public String toString() 
            return "Element" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", description='" + description + '\'' +
                    '';
        
    

    public static void main(String[] args) 
        List<Element> elements = new ArrayList<>(Arrays.asList(
           new Element(12345, "nameofitem", "asdfafd"),
           new Element(34567, "nameofitem", "asdfafd"),
           new Element(56789, "nameofitem", "asdfafd")
        ));
        List<Integer> filterNot = new ArrayList<>(Arrays.asList(12345, 56789));
        List<Element> result = elements.stream().filter(item -> !filterNot.contains(item.id)).collect(Collectors.toList());

        result.forEach(System.out::println);
    



【讨论】:

非常感谢。有效。这一点我错过了 -> !filterNot.contains(item.id)【参考方案2】: 如果我理解正确,您将获得以下信息: 具有 3 个字段的类:idnamedescription。让我们调用这个类Item。 应从List A 中删除的Items 的ID 列表。让我们将此列表称为idsOfItemsToRemove。 要评估的所有 Items 的列表 预期列表; Items 的列表,其中不包含 idsOfItemsToRemove 中存在的任何值。 如果上述假设成立,那么下面的代码 sn-p 应该表明您正在寻求执行的操作。
@Test
public void test() 
    // given
    Integer idOfItemToBeRemoved1 = 12345;
    Integer idOfItemToBeRemoved2 = 56789;
    Item itemExpectedToBeDeleted1 = new Item(idOfItemToBeRemoved1, "nameOfItem", "descriptionOfItem");
    Item itemExpectedToBeDeleted2 = new Item(idOfItemToBeRemoved2, "nameOfItem", "descriptionOfItem");
    Item itemExpectedToBeRetained1 = new Item(34567, "nameOfItem", "descriptionOfItem");
    Item itemExpectedToBeRetained2 = new Item(98756, "nameOfItem", "descriptionOfItem");


    List<Integer> idsOfItemsToRemove = Arrays.asList(
            idOfItemToBeRemoved1,
            idOfItemToBeRemoved2);

    List<Item> listOfItems = Arrays.asList(
            itemExpectedToBeDeleted1,
            itemExpectedToBeDeleted2,
            itemExpectedToBeRetained1,
            itemExpectedToBeRetained2);

    List<Item> expectedList = Arrays.asList(
            itemExpectedToBeRetained1,
            itemExpectedToBeRetained2);

    // when
    List<Item> actualList = listOfItems
            .stream()
            .filter(item -> !idsOfItemsToRemove.contains(item.getId()))
            .collect(Collectors.toList());

    // then
    Assert.assertEquals(expectedList, actualList);

此代码也已pushed 到 Github。

`https://raw.githubusercontent.com/Git-Leon/***-answers/master/javastreamfilter/

【讨论】:

以上是关于使用 Java Stream 根据第二个列表中的值过滤列表的主要内容,如果未能解决你的问题,请参考以下文章

如何根据使用 jQuery/AJAX 和 PHP/MySQL 选择的第一个下拉列表填充第二个下拉列表?

无法根据 UIPickerview 中第一个组件中的值重新加载第二个组件

根据下拉列表的值创建 2 个下拉列表和一个表

根据子列表中的第二个元素按字母顺序对列表进行排序,但不区分大小写[重复]

如何根据第二个数据帧映射第一个数据帧中的值?

使用与第一个下拉列表相同的值填充第二个下拉列表