Java:通过引用Collection来克隆任意Collection
假设您在方法中有一个 java.util.Collection
类型的引用,并且无法说明它在运行时将指向 java.util.Collection
的哪个实现,是可以克隆该集合吗?
我想实现一个通用方法,它将过滤给定的任何类型的集合。因此该方法将采用 java.util.Collection 作为输入。然而除此之外,我不想修改原始集合,所以我想克隆该集合。
Suppose you've a reference of type java.util.Collection
in a method and cannot say what implementation of java.util.Collection
will it point to at run time, is it possible to clone the Collection?
I wanted to implement a generic method which will filter any type of collection given. Hence the method will take java.util.Collection
as input. However beyond this, I didn't want to modify the original collection, so I wanted to clone the collection.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
不幸的是,Collection 接口没有提及任何关于实现 Clonable 接口的信息。
但你总是可以做的是复制集合:
如果你只想确保它没有被修改,那么用不可修改的集合包装它,而不是克隆它:
Unfortunaly the interface Collection does not say anything about implementing Clonable Interface.
But what you can always do is copy the collection:
If you only want to make sure that it is not modified then wrap it with an unmodidfiable collection instead of cloning it:
我将在 Scala 中进行演示,因为它有一个可以测试的 REPL,但相同的语义也应该在 Java 中工作。
Scala REPL 告诉我 theClone 具有静态类型
Object
(您可以将其转换为Collection[Int]
或LinkedList[Int]
),但是克隆的动态类型仍然是LinkedList
。现在我想你想要的是一个方法,当它收到静态类型
LinkedList
时返回静态类型LinkedList
并在收到静态类型LinkedList
时返回静态类型ArrayList
它接收静态类型 ArrayList 等,在这种情况下,在 Java 中,我认为这是
I'm going to demonstrate in Scala, becuase it has a REPL where I can test, but the same semantics should work in Java.
The Scala REPL tells me that theClone has static type
Object
(you can cast this toCollection[Int]
orLinkedList[Int]
), but the dynamic type of the clone is stillLinkedList
.Now I suppose what you want is a method that returns a static type
LinkedList
when it recieves a static typeLinkedList
and returns a static typeArrayList
when it recieves a static typeArrayList
, etc. in which caseIn Java, I think that's
如果你真的真的真的需要这样做,有一个丑陋的黑客。
If you really, really, really, really need to do this, there is an ugly hack.
我看到三个选项:
依赖集合自己的< em>编辑:正如评论和其他答案中所指出的,clone
方法(假设它实现Cloneable
),然后删除不需要的元素。clone()
不是公开的,因此不可访问。要求调用者提供一个空集合以在源和目标之间复制目标元素。
定义一个工厂接口来创建一个空集合并要求调用者提供一个工厂实现。然后在源和目标之间复制目标元素。
I see three options:
Rely on the collection's ownEdit: As pointed out in the comments and other answers,clone
method (assuming it implementsCloneable
) and then remove the undesired elements.clone()
is not public and therefore is not accessible.Ask the caller to provide an empty collection to copy the target elements between source and destination.
Define a factory interface to create an empty collection and ask the caller to provide a factory implementation. Then copy the target elements between source and destination.
通过在方法中修改集合来更好地过滤集合。由呼叫者向您提供原始集合或其正确副本。
Better filter the collection by modifying it in your method. Up to the caller to provide you with the original collection or a proper copy of it.
理论上,可以通过反射来实现,但是并非所有
Collection
实现都可以(或应该)以这种方式实例化。一个典型的例子是Collections.singletonList()
的结果,它根本没有公共构造函数。其他特殊收藏也会引发其他问题。我要做的只是检查输入集合实现的接口并返回该类型的“默认”实现。例如:
Ans等等。
In theory it is possible with reflection, however not all
Collection
implementations can (or should) be instantiated this way. A prime example is a result ofCollections.singletonList()
, which has no public constructors at all. Other special collections can raise other issues too.What I would do instead is to just check the interfaces the input collection implements and return a "default" implementation for that type. So for example:
Ans so on.
如果集合实现了
Cloneable
,你就可以做到。您不必担心确切的类型;集合的clone()
实现会处理这个问题。If the collection implements
Cloneable
, you can do it. You wouldn't have to worry about the exact type; the collection'sclone()
implementation would take care of that.