【问题标题】:Use Java Stream to filter list based on values from second list使用 Java Stream 根据第二个列表中的值过滤列表
【发布时间】: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!)}** <<<<-
                        .filter{c in c.deleted_at == nil}.sorted {
                        $0.index ?? 0 < $1.index ?? 0
                       }
                
                    allModsList?.first?.options = allowedOptions
                
                }
               modisList.append(contentsOf: allModsList!)
            }

感谢任何帮助

【问题讨论】:

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

标签: java sorting java-stream filtering


【解决方案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/stackoverflow-answers/master/javastreamfilter/

【讨论】:

    猜你喜欢
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 2021-08-19
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多