首页 > 解决方案 > 我可以为此编写一个列表流吗?

问题描述

说,我有一个如下的配置类(我已经包含了下面的类)

(parentType, subType) 对可以具有以下其中一个 {(0, 0), (X, 0), (X, Y)} 其中 X > 0,并且 Y > 0。对于任一父类型,值为 0或子类型,表示它是一种常见的配置。非零值是特定配置。通用配置适用于所有类型,尤其是在没有特定配置的情况下。

如果我有一个具有以下值的 Config 对象列表(List),则以这种格式给出的值(类别、父类型、子类型、值):

("A", 0, 0, 5), ("A", 2, 0, 6), ("A", 2, 1, 9)
("B", 0, 0, 5), ("B", 2, 0, 6), 
("C", 0, 0, 5), ("C", 4, 0, 13)
("D", 4, 1, 11), ("D", 4, 0, 9)

如果我正在搜索父类型 = 2 和子类型 = 1 的配置,我想要以下列表作为结果列表。 ("A", 2, 1, 9), ("B", 2, 0, 6), ("C", 0, 0, 5)

我们没有得到“D”对象,因为在“D”下,我们没有特定的父类型 2,也没有共同的父类型 0。

同样,如果我正在搜索父类型 = 4 和子类型 = 1 的配置,我希望将以下列表作为结果列表。 ("A", 0, 0, 5), ("B", 0, 0, 5), ("C", 4, 0, 13), ("D", 4, 1, 11)

对于父类型 4 和子类型 1(下面仅编码一个想法) list.stream().filter(oneConf -> (4.equals(oneConfig.getParentType()) && 1.equals(oneConfig.getSubType()) )).findFirst().orElse(null)

上面将只给出 4 和 1 的配置。我可以再有两个 list.stream().filter(4 和 0 的条件)... list.stream().filter(0 和 0 的条件)...

给定 parenttype 4 和 subtype 1,我们是否可以得到以下结果列表,具有 Java 8 的特性,而无需编写许多代码循环。("A", 0, 0, 5), ("B", 0, 0, 5), ("C", 4, 0, 13), ("D", 4, 1, 11)

public class Config {
    String category;
    Integer parentType;
    Integer subType;
    Integer value;
    
    public Config() {}
    public Config(String pCategory, Integer pParentType, Integer pSubType, Integer pValue) {
        category = pCategory;
        parentType = pParentType;
        subType = pSubType;
        value = pValue;
    }
    
    
}

标签: java

解决方案


看起来您想要匹配值与输入匹配或值为 0 的每种类型(父/子)。我还猜测您只需要每个类别中的一个 Config。

这可能会做你想要的:

private static List<Config> filterConfig(List<Config> list, int parentType, int subType) {
    return new ArrayList<>(list.stream()
            .filter(c -> c.parentType == 0 || c.parentType == parentType)
            .filter(c -> c.subType == 0 || c.subType == subType)
            .collect(Collectors.toMap(
                    c -> c.category,
                    Function.identity(),
                    (p, q) -> p.parentType != 0 ? (p.subType != 0 ? p : q) : q
            )).values());

}

测试:

System.out.println("2/1");
filterConfig(list, 2, 1).forEach(System.out::println);
System.out.println("4/1");
filterConfig(list, 4, 1).forEach(System.out::println);

输出:

2/1
Config{category='A', parentType=2, subType=1, value=9}
Config{category='B', parentType=2, subType=0, value=6}
Config{category='C', parentType=0, subType=0, value=5}
4/1
Config{category='A', parentType=0, subType=0, value=5}
Config{category='B', parentType=0, subType=0, value=5}
Config{category='C', parentType=4, subType=0, value=13}
Config{category='D', parentType=4, subType=1, value=11}

解释

第一个过滤器找到任何匹配 parentType 或 parentType 为 0 的 Config(并删除任何非命中)。

第二个过滤器查找任何匹配 subType 或 subType 为 0 的 Config。

Collector.toMap() 将对象放入以类别为键的地图中。这确保我们每个类别最多找到 1 个配置。该值是 Config 对象本身。

toMap() 的第三个参数是一个选择器,当发生键冲突时,它会从两个对象中选择一个。我放置的 lambda 应该首先选择具有非 0 父类型和其次非 0 子类型的任何一个。如果未找到,请选择第二个。

免责声明:我仅针对您的输入对其进行了测试,因此 lambda 可能需要调整。


推荐阅读