java - 在Java中开发泛型修饰符的正确方法

标签 java oop generics collections

在 Java 中,我们有这样的函数:

public Collection<String> removeNulls(Collection<String> input) {
    List<String> output = new ArrayList<>();
    // ...
    return output;
}

请注意,我没有以任何方式修改输入,因为很多时候我们碰巧使用 ImmutableList 作为 List。更常见的是,我们尽可能地确保函数的不变性。然而,我在这里看到的一个陷阱是,我的所有方法都经常使用它们自己的 Collection 实现。如果使用我的库的人使用的是 LinkedListSetSortedSet,则假设“查找是 O(1)”或“列表始终排序”每当在他们的列表上调用我的函数时就会中断:

Set<String> mySet = new SortedSet<>();
mySet.add(10);
mySet.add(9); // I know that my collection is now sorted
Collection<String> myFilteredSet = removeNulls(mySet); // It is no longer sorted
Set<String> mySet = Sets.newSortedSet(myFilteredSet); // Have to sort it again

LinkedList 的情况下,这变得更加微妙,如果我的函数返回一个 List,那么我将继续使用该列表。它不会有任何编译时错误,我们也不会看到我们看到的问题。在之前的案例中,问题至少是可见的,因为我仍然必须将返回的 Collection(或 List)转换为 Set,而且我知道发生了什么。这个问题只会在以后出现,如果有一些繁重的处理正在进行,这取决于正在使用的 LinkedList。一种理想的方式(虽然并不意味着“推荐”)是:

public List<String> removeNulls(List<String> input) {
    List<String> output = (List<String>)input.getClass().newInstance();
    // ...
    return output;
}

通过这种方式,我确保至少使用相同的类型实现。在您看来,这个问题的解决方案是什么?

编辑

澄清一下,我实际上没有 removeNulls 方法,这不是我要找的。这个问题不属于现实生活中的问题,而更像是一个“需要思考的事情”。换句话说,我的问题是,假设你给我一个集合,我必须返回另一个以某种方式派生自它并且不修改输入的集合,我如何确保我的输出集合遵守契约(Contract)(或具体来说,输入集合的实现?

最佳答案

我认为您的方法需要改变。

如果您以后需要调整它们,那么创建不可变集合没有什么意义。集合应该在暴露给外界之前设置为不可变的(如果有必要)。因此,您应该只对可修改的集合进行操作,并允许您的方法调整参数。

如果您从其他地方收到不可变集合,请将其转换为可修改集合,然后按照上述方法操作。

关于java - 在Java中开发泛型修饰符的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24240085/

相关文章:

oop - UML 和算法

java - 从现有子集创建子集的有效方法?

c# - 使用 IEnumerable<T> 创建通用集合的通用类

generics - 如何让 Rust 函数接受任何 float 类型作为参数

java - 使用预定义字符混合/混淆字符串的简单算法

java - 为什么使用 ImageIO 下载的文件比浏览器下载的文件小?

java - Micronaut自定义验证约束,根据值编写自定义消息

c# - .NET Stream 类是否设计不当?

java - 控制 Web 服务中的命名空间前缀?

swift - 如何在 Swift 中调用具有动态类型的泛型函数