首页 > 解决方案 > Java 8 流式传输从 2 个列表中收集外部列表中记录的最佳方式

问题描述

我有 2 个列表,并且只想根据匹配属性将这些记录保留在两个列表中。我已经实现了 FlatMap,我正在以下面的方式结合 flatmap 过滤条件填充外部列表,并且工作正常。有人可以告诉

  1. 如果这是正确的做法
  2. 有什么其他选择可以做到这一点。
  3. 我还添加了传统方式,即使用 2 个我不想使用的 forloop,因为 forloop 具有 n2 复杂性,

下面是代码片段:

package stream;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.lang.StringUtils;

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

public class FlatMapDemo1 {

   static Map<String, Integer> catalog = new HashMap<>();

    public static void main(String[] args) {

        List<Item> items1 = Arrays.asList(new Item(11, "item1", 1), new Item(12, "item2", 2), new Item(13, "item3", 3));
        Order order1 = new Order(1, "Order1", items1);
        List<Catalog> catalogs =  Arrays.asList(new Catalog("item1"), new Catalog("item3"), new Catalog("item5"), new Catalog(""));

        // Java Stream - is this right way to populate the external list in conjunction with filter condition? If not then how shall we do that without using 2 for loops
        List<Item> items = new ArrayList<>();
        List<Catalog> externalCatalogs =  order1.getItems().stream().flatMap(item -> catalogs.stream()
                .filter(c -> c.getName().equals(item.getName())
                        && items.add(item)))
                .collect(Collectors.toList());
        System.out.println(externalCatalogs);
        System.out.println(items);

        // Using 2 For loops - i don't want to use this approach
        List<Catalog> filteredExternalCatalogs = new ArrayList<>();
        List<Item> filteredItems = new ArrayList<>();

        order1.getItems().stream().forEach(
                i -> {
                    catalogs.stream().forEach(c -> {
                        if(StringUtils.isNotBlank(c.getName()) && i.getName().equals(c.getName())) {
                            filteredExternalCatalogs.add(c);
                            filteredItems.add(i);
                        }
                    });
                }
        );
        System.out.println(filteredExternalCatalogs);
        System.out.println(filteredItems);
    }

    @Data
    @AllArgsConstructor
    public static class Order {
        int id;
        String name;
        List<Item> items;
    }
    @Data
    @AllArgsConstructor
    public static class Item {
        int id;
        String name;
        int quantity;
    }

    @Data
    @AllArgsConstructor
    public static class Catalog {
        String name;
    }
}

标签: javajava-stream

解决方案


这是做同样事情的替代方法。

List<Catalog> xfilteredExternalCatalogs = new ArrayList<>();
List<Item> xfilteredItems = new ArrayList<>();
List<String> ordersList = order1.getItems().stream()
    .map(o -> o.getName())
    .collect(Collectors.toList());

List<String> catalogsList = catalogs.stream()
    .map(o -> o.getName())
    .collect(Collectors.toList());

catalogs.stream()
    .filter(p -> ordersList.contains(p.getName()))
    .forEach(c -> xfilteredExternalCatalogs.add(c));

order1.getItems().stream()
    .filter(p -> catalogsList.contains(p.getName()))
    .forEach(o -> xfilteredItems.add(o));

System.out.println(xfilteredExternalCatalogs);
System.out.println(xfilteredItems);

推荐阅读