使用Iterable初始化Set

Vai*_*hek 19 java set

我想用Iterable初始化Java中的Set Implementation(HashSet).但是,HashSet的构造函数不接受Iterables,而只接受Collections类型的对象.

有没有办法从Iterable转换为某些子集类型.

Con*_*vey 46

你可以使用番石榴.

Set<T> set = Sets.newHashSet(iterable);
Run Code Online (Sandbox Code Playgroud)

或者使它像一个句子静态导入一样读,

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

Set<T> set = newHashSet(iterable);
Run Code Online (Sandbox Code Playgroud)


Ósc*_*pez 7

当然,它在这个答案中显示出来.基本上,遍历iterable并将其内容复制到集合中:

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;
}
Run Code Online (Sandbox Code Playgroud)

使用如下,生成的List对象可以作为参数传递给HashSet构造函数.

Iterable<Integer> list = Arrays.asList(1, 2, 3);
List<Integer> copy = copyIterable(list);
Set<Integer> aSet = new HashSet<Integer>(copy);
Run Code Online (Sandbox Code Playgroud)

编辑

我一直都弄错了.Iterable是一个超级接口Collection,所以一个简单的(但不安全的)演员会做的伎俩,只要Iterable是一个Collection开始.

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

  • `Collection` 是一个 `Iterable`,但一个 `Iterable` 不一定是一个 `Collection`。因此,如果具体的`Iterable` 不是`Collection`,你的演员表是不安全的(如你所说)并且可能在运行时失败。 (3认同)
  • 将 Iterable 转换为 Collection 是个坏主意 (2认同)

Mar*_*nik 6

HashSet构造函数依赖的不仅仅是Iterable提供:它想要预先了解size集合,以便最佳地构建底层HashMap.如果你有一个真实的,严肃的Iterable,不知道它的大小,那么你必须Iterable通过Collection在任何一些明显的方式中将它变成常规来实现前期.

另一方面,如果你有一个已经知道它的大小的更丰富的对象,那么创建一个将你包装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(); }
}
Run Code Online (Sandbox Code Playgroud)