gpt4 book ai didi

java - Java 9 集合工厂的使用

转载 作者:搜寻专家 更新时间:2023-10-30 21:46:39 24 4
gpt4 key购买 nike

List.of() or Collections.emptyList() 中给出的评论和答案的上下文中和 List.of(...) or Collections.unmodifiableList()我提出了以下两个经验法则(相应地也适用于 SetMap 工厂)。

  • 不要替换所有出现的

  • 继续使用 Collections.emptyList()为了可读性和当例如初始化惰性字段成员,如:
    class Bean {
    private List<Bean> beans = Collection.emptyList();
    public List<Bean> getBeans() {
    if (beans == Collections.EMPTY_LIST) { beans = new ArrayList<>(); }
    return beans;
    }
    }
  • 使用新工厂作为方法参数构建器

  • 使用新工厂 List.of()当使用 List 调用可执行文件时,和变体作为快速和较少类型的版本参数。这是我目前的替换模式:
    Collections.emptyList()       --> List.of()
    Collections.singletonList(a) --> List.of(a)
    Arrays.asList(a, ..., z) --> List.of(a, ..., z)

    Collections.indexOfSubList 的虚构用法中,以下几行
    Collections.indexOfSubList(Arrays.asList(1, 2, 3), Collections.emptyList());
    Collections.indexOfSubList(Arrays.asList(1, 2, 3), Collections.singletonList(1));
    Collections.indexOfSubList(Arrays.asList(1, 2, 3), Arrays.asList(1));
    Collections.indexOfSubList(Arrays.asList(1, 2, 3), Arrays.asList(2, 3));
    Collections.indexOfSubList(Arrays.asList(1, 2, 3), Arrays.asList(1, 2, 3));

    会读
    Collections.indexOfSubList(List.of(1, 2, 3), List.of());
    Collections.indexOfSubList(List.of(1, 2, 3), List.of(1));
    Collections.indexOfSubList(List.of(1, 2, 3), List.of(1));
    Collections.indexOfSubList(List.of(1, 2, 3), List.of(2, 3));
    Collections.indexOfSubList(List.of(1, 2, 3), List.of(1, 2, 3));

    你(不)同意吗?

    最佳答案

    一般来说,新工厂的使用对于新代码是安全的,其中没有依赖于现有集合行为的现有代码。

    新的集合工厂不能直接替代使用现有 API 初始化集合的代码有几个原因。显然,不变性是最突出的原因之一;如果以后需要修改集合,显然不能一成不变!但也有其他原因,其中一些非常微妙。

    有关使用新 API 替换现有 API 的示例,请参阅 JDK-8134373 .评论主题在这里:Part1 Part2 .

    这是问题的概述。

    数组包装与复制。 有时你有一个数组,例如varargs 参数,并且您希望将其作为列表处理。有时 Arrays.asList是这里最合适的东西,因为它只是一个包装器。相比之下,List.of创建一个副本,这可能会很浪费。另一方面,调用者仍然拥有包装数组的句柄并且可以修改它,这可能是一个问题,因此有时您需要支付复制它的费用,例如,如果您想保留对实例变量中的列表。

    散列集合迭代顺序。 新款Set.ofMap.of结构随机化它们的迭代顺序。 HashSet的迭代顺序和 HashMap是未定义的,但实际上它是相对稳定的。代码可能会无意中产生对迭代顺序的依赖。切换到新的集合工厂可能会将旧代码暴露给迭代顺序依赖性,从而暴露潜在的错误。

    禁止空值。 新集合完全禁止空值,而常见的非并发集合( ArrayListHashMap )允许它们。

    序列化格式。 新集合具有与旧集合不同的序列化格式。如果集合被序列化,或者它存储在其他序列化的类中,则序列化输出将有所不同。这可能是也可能不是问题。但是,如果您希望与其他系统互操作,这可能是一个问题。特别是,如果您将新集合的序列化形式传输到 Java 8 JVM,它将无法反序列化,因为 Java 8 上不存在新类。

    严格的 Mutator 方法行为。 新集合是不可变的,所以它们当然会抛出 UnsupportedOperationException当调用mutator方法时。但是,存在一些边缘情况,其中所有集合的行为不一致。例如,

        Collections.singletonList("").addAll(Collections.emptyList())

    什么都不做,而
        List.of("").addAll(Collections.emptyList())

    会抛出UOE。一般来说,新的集合和不可修改的包装器始终严格地在任何对 mutator 方法的调用上抛出 UOE,即使不会发生实际的变化。其他不可变集合,例如来自 Collections.empty* 的集合和 Collections.singleton* , 只有在实际发生突变时才会抛出 UOE。

    重复。 新款 SetMap工厂拒绝重复的元素和键。如果您使用常量列表初始化集合,这通常不是问题。实际上,如果常量列表有重复项,则可能是错误。这可能是一个问题,当允许调用者传入元素的集合或数组(例如,可变参数)时。如果调用者传入重复项,现有 API 将忽略重复项,而新工厂将抛出 IllegalArgumentException .这是一种可能会影响调用者的行为变化。

    这些问题都不是致命的问题,但它们是您在改造现有代码时应该注意的行为差异。不幸的是,这意味着用新的收集工厂大规模替换现有调用可能是不明智的。可能有必要在每个站点进行一些检查,以评估行为变化的任何潜在影响。

    关于java - Java 9 集合工厂的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40888754/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com