Java 使用可迭代对象初始化集合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16449847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Initializing a Set with an Iterable
提问by VaidAbhishek
I want to initialize a Set Implementation (HashSet) in Java with an Iterable. However, the constructor of HashSet doesn't accept Iterables, but only Collections type objects.
我想在 Java 中使用 Iterable 初始化一个 Set 实现(HashSet)。但是,HashSet 的构造函数不接受 Iterables,而只接受 Collections 类型的对象。
Is there a way to convert from Iterable to some subtype of Collections.
有没有办法从 Iterable 转换为 Collections 的某些子类型。
采纳答案by Marko Topolnik
HashSet
constructor relies on more than what Iterable
offers: it wants to know the size
of the collection up front in order to optimally construct the underlying HashMap
. If you have a true, austere Iterable
, which doesn't know its size, then you'll have to realize the Iterable
up front by turning it into a regular Collection
in any of a number of obvious ways.
HashSet
构造函数依赖的不仅仅是所Iterable
提供的:它想预先知道size
集合的 ,以便以最佳方式构造底层的HashMap
. 如果您有一个真正的、简朴的Iterable
,它不知道它的大小,那么您必须Iterable
通过Collection
以多种明显方式中的任何一种将其转换为常规来预先实现。
If, on the other hand, you have a richer object that already knows its size, then it would pay to create a minimalist adapter class that wraps your Iterable
into a collection, implementing just size
in addition to forwarding the call to iterator
.
另一方面,如果您有一个更丰富的对象并且已经知道它的大小,那么创建一个极简的适配器类将您的对象包装Iterable
到一个集合中,size
除了将调用转发到iterator
.
public class IterableCollection<T> implements Collection<T>
{
private final Iterable<T> iterable;
public IterableCollection(Iterable<T> it) { this.iterable = it; }
@Override public Iterator<T> iterator() { return iterable.iterator(); }
@Override public int size() { return ... custom code to determine size ... }
@Override .... all others ... { throw new UnsupportedOperationException(); }
}
回答by wchargin
Just add each one.
只需添加一个。
public static <T> Set<T> setFromIterable(Iterable<T> i) {
HashSet<T> set = new HashSet<T>();
Iterator<T> it = i.iterator();
while (it.hasNext()) {
set.add(it.next());
}
return set;
}
Iterable<Integer> someIterable = ...;
Set<Integer> someSet = setFromIterable(someIterable);
Note that you don'tuse the constructor new HashSet<Integer>(someIterator)
, because that doesn't exist. Just call the static method.
请注意,您不使用构造函数new HashSet<Integer>(someIterator)
,因为它不存在。只需调用静态方法。
回答by óscar López
Sure, it's shown in thisanswer. Basically, iterate over the iterable and copy its contents in a collection:
当然,它显示在这个答案中。基本上,迭代可迭代对象并将其内容复制到集合中:
public static <T> List<T> copyIterable(Iterable<T> iterable) {
Iterator<T> iter = iterable.iterator();
List<T> copy = new ArrayList<T>();
while (iter.hasNext())
copy.add(iter.next());
return copy;
}
Use it as follows, the resulting List
object can be passed as a parameter to the HashSet
constructor.
如下使用它,生成的List
对象可以作为参数传递给HashSet
构造函数。
Iterable<Integer> list = Arrays.asList(1, 2, 3);
List<Integer> copy = copyIterable(list);
Set<Integer> aSet = new HashSet<Integer>(copy);
EDIT
编辑
I've been mistaken all along. Iterable
is a superinterface of Collection
, so a simple (but unsafe) cast will do the trick, as long as the Iterable
was a Collection
to begin with.
我一直都误会了。Iterable
是 的超级接口Collection
,所以只要Iterable
是一个Collection
开始,一个简单(但不安全)的转换就可以解决问题。
Iterable<Integer> list = Arrays.asList(1, 2, 3);
Set<Integer> aSet = new HashSet<Integer>((Collection)list); // it works!