在Java中开发通用修饰符的正确方法

罗汉·普拉布(Rohan Prabhu)

在Java中,我们具有以下功能:

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

请注意,我没有以任何方式修改输入,因为我们花了很多时间来使用ImmutableListList。更常见的是,我们尝试尽可能确保功能的不变性。但是,我在这里看到的一个陷阱是,我的所有方法经常都使用自己的实现Collection如果有人在使用我的库时使用LinkedList或aSet或a SortedSetO(1)则只要在他们的列表上调用我的函数,诸如“ lookups are ”或“ list总是被排序”的假设就会中断:

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

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

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

这样,我确保至少使用相同的类型实现。您认为该问题的解决方案是什么?

编辑

只是为了澄清一点,我实际上没有removeNulls方法,这不是我想要的。这个问题与现实生活中的问题无关,而是更多的“思考问题”。换句话说,我的问题是,鉴于您给了我一个集合,我必须返回另一个以某种方式派生自该集合且不修改输入的集合,如何确保我的输出集合遵守合同(或输入收集的具体实现)?

Proskor

我猜想,您想要的是用操作修改Collection接口withoutNulls,并相应地实现它,但是由于您不能“向现有集合类中添加新方法”,因此您很不走运。但是,因为你经常使用自己的集合实现,也许你可以扩展你的接口,并提供了一些方法,以定期集合类转换成你自己的。

像这样:

public interface BetterCollection<E> extends Collection<E> {
    BetterCollection<E> withoutNulls();
}

public class BetterLinkedList<E> extends LinkedList<E> implements BetterCollection<E> {
    public BetterLinkedList() {}

    public BetterLinkedList(LinkedList<E> input) {
        super(input);
    }

    @Override
    public BetterCollection<E> withoutNulls() {
        BetterCollection<E> result = new BetterLinkedList<E>();
        ...
        return result;
    }
}

我认为在C#中可以使用扩展方法,但是您在实现上受到一些限制(例如,您无法访问私有字段,并且不确定它们是否可以是虚拟的)。

Java的另一种解决方案是重载方法,使它们接受不同的集合类型,例如removeNulls(LinkedList<String>)removeNulls(SortedSet<String>),但显然也有其缺点。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Java中的方法修饰符

来自分类Dev

Java中c#通用修饰符“ out”的替代方法

来自分类Dev

Java中c#通用修饰符“ out”的替代方法

来自分类Dev

Java枚举中的EnumSet修饰符

来自分类Dev

Java批注中的字段和方法的默认修饰符是哪些?

来自分类Dev

我应该在Java中的方法中使用哪个访问修饰符?

来自分类Dev

Javascript:Java中RegExp的/ e修饰符

来自分类Dev

与C ++相比Java中的访问修饰符

来自分类Dev

来自 C++ 的静态修饰符,但在 Java 中?

来自分类Dev

检查方法的访问修饰符

来自分类Dev

ABC是否执行方法修饰符?

来自分类Dev

Prestashop 未使用修饰符方法

来自分类Dev

java访问修饰符互相淘汰?

来自分类Dev

C#中的幂等修饰符

来自分类Dev

如何理解木偶中的修饰符

来自分类Dev

C#中的访问修饰符

来自分类Dev

Laravel中的列修饰符

来自分类Dev

SwiftUI中的.transition修饰符

来自分类Dev

JS中的局部修饰符

来自分类Dev

Python中“ @package”修饰符的含义

来自分类Dev

宏中的冒号修饰符

来自分类Dev

AtTask修饰符

来自分类Dev

使用EnableDelayedExpansion时,变量修饰符的语法正确

来自分类Dev

更改签名的修饰符:正确记录附加参数

来自分类Dev

Java中任何类文件中MODULE变量的最佳访问修饰符?

来自分类Dev

在运行时调用方法时如何忽略修饰符-JAVA

来自分类Dev

我应该为Angular中的模板可访问方法提供哪种访问修饰符?

来自分类Dev

访问修饰符是C#中“方法签名”的一部分吗?

来自分类Dev

Web方法中的正则表达式修饰符