2016-07-28 37 views
1

我有对象名单listOfStudents列表: 对象:查找字符串的最大次数 - 领带情况下

private class Students 
{ 
    private String name; 
    private int numberOfTimesComeToSchool; 
} 

我试图查找出现最多次的学生的姓名和这样做,我用:

listOfStudents.stream().map(Student::getName)collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); 

如果不系领带,然后我用

Collections.max(collect.entrySet(), Map.Entry.comparingByValue()).getKey(); 

确定发生次数最多的名称。

但是可能会发生这样的情况,即学生的名字中有一个关系,在这种情况下,我想选择最多次来到学校的学生姓名,即具有学生姓名numberOfTimesComeToSchool中所有名称的最高总和。

例如:

Student 1: Name: Hello numberOfTimesComeToSchool: 1 
Student 2: Name: Hello numberOfTimesComeToSchool: 4 
Student 3: Name: Trial numberOfTimesComeToSchool: 2 
Student 4: Name: Trial numberOfTimesComeToSchool: 2 
Student 5: Name: NeedThis numberOfTimesComeToSchool: 2 
Student 6: Name: NeedThis numberOfTimesComeToSchool: 2 

在这种情况下,正确的答案应该是你好作为numberOfTimesComeToSchool的总和是名字的只有4个,其余5时,即使所有的名字都发生在同一数量的时代。

任何与此有关的帮助将被处理。

+0

我将如何能够使用呢?我从来不知道学生的名字。 – Massa

+0

调用'HashBag.uniqueSet()'并迭代它。文档:https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/bag/HashBag.html – ifly6

回答

3

使用.map(Student::getName)的问题是,你放弃了每个学生上学次数的信息。

取而代之,只需在原始列表上使用groupingBy即可获得Map<String, List<Student>>。然后遍历地图的条目集,然后通过比较列表的大小和匹配情况下的总和numberOfTimesComeToSchool来查找最大条目。

Map<String, List<Student>> map = 
     listOfStudents.stream().collect(Collectors.groupingBy(Student::getName)); 

Optional<String> studentName = 
     map.entrySet() 
      .stream() 
      .max(Comparator.<Map.Entry<String, List<Student>>>comparingInt(e -> e.getValue().size()) 
          .thenComparingInt(e -> e.getValue().stream().mapToInt(Student::getNumberOfTimesComeToSchool).sum())) 
      .map(Map.Entry::getKey); 

类型推断还不够强大,所以你必须在比较器中指定类型参数,这使得它很难阅读。

最后,你可以通过使用Collectors.collectingAndThen让一个班轮:

Optional<String> studentName = 
    listOfStudents.stream() 
        .collect(collectingAndThen(groupingBy(Student::getName), 
                 m -> m.entrySet() 
                   .stream() 
                   .max(Comparator.<Map.Entry<String, List<Student>>>comparingInt(e -> e.getValue().size()) 
                      .thenComparingInt(e -> e.getValue().stream().mapToInt(Student::getNumberOfTimesComeToSchool).sum())) 
                   .map(Map.Entry::getKey))); 
相关问题