【问题标题】:Can I write a single List Stream for this?我可以为此编写一个列表流吗?
【发布时间】:2020-12-31 04:03:28
【问题描述】:

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

(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 的条件)...

给定父类型 4 和子类型 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


    【解决方案1】:

    看起来您想匹配值与输入匹配或值为 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 可能需要调整。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-07
      • 2017-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多