2016-09-16 2 views
6

나는 cityzip 필드를 가진 객체를 가지고 있는데, 이것을 Record으로 부르기로한다.자바 8 스트림에서 최대 빈도로 객체 가져 오기

public class Record() { 
    private String zip; 
    private String city; 

    //getters and setters 
} 

지금, 나는 다음과 같은 코드를 사용하여 zip하여 이러한 개체의 수집 및 I 그룹을 가지고

final Collection<Record> records; //populated collection of records 
final Map<String, List<Record>> recordsByZip = records.stream() 
    .collect(Collectors.groupingBy(Record::getZip)); 

그래서를, 지금은 키가 zip하고있는지도가 값은 zipRecord 개체 목록입니다.

각각 zip에 대해 가장 일반적인 내용은 city입니다.

recordsByZip.forEach((zip, records) -> { 
    final String mostCommonCity = //get most common city for these records 
}); 

모든 스트림 작업에서이 작업을 수행하고 싶습니다. 예를 들어,이 수행하여 각 city에 대한 주파수의지도를 얻을 수 있어요 :

recordsByZip.forEach((zip, entries) -> { 
    final Map<String, Long> frequencyMap = entries.stream() 
     .map(GisSectorFileRecord::getCity) 
     .filter(StringUtils::isNotBlank) 
     .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); 
}); 

을하지만 난 그냥 city 가장 빈번한를 반환하는 한 줄 스트림 작업을 할 수 있도록하고 싶습니다 .

거기에 어떤 마법을 쓸 수있는 Java 8 스트림 전문가가 있습니까?

놀고 싶다면 여기 ideone sandbox입니다. 자신의 우편에 의한

final Map<String, String> mostFrequentCities = 
    records.stream() 
     .collect(Collectors.groupingBy(
      Record::getZip, 
      Collectors.collectingAndThen(
       Collectors.groupingBy(Record::getCity, Collectors.counting()), 
       map -> map.entrySet().stream().max(Map.Entry.comparingByValue()).get().getKey() 
      ) 
     )); 

이 그룹 각각의 기록을, 그들의 도시로, 각각의 우편 번호에 대한 도시의 수를 계산 :

답변

6

는 다음을 가질 수있다. 그런 다음 지퍼별로 도시 수의지도를 최대 개수가있는 도시 만 유지하도록 사후 처리합니다.

+1

'collectingAndThen' 나는 뭔가를 놓친다는 것을 알았지 만, 대신 나는 항상'mapping'에 대해 생각합니다. +1 –

+0

'.get()'을 호출하기 전에'.max()'에 의해 반환 된'Optional'이 스트림 연산에 존재하는지 확인하는 방법이 있습니까? –

+1

@AndrewMairose 그렇습니다.하지만 .get()은 여기를 호출하는 것이 안전합니다.지도는 비어서는 안되며, 적어도 우편 번호별로 그룹화 된 도시를 포함해야합니다. – Tunaki

0

저는 Multiset이 이런 종류의 질문에 좋은 선택이라고 생각합니다. 다음 코드는 AbacusUtil

Stream.of(records).map(e -> e.getCity()).filter(N::notNullOrEmpty).toMultiset().maxOccurrences().get().getKey(); 

공개하는 것입니다 : 내가 AbacusUtil의 개발자입니다.