• kotlin


    问 题
     

    在Java 8中,有 Stream.collect 允许集合上的聚合。在Kotlin中,这不以同样的方式存在,除了可能作为stdlib中的扩展函数的集合。但是不清楚不同用例的等效性。



    例如,在 Collectors 的JavaDoc顶部是为Java 8编写的示例,当将它们移植到Kolin时,不能使用Java 8类在不同的JDK版本上,所以可能应该写成不同的。



    在资源在线显示Kotlin集合的例子,他们通常是微不足道的,并不真正比较相同的用例。什么是很好的例子,真正匹配的案例,如记录为Java 8 Stream.collect ?列表中有:




      • 将名称累积到列表中
      • 将名称累积到TreeSet
      • 将元素转换为字符串并用逗号分隔
      • 计算员工的工资总额



      • 按部门计算工资总额
      • 将学生分成通过和失败




    有关上述链接的JavaDoc的详细信息。



    注意: >这个问题是由作者故意写和回答的(自我回答的问题),以便常用的Kotlin主题的惯用答案出现在SO中。还要澄清一些为Kotlin的alphas写的,对当前Kotlin不准确的老的答案。

    解决方案

    这些示例和更多内容现在在堆栈中维护溢出文档



    Kotlin stdlib中有用于平均,计数,不同,过滤,查找,分组,连接,映射,最小, ,切片,排序,求和,到/从数组,到/从列表,到/从映射,联合,协同,所有的功能范例等等。所以你可以使用它们来创建一个简单的1-liners,并且没有必要使用更复杂的Java 8语法。



    我认为唯一缺少的来自内置的Java 8 Collectors 类是摘要(但在另一个答案这个问题是一个简单的解决方案)。



    两者之间缺少的一件事是按计数进行批量处理,这在另一个Stack Overflow answer ,并有一个简单的答案。另一个有趣的情况是这也是从Stack Overflow:惯用语使用Kotlin将溢出序列分成三个列表。如果您想要创建 Stream.collect 以实现其他目的,请参阅自定义流。收集在Kotlin



    总是好的探索用于kotlin.collections的API参考作为一个整体,然后创建可能已经存在的新函数。



    这里是一些从Java 8 Stream.collect 到Kotlin中的等价类型的转换:



    将名称累加到列表中



      // Java:
    List< String> list = people.stream()。map(Person :: getName).collect(Collectors.toList());



      // Kotlin:
    val list = people .map {it.name} // toList()不需要



    并连接起来,并以逗号分隔



      // Java:
    String join = things.stream()
    .map(Object :: toString)
    .collect(Collectors.joining(“,”));



      // Kotlin:
    val joined = things .joinToString(“,”)



    计算员工工资总额 / p> 

      // Java:
    int total = employees.stream()
    .collect(Collectors.summingInt(Employee :: getSalary)));



      // Kotlin:
    val total = .sumBy {it.salary}



    按部门分组员工



      // Java:
    Map< Department,List< Employee> byDept
    = employees.stream()
    .collect(Collectors.groupingBy(Employee :: getDepartment));



      // Kotlin:
    val byDept = employees .groupBy {it.department}



    按部门计算工资总和 / p> 

      // Java:
    Map< Department,Integer> totalByDept
    = employees.stream()
    .collect(Collectors.groupingBy(Employee :: getDepartment,
    Collectors.summingInt(Employee :: getSalary)));



      // Kotlin:
    val totalByDept = employees .groupBy {it.dept} .mapValues {it.value.sumBy {it.salary}}



    将学生分成传递和失败



      // Java:
    Map< Boolean,List< Student>> passedFailing =
    students.stream()
    .collect(Collectors.partitioningBy(s - > s.getGrade()> = PASS_THRESHOLD));



      // Kotlin:
    val passingFailing = students .partition {it.grade> = PASS_THRESHOLD}



    男性成员姓名



      // Java:
    List< String> namesOfMaleMembersCollect = roster
    .stream()
    .filter(p - > p.getGender()== Person.Sex.MALE)
    .map(p - > p.getName ))
    .collect(Collectors.toList());



      // Kotlin:
    val namesOfMaleMembers = roster .filter {it.gender == Person.Sex.MALE} .map {it.name}



    按性别列在成员名单中的成员名称



      
    Map< Person.Sex,List< String>> namesByGender =
    roster.stream()。collect(
    Collectors.groupingBy(
    Person :: getGender,
    Collectors.mapping(
    Person :: getName,
    Collectors.toList())));



      // Kotlin:
    val namesByGender = roster .groupBy {it.gender} .mapValues {it.value.map {it.name}}



    将列表过滤到另一个列表



      // Java:
    List< String> filtered = items.stream()
    .filter(item - > item.startsWith(“o”))
    .collect(Collectors.toList



      // Kotlin:
    val filtered = items .filter {item.startsWith('o')}



    / strong>



      // Java:
    String shortest = items.stream
    .min(Comparator.comparing(item - > item.length()))
    .get();



      // Kotlin:
    val short = items .minBy {it.length}



    在应用过滤器后对列表中的项目进行计数



      // Java:
    long count = items.stream filter(item - > item.startsWith(“t”))。count();



      // Kotlin:
    val count = items .filter {it.startsWith('t')} .size
    //但最好不要过滤,但是使用谓词
    val count = items.count {it.startsWith('t') }



    并在它上...在所有情况下,没有特殊的折叠,缩小或其他功能需要模仿 Stream.collect 。如果您有其他用例,请在评论中添加它们,我们可以看到!



    关于懒惰



    想要延迟处理链,可以在链之前使用 asSequence()转换为序列。在函数链的末尾,通常最后还有一个 Sequence 。然后可以使用 toList(), toSet(), toMap c $ c>或一些其他函数来实现 Sequence 结束。



      //切换到和从lazy 
    val someList = items.asSequence()。filter {...} .take(10).map {...} .toList()

    //切换到lazy,但sorted()在最后再次出现
    val someList = items.asSequence()。filter {...} .take(10).map {... } .sorted()



    为什么没有Types?!?



    你会注意到Kotlin的例子没有指定类型。这是因为Kotlin具有完整的类型推断,并且在编译时是完全类型安全的。比Java更多,因为它也有可空类型,可以帮助防止可怕的NPE。所以这在Kotlin:



      val someList = people.filter {it.age< = 30} .map {it.name } 



    与以下相同:



      val someList:List< String> = people.filter {it.age< = 30} .map {it.name} 



    Kotlin知道人是什么, people.age 是 Int 因此过滤器表达式只允许与 Int 进行比较, people.name 是 String ,因此 map 步骤产生一个 List< String> (readonly <$现在,如果<$ c>

    $ c>人可能 null ,因为在列表<人>?那么:



      val someList = people?.filter {it.age< = 30}?map {it.name} 



    返回 List< String>?将需要为null选中(或使用其他Kotlin运算符作为可空值,请参阅此 Kotlin处理可空值的常用方法以及在Kotlin中处理可空或空列表的惯用方法 

  • 相关阅读:
    2020.08.28【周报】
    区间合并【排序、栈】
    1042 数字0-9的数量【解题数分DP】
    asp.net数据分页方法
    纯css面板插件,自适应,多样式
    c#winform图表控件使用示例
    使用妹子UI开发的体验分享
    阿里云储存代码整理(由三卷天书整理)
    测试程序的时候用到写参数或者错误日志的几个方法,用来方便发现错误
    fineUI表格控件各属性说明
  • 原文地址:https://www.cnblogs.com/vana/p/10201245.html
Copyright © 2020-2023  润新知