2009-12-07 2 views
3

목록이 있습니다. 목록에는 동일한 enum 유형의 여러 항목이 포함될 수 있습니다. BALL, DOLL, PLAYSTATION : 값이 TOY :Java - 목록의 유형 검색

내가 열거가 있다고 가정하자. PLAYSTATION 개의 상품이 TOY 유형의 목록에 몇 개 있는지 알고 싶습니다. (즉, List<Toy> 장난감)

가장 좋은 해결책은 무엇입니까? 매번 반복 목록을 반복하고 싶지 않습니다.

답변

8

Apache commons-collections 'HashBag을 사용할 수 있습니다. 그것은 당신에게 적합한 getCount(Object) 방법이 있습니다.

+3

일 - HashBag이지도에 카운트를 유지, 그래서 빠른 조회의 getCount를 호출 할 때마다 목록을 반복하는 것보다 훨씬 낫습니다. –

+0

이것은 내가 필요한 대답처럼 들립니다. 빠른 검색, 그리고 매 반복마다 (내가 전에 게시 한 자바 콜렉션 답처럼)가 아니다. –

1

내부적으로 추가/제거 된 각 열거 유형에 대한 개수 목록을 저장하는 사용중인 목록 유형의 데코레이터를 작성하지 않는 이유는 무엇입니까? 그렇게하면 일반 목록으로 사용할 수 있지만 현재 포함되어있는 유형의 수를 쿼리하는 몇 가지 추가 기능을 추가 할 수 있습니다.

당신이해야 할 일은 add/remove/addAll 등의 메소드를 오버라이드하고 카운터를 증가시켜 실제 목록 유형으로 전달하는 것입니다. 가장 좋은 점은 새 래퍼로 모든 목록 유형을 꾸밀 수 있다는 것입니다.

0

java.util.List 메소드를 확장하고 모든 뮤 테이타 메소드, 즉 요소 추가 또는 삭제에 사용되는 메소드와 목록 지우기에 사용되는 메소드를 오버라이드하십시오. 1 종류의 항목 수를 보관 유지하는 비공개 java.util.Map 에의 참조를 추가합니다. 유형 당 현재 요소 수를 반환하는 접근 자 메서드를 추가합니다. 최소한

1

, 같은 유틸리티 방법 :

public int count(List<Toy> haystack, Toy needle) { 
    int result; 
    for (Toy t : haystack) { 
     if (t == needle) { 
      result++; 
     } 
    } 
    return result; 
} 

당신이 간결하게 다른 곳에서 코드에서 플레이 스테이션의 번호를 참조 할 수겠습니까. 또는 목록이 변경 될 가능성이 거의 없다는 것을 알고 있다면 Map<Toy, Integer>을 작성하면 모든 항목의 수를 한 번 늘릴 수 있습니다.

+0

그래, 그게 짐승 - 강제 방법이지만, 그 때마다 장난감의 종류()를 알고 싶었을 때마다 봐야 할 것입니다. –

2

java.util.Collections에는 frequency(Collection c, Object type)이라는 메서드가 있습니다. 내 질문에

사용법 :

int amountOfPlayStations = Collections.frequency(toys, TOY.PLAYSTATION); 
+1

Meh. 이 구현은 기본적으로 for 루프를 매번 수행하는 것처럼 보입니다. 그래서 이것은 CPU 친화적 인 것이 아닙니다. –

+0

이 방법은 컬렉션의 각 요소를 반복하고 발생 횟수를 계산합니다. – Bozho

0

(Bozho 별) HashBag 가장 좋은 것 같다. 모든 솔루션 게다가

List<Toy> toys; 
List<Toy> playstations = Collections2.filter(toys, new Predicate() { 
    boolean apply(TOY toy){ 
    return toy == TOY.PLAYSTATION; 
    } 
}); 
0

(필자는 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)

1

당신이 전체 컬렉션을 통해 각 시간을 반복하고 싶지 않을 경우, 다른 대안이 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; 
        } 
    
    } 
    
+0

실제로 매우 좋은 해결책입니다. 감사! –