如何使用JAVA8的lambda表达式将Map转换为SortedMap?

5
例如,我有一个类 Student
public class Student{
    private String name;
    private int age;

    public int getAge(){
        return this.age;
    }
}

还有一个名为School的类:

public class School{
    private Map<String,Student> students=new TreeMap<>();
    //stroe the index of students in the school by key is their names.

    public SortedMap<Integer,Long> countingByAge(){
        return this.students.entrySet().stream().map(s->s.getValue())
               .collect(groupingBy((Student s)->s.getAge(),counting()));
    }
}

countingByAge方法要求返回一个SortedMap,其中key是学生的年龄,value是每个不同年龄的学生人数,即我需要计算每个年龄有多少学生。
我已经快完成这个方法了,但我不知道如何将Map转换为SortedMap而不使用(SortedMap)强制转换。

在我看来,你可以直接进行强制类型转换。在这种情况下使用强制类型转换并没有什么问题。 - BufBills
2
@BufBills,仅仅进行强制类型转换是不可取的。Java编译器会因此生成警告,这是有充分理由的。未经检查的类型转换会削弱编译器在使用泛型对象时保证正确、安全代码的能力。 - VGR
4
在这种情况下,这不是一个未经检查的转换。这只是一个简单的强制类型转换,在运行时将失败,因为默认的grouping收集器返回的Map不是一个SortedMap - Holger
1个回答

10
你可以使用groupingBy(classifier, mapFactory, downstream),并将mapFactory作为返回实现了SortedMap的Map实例的Supplier,例如TreeMap::new
public SortedMap<Integer, Long> countingByAge(){
    return  students.entrySet()
            .stream()
            .map(Map.Entry::getValue)
            .collect(groupingBy(Student::getAge, TreeMap::new, counting()));
}

顺便提一下,正如@Holger评论中提到的那样,你可以简化

map.entrySet()
.stream()
.map(Map.Entry::getValue)
map.values()
.stream()

6
entrySet().stream().map(Map.Entry::getValue)是一个不必要复杂的写法,等价于更简单的values().stream() - Holger
@Holger 我不想在 OP 代码中改变太多东西,但是这确实是一个很好的简化。 - Pshemo
1
你可以将它作为一个替代方案添加进去,因为答案并不长,这样不会分散读者的注意力。 - Holger
@Holger 已完成。将来如果您认为我的答案可以改进/简化,请随意编辑。我相信您的判断,特别是关于Java-8问题。 - Pshemo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接