Iterable을 사용하여 Java에서 Set Implementation (HashSet)을 초기화하려고합니다. 그러나 HashSet의 생성자는 반복 가능을 허용하지 않고 컬렉션 유형 객체 만 허용합니다.Iterable을 사용하여 세트 초기화
Iterable에서 Collections의 하위 유형으로 변환하는 방법이 있습니까?
Iterable을 사용하여 Java에서 Set Implementation (HashSet)을 초기화하려고합니다. 그러나 HashSet의 생성자는 반복 가능을 허용하지 않고 컬렉션 유형 객체 만 허용합니다.Iterable을 사용하여 세트 초기화
Iterable에서 Collections의 하위 유형으로 변환하는 방법이 있습니까?
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(); }
}
그냥 하나씩 추가하십시오. 즉 존재하지 않기 때문에 당신이하지 생성자 new HashSet<Integer>(someIterator)
를 사용 할
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);
참고. 정적 메서드를 호출하기 만하면됩니다.
'Iterable'과'Iterator'를 혼동스럽게 생각합니다. –
네, 맞습니다. 그러나 iterator()는 작동하지 않습니다. 내가 가지고있는 객체는 Iterator()를 돌려 주지만, 심지어 생성자에게는 받아 들여지지 않습니다. – VaidAbhishek
Kirk : 네 말이 맞아. 감사. @Vaid는 내 편집을 참조하십시오. – wchargin
물론, this 답변에 표시됩니다. 기본적으로, 반복 가능한 반복하고 컬렉션의 내용을 복사 다음과 같이
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;
}
그것을 사용하여, 그 결과 List
객체는 HashSet
생성자에 매개 변수로 전달 될 수있다.
Iterable<Integer> list = Arrays.asList(1, 2, 3);
List<Integer> copy = copyIterable(list);
Set<Integer> aSet = new HashSet<Integer>(copy);
내가 모두 함께 착각했습니다
편집 할 수 있습니다. Iterable
은 의 수퍼 인터페이스이므로 Iterable
이 Collection
으로 시작하는 한 단순하지만 위험한 캐스트가 트릭을 수행합니다.
Iterable<Integer> list = Arrays.asList(1, 2, 3);
Set<Integer> aSet = new HashSet<Integer>((Collection)list); // it works!
Downovoter : 관심있는 댓글? –
Iterable을 반복적으로 반복하거나 Iterator를 직접 사용하는 것을 피했습니다.HashSet 또는 Set 구현의 생성자가 받아 들일 수 있도록 메커니즘을 찾고 있습니다. (나는 투표하지 않았다.) 그러나 나에게 해결 방법을 보여줄 수 있다면 나는 분명히 당신을 업 그레 이드 할 것이다. :-) – VaidAbhishek
반복자가 아니라 반복자를 받아들입니다. – wchargin
Guava을 사용할 수 있습니다.
Set<T> set = Sets.newHashSet(iterable);
하거나 문장 정적 수입처럼 읽을 수 있도록,
import static com.google.common.collect.Sets.*;
Set<T> set = newHashSet(iterable);
Iterable 인터페이스는 "foreach는"구문이 작업을 수행 할 수 있습니다, 그래서 가장 깨끗한 방법은 가능성이 높습니다 :
public <T> Set<T> toSet(Iterable<T> collection) {
HashSet<T> set = new HashSet<T>();
for (T item: collection)
set.add(item);
return set;
}
좋은 설명. 나는 네가 요점과 직감을 얻은 것 같아. – VaidAbhishek