Java的Stream流编程的排序sorted方法里参数o1,o2分别代表什么?

news/2024/10/19 5:45:12

先说结论:在sorted方法中,o1是最后面的元素,o2是倒数第二个元素,以此类推,流是处理元素是从后面开始取值。 

  1.  
    package com.br.itwzhangzx02.learn;
  2.  
     
  3.  
     
  4.  
    import org.junit.Test;
  5.  
     
  6.  
    import java.util.ArrayList;
  7.  
    import java.util.List;
  8.  
     
  9.  
    import com.br.itwzhangzx02.learn.POJO.User;
  10.  
     
  11.  
    public class StreamTest {
  12.  
     
  13.  
    /**
  14.  
    * 1.id全部满足是偶数
  15.  
    * 2.年龄大于10
  16.  
    * 3.用户名大写
  17.  
    * 4.用户名字母倒排序
  18.  
    * 5.只输出一个用户名
  19.  
    *
  20.  
    *
  21.  
    * */
  22.  
    @Test
  23.  
    public void testStream(){
  24.  
    List<User> list = new ArrayList<User>(){
  25.  
    {
  26.  
    add(new User(1l,"q",10, "清华大学"));
  27.  
    add(new User(2l,"f",12, "清华大学"));
  28.  
    add(new User(3l,"b",15, "清华大学"));
  29.  
    add(new User(4l,"a",12, "清华大学"));
  30.  
    add(new User(5l,"d",25, "北京大学"));
  31.  
    add(new User(6l,"c",16, "北京大学"));
  32.  
    add(new User(7l,"t",14, "北京大学"));
  33.  
    add(new User(8l,"g",14, "浙江大学"));
  34.  
    add(new User(9l,"j",17, "浙江大学"));
  35.  
    add(new User(10l,"l",10, "浙江大学"));
  36.  
    }
  37.  
    };
  38.  
    list.stream()
  39.  
    .filter(user -> user.getId()%2==0)
  40.  
    .filter(user -> user.getAge()>10)
  41.  
    .map(user -> user.getName().toUpperCase())
  42.  
    .sorted((o1,o2)->{return 1;})
  43.  
    .forEach(System.out::println);
  44.  
     
  45.  
    //sorted 方法中,我们重写compare方法:如果return1,则是按照原先的排序排。-1则是按照逆序排
  46.  
    //
  47.  
    }
  48.  
    /** a negative integer, zero, or a positive integer as the
  49.  
    * first argument is less than, equal to, or greater than the
  50.  
    * second.**/
  51.  
     
  52.  
    }
  1.  
    package com.br.itwzhangzx02.learn.POJO;
  2.  
     
  3.  
    public class User {
  4.  
    public Long getId() {
  5.  
    return id;
  6.  
    }
  7.  
     
  8.  
    public void setId(Long id) {
  9.  
    this.id = id;
  10.  
    }
  11.  
     
  12.  
    public String getName() {
  13.  
    return name;
  14.  
    }
  15.  
     
  16.  
    public void setName(String name) {
  17.  
    this.name = name;
  18.  
    }
  19.  
     
  20.  
    public Integer getAge() {
  21.  
    return age;
  22.  
    }
  23.  
     
  24.  
    public void setAge(Integer age) {
  25.  
    this.age = age;
  26.  
    }
  27.  
     
  28.  
    public String getSchool() {
  29.  
    return school;
  30.  
    }
  31.  
     
  32.  
    public void setSchool(String school) {
  33.  
    this.school = school;
  34.  
    }
  35.  
     
  36.  
    private Long id; //主键id
  37.  
    private String name; //姓名
  38.  
    private Integer age; //年龄
  39.  
    private String school; //学校
  40.  
     
  41.  
    public User(Long id, String name, Integer age, String school) {
  42.  
    this.id = id;
  43.  
    this.name = name;
  44.  
    this.age = age;
  45.  
    this.school = school;
  46.  
    }
  47.  
    }

一开始的疑惑:

  1.  
    * @param o1 the first object to be compared.
  2.  
    * @param o2 the second object to be compared.
  3.  
    * @return a negative integer, zero, or a positive integer as the
  4.  
    * first argument is less than, equal to, or greater than the
  5.  
    * second.
  6.  
    * @throws NullPointerException if an argument is null and this
  7.  
    * comparator does not permit null arguments
  8.  
    * @throws ClassCastException if the arguments' types prevent them from
  9.  
    * being compared by this comparator.
  10.  
    */
  11.  
    int compare(T o1, T o2);

上面是我拿到的Comparator接口中关于,compare方法的注释:

按照规则:第一个参数>第二个参数时,返回的是一个正数,那么返回正数,代表什么?

结论:正数的话,就是保持俩个元素的位置不变,负数的话俩元素位置互换。

首先,我们验证返回正数时,元素位置不变:

 返回为负数时,元素位置互换。比如:F,A--->A,F

sorted()方法,使用的是默认的自然顺序--升序排序。但是,stream中元素,需要实现comparable接口,重写了方法compareTo方法。查看string的这个方法:

  1.  
    public int compareTo(String anotherString) {
  2.  
    int len1 = value.length;
  3.  
    int len2 = anotherString.value.length;
  4.  
    int lim = Math.min(len1, len2);
  5.  
    char v1[] = value;
  6.  
    char v2[] = anotherString.value;
  7.  
     
  8.  
    int k = 0;
  9.  
    while (k < lim) {
  10.  
    char c1 = v1[k];
  11.  
    char c2 = v2[k];
  12.  
    if (c1 != c2) {
  13.  
    return c1 - c2;
  14.  
    }
  15.  
    k++;
  16.  
    }
  17.  
    return len1 - len2;
  18.  
    }

 比较规则很简单,就是从字符数组的char[0]开始,比较二者的值,然后返回 c1-c2.

比如我们的F,A比较的时候,F>A,返回值为正数,根据我们前面的结论,返回一个正数时,顺序是保持不变的才对,那么这里到底是怎么回事?

为了看问题方便,我只保留了F和A的数据,测试如下:

 

按照我们的结论:返回正数时,顺序是不变的,为啥现在顺序变了,而且刚好是逆序。

最后,仔细想是不是,流处理元素的时候顺序的问题。比如:o1代表的是我们的A那个元素,o2代表的是F那个元素。

怎么验证呢?

人为抛异常,先处理的那个元素,最先抛异常

正常我们的数据,在list中是F元素在前,A元素在后。然后我们的代码先,o1转Integer抛错,从异常看,说明o1是A元素。

所以,最后的结论是,o1是A,o2是F。也就是说我们处理流时,不是按我们的list的索引从0开始的处理,而是反向处理的。

另一种论证方式:直接打印出我们的o1和o2

结论:在sorted((o1,o2)->{return o1.compareTo(o2)})这个方法里,我们的参数是从后往前取的。o1是最后一个元素,o2是倒数第二个元素,依次类推。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/72722.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

无刷直流电机

无刷直流电机 无刷直流电机(Brushless Direct Current Motor,简称BLDC)是一种没有电刷和换向器的电机,它使用电子方式切换电流方向来控制电机的旋转。与传统的有刷直流电机相比,无刷直流电机具有许多优点,包括高效率、低噪音、长寿命和高可靠性。 一、直流无刷电机的组成…

Megacli查看Dell服务器Raid状态

通常我们使用的DELL/HP/IBM三家的机架式PC级服务器阵列卡是从LSI的卡OEM出来的,DELL和IBM两家的阵列卡原生程度较高,没有做太多封装,可以用原厂提供的阵列卡管理工具进行监控;而HP的阵列卡一般都做过封装了,因此需要使用自身特有的管理工具来监控。 MegaCli是一款管理维护…

基于BP神经网络的CoSaMP信道估计算法matlab性能仿真,对比LS,OMP,MOMP,CoSaMP

1.算法仿真效果 matlab2022a仿真结果如下(完整代码运行后无水印): 仿真操作步骤可参考程序配套的操作视频。2.算法涉及理论知识概要LS估计法实现方式较为简单,其估计过程没有考虑实际信道的噪声因素。因此,特别当毫米波MIMO信道干扰较大时,其估计性能较差,只适用于对信道…

中兴光猫F7615TV3 改散热

中兴光猫F7615TV3 改散热之前有剩余的散热片, 各种贴! 温控开关是 50 度的常开, (达到 50 度 开始闭合 接通电路) 风扇开转 电话插口有点影响焊接, 自己又用不到, 直接拆掉! 温控开关这边是接到负极这边 在 dc 取电的时候不太好焊 用打磨笔将金属片 打磨打磨, 就比较好焊接…

ton初始化合约的参数不一样,生成的合约地址也是一样

发现一个问题,tact合约如果代码都没有更改的情况下,不论怎么编译,合约地址都是同一个。 然后发现只要初始化的参数不一样就可以简单的生成不同的合约:contract StudyContract with Deployable {msg: String = "123";// Constructorinit(msg: String){self.msg = …

Tang Primer 25K学习记录

Tang Primer 25KTang Primer 25K 是基于 GW5A-LV25MG121 所设计的一款极小封装的核心板(23x18mm),并配套全引脚引出(除MIPI高速脚外)的25K Dock底板。(国产高云FPGA),作为学习使用,非常小巧,大家可以购买(底板的3d保护壳可以使用博主的,建议打印一个,因为fpga开发板这…

VUE传递字符串显示二维码

1.安装插件npm install vue-qrcode 2.使用<script setup lang="ts"> import { ref } from vue import VueQrcode from vue-qrcode; const qrCodeString = ref(abc); </script><vue-qrcode :value="qrCodeString" :size="150">…

环境安装

模拟器root环境 安装Magisk:安装链接用于定制Android开源软件,支持高于Android 5.0设备 MagiskSU:为应用程序提供root访问权限 Magisk模块:通过安装模块修改只读分区 MagiskHide:从根检测/系统完整性检查中隐藏Magisk(Shamiko) MagiskBoot:最完整的安卓启动镜像解包和重新…