목록이 있습니다. 목록에는 동일한 enum 유형의 여러 항목이 포함될 수 있습니다. BALL
, DOLL
, PLAYSTATION
: 값이 TOY
:Java - 목록의 유형 검색
내가 열거가 있다고 가정하자. PLAYSTATION
개의 상품이 TOY
유형의 목록에 몇 개 있는지 알고 싶습니다. (즉, List<Toy>
장난감)
가장 좋은 해결책은 무엇입니까? 매번 반복 목록을 반복하고 싶지 않습니다.
목록이 있습니다. 목록에는 동일한 enum 유형의 여러 항목이 포함될 수 있습니다. BALL
, DOLL
, PLAYSTATION
: 값이 TOY
:Java - 목록의 유형 검색
내가 열거가 있다고 가정하자. PLAYSTATION
개의 상품이 TOY
유형의 목록에 몇 개 있는지 알고 싶습니다. (즉, List<Toy>
장난감)
가장 좋은 해결책은 무엇입니까? 매번 반복 목록을 반복하고 싶지 않습니다.
Apache commons-collections 'HashBag
을 사용할 수 있습니다. 그것은 당신에게 적합한 getCount(Object)
방법이 있습니다.
내부적으로 추가/제거 된 각 열거 유형에 대한 개수 목록을 저장하는 사용중인 목록 유형의 데코레이터를 작성하지 않는 이유는 무엇입니까? 그렇게하면 일반 목록으로 사용할 수 있지만 현재 포함되어있는 유형의 수를 쿼리하는 몇 가지 추가 기능을 추가 할 수 있습니다.
당신이해야 할 일은 add/remove/addAll 등의 메소드를 오버라이드하고 카운터를 증가시켜 실제 목록 유형으로 전달하는 것입니다. 가장 좋은 점은 새 래퍼로 모든 목록 유형을 꾸밀 수 있다는 것입니다.
java.util.List 메소드를 확장하고 모든 뮤 테이타 메소드, 즉 요소 추가 또는 삭제에 사용되는 메소드와 목록 지우기에 사용되는 메소드를 오버라이드하십시오. 1 종류의 항목 수를 보관 유지하는 비공개 java.util.Map 에의 참조를 추가합니다. 유형 당 현재 요소 수를 반환하는 접근 자 메서드를 추가합니다. 최소한
, 같은 유틸리티 방법 :
public int count(List<Toy> haystack, Toy needle) {
int result;
for (Toy t : haystack) {
if (t == needle) {
result++;
}
}
return result;
}
당신이 간결하게 다른 곳에서 코드에서 플레이 스테이션의 번호를 참조 할 수겠습니까. 또는 목록이 변경 될 가능성이 거의 없다는 것을 알고 있다면 Map<Toy, Integer>
을 작성하면 모든 항목의 수를 한 번 늘릴 수 있습니다.
그래, 그게 짐승 - 강제 방법이지만, 그 때마다 장난감의 종류()를 알고 싶었을 때마다 봐야 할 것입니다. –
java.util.Collections
에는 frequency(Collection c, Object type)
이라는 메서드가 있습니다. 내 질문에
사용법 :
int amountOfPlayStations = Collections.frequency(toys, TOY.PLAYSTATION);
Meh. 이 구현은 기본적으로 for 루프를 매번 수행하는 것처럼 보입니다. 그래서 이것은 CPU 친화적 인 것이 아닙니다. –
이 방법은 컬렉션의 각 요소를 반복하고 발생 횟수를 계산합니다. – Bozho
(Bozho 별) HashBag 가장 좋은 것 같다. 모든 솔루션 게다가
List<Toy> toys;
List<Toy> playstations = Collections2.filter(toys, new Predicate() {
boolean apply(TOY toy){
return toy == TOY.PLAYSTATION;
}
});
(필자는 Collections.Frequency 호출에 대한 약점을 가지고), 난 google collections에서 살펴 봐야 당신을 추천합니다, 특히 것이다 : 그러나 좀 더 일반적인 것은 적절한 술어 Googles Collections 2이 될 것입니다 [Collections2.transform] [2]로 이동하여 항목에 대한 라이브 뷰를 제공 할 수 있습니다.
[2] : http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Collections2.html#transform(java.util.Collection, com.google.common.base.Function)
당신이 전체 컬렉션을 통해 각 시간을 반복하고 싶지 않을 경우, 다른 대안이 ForwardingList 구현을 작성하는 것입니다 .HashBag 제안을 통해이의 주요 장점은 다음과 같습니다 당신이
는이리스트를 요구하는 어떠한 방법으로 전달할 수 있도록
다음은 수행 방법에 대한 간단한 예입니다. 당신은이 작업을 수행 할 경우 목록에서 삭제/추가 모든 메소드를 오버라이드 (override) 할 필요가 있습니다 그렇지 않으면 당신은 일관성없는 상태로 끝날 수
import com.google.common.collect.ForwardingList;
public class CountingList<E> extends ForwardingList<E> {
private List<E> backingList = new LinkedList<E>();
private Map<E, Integer> countMap = new HashMap<E, Integer>();
@Override
protected List<E> delegate() {
return backingList;
}
@Override
public boolean add(E element) {
backingList.add(element);
if(countMap.containsKey(element)) {
countMap.put(element, countMap.get(element) + 1);
} else {
countMap.put(element, 1);
}
return true;
}
public int getCount(E element) {
Integer count = countMap.get(element);
return count != null ? count.intValue() : 0;
}
}
실제로 매우 좋은 해결책입니다. 감사! –
일 - HashBag이지도에 카운트를 유지, 그래서 빠른 조회의 getCount를 호출 할 때마다 목록을 반복하는 것보다 훨씬 낫습니다. –
이것은 내가 필요한 대답처럼 들립니다. 빠른 검색, 그리고 매 반복마다 (내가 전에 게시 한 자바 콜렉션 답처럼)가 아니다. –