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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 06:58:45  来源:igfitidea点击:

Initializing a Set with an Iterable

javaset

提问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

HashSetconstructor relies on more than what Iterableoffers: it wants to know the sizeof 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 Iterableup front by turning it into a regular Collectionin 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 Iterableinto a collection, implementing just sizein 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 Listobject can be passed as a parameter to the HashSetconstructor.

如下使用它,生成的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. Iterableis a superinterface of Collection, so a simple (but unsafe) cast will do the trick, as long as the Iterablewas a Collectionto begin with.

我一直都误会了。Iterable是 的超级接口Collection,所以只要Iterable是一个Collection开始,一个简单(但不安全)的转换就可以解决问题。

Iterable<Integer> list = Arrays.asList(1, 2, 3);
Set<Integer> aSet = new HashSet<Integer>((Collection)list); // it works!

回答by ConnorWGarvey

You can use Guava.

您可以使用番石榴

Set<T> set = Sets.newHashSet(iterable);

or to make it read like a sentence static import,

或者让它读起来像一个句子静态导入,

import static com.google.common.collect.Sets.*;

Set<T> set = newHashSet(iterable);

回答by Don Roby

The Iterableinterface allows the "foreach" syntax to work, so the cleanest way is likely:

可迭代接口允许“的foreach”语法来工作,所以最彻底的方法可能是:

public <T> Set<T> toSet(Iterable<T> collection) {
    HashSet<T> set = new HashSet<T>();
    for (T item: collection)
        set.add(item);
    return set;
}