[java] List에서 요소의 발생 횟수를 계산하는 방법

나는이 ArrayList다음과 같이 자바의 컬렉션 클래스를 :

ArrayList<String> animals = new ArrayList<String>();
animals.add("bat");
animals.add("owl");
animals.add("bat");
animals.add("bat");

보다시피, animals ArrayList3 개의 bat요소와 하나의 owl요소로 구성됩니다. Collection 프레임 워크에 bat발생 횟수를 반환하는 API가 있는지 또는 발생 횟수를 결정하는 다른 방법 이 있는지 궁금합니다 .

Google의 Collection Multiset에는 요소의 총 발생 횟수를 반환하는 API가 있습니다. 그러나 이는 JDK 1.5 와만 호환됩니다. 당사 제품은 현재 JDK 1.6에 있으므로 사용할 수 없습니다.



답변

Collections의 정적 주파수 방법이 여기에 유용 할 것이라고 확신합니다.

int occurrences = Collections.frequency(animals, "bat");

어쨌든 내가 그렇게하는 방법입니다. 나는 이것이 jdk 1.6이라고 확신합니다.


답변

자바 8 :

Map<String, Long> counts =
    list.stream().collect(Collectors.groupingBy(e -> e, Collectors.counting()));


답변

이는 효과적인 Java 서적에 설명 된대로 ” 인터페이스로 오브젝트 참조 “가 중요한 이유를 보여줍니다 .

구현에 코드를 작성하고 ArrayList를 사용하여 코드의 50 개 장소를 가정 해 봅시다. 항목을 세는 훌륭한 “List”구현을 발견하면 해당 50 개 장소를 모두 변경해야 할 것입니다. 코드를 깰 수 있습니다 (만 사용하면 큰 문제는 없지만 다른 사람이 사용하면 코드도 손상됩니다)

인터페이스에 프로그래밍하면 50 개 위치를 변경하지 않고 ArrayList에서 “CountItemsList”(예 🙂 또는 다른 클래스로 구현을 대체 할 수 있습니다.

아래는 이것이 어떻게 작성 될 수 있는지에 대한 매우 기본적인 샘플입니다. 이것은 샘플 일뿐입니다. 프로덕션 준비 목록은 훨씬 더 복잡합니다.

import java.util.*;

public class CountItemsList<E> extends ArrayList<E> {

    // This is private. It is not visible from outside.
    private Map<E,Integer> count = new HashMap<E,Integer>();

    // There are several entry points to this class
    // this is just to show one of them.
    public boolean add( E element  ) {
        if( !count.containsKey( element ) ){
            count.put( element, 1 );
        } else {
            count.put( element, count.get( element ) + 1 );
        }
        return super.add( element );
    }

    // This method belongs to CountItemList interface ( or class ) 
    // to used you have to cast.
    public int getCount( E element ) {
        if( ! count.containsKey( element ) ) {
            return 0;
        }
        return count.get( element );
    }

    public static void main( String [] args ) {
        List<String> animals = new CountItemsList<String>();
        animals.add("bat");
        animals.add("owl");
        animals.add("bat");
        animals.add("bat");

        System.out.println( (( CountItemsList<String> )animals).getCount( "bat" ));
    }
}

여기에 적용되는 OO 원칙 : 상속, 다형성, 추상화, 캡슐화.


답변

그것을 할 수있는 간단한 메소드 호출이 없습니다. 그래도지도를 만들고 빈도를 세면됩니다.

HashMap<String,int> frequencymap = new HashMap<String,int>();
foreach(String a in animals) {
  if(frequencymap.containsKey(a)) {
    frequencymap.put(a, frequencymap.get(a)+1);
  }
  else{ frequencymap.put(a, 1); }
}


답변

Java에는이를위한 기본 메소드가 없습니다. 그러나 Apache Commons-Collections의 IterableUtils # countMatches () 를 사용 하여 대신 할 수 있습니다.


답변

실제로 Collections 클래스에는 다음과 같은 정적 메소드가 있습니다 : frequency (Collection c, Object o) 검색하려는 요소의 발생 횟수를 반환합니다. 그런데 이것은 완벽하게 작동합니다.

ArrayList<String> animals = new ArrayList<String>();
animals.add("bat");
animals.add("owl");
animals.add("bat");
animals.add("bat");
System.out.println("Freq of bat: "+Collections.frequency(animals, "bat"));


답변

스트림 을 사용하는 대체 Java 8 솔루션 :

long count = animals.stream().filter(animal -> "bat".equals(animal)).count();