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

本文深入探讨Java Stream API的流处理特性,特别是sorted方法的内部机制。通过实例演示如何利用流进行过滤、映射及排序操作,揭示元素处理顺序的真相。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

package com.br.itwzhangzx02.learn;


import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

import com.br.itwzhangzx02.learn.POJO.User;

public class StreamTest {

  /**
   * 1.id全部满足是偶数
   * 2.年龄大于10
   * 3.用户名大写
   * 4.用户名字母倒排序
   * 5.只输出一个用户名
   *
   *
   * */
  @Test
  public void testStream(){
    List<User> list = new ArrayList<User>(){
      {
        add(new User(1l,"q",10, "清华大学"));
        add(new User(2l,"f",12, "清华大学"));
        add(new User(3l,"b",15, "清华大学"));
        add(new User(4l,"a",12, "清华大学"));
        add(new User(5l,"d",25, "北京大学"));
        add(new User(6l,"c",16, "北京大学"));
        add(new User(7l,"t",14, "北京大学"));
        add(new User(8l,"g",14, "浙江大学"));
        add(new User(9l,"j",17, "浙江大学"));
        add(new User(10l,"l",10, "浙江大学"));
      }
    };
    list.stream()
      .filter(user -> user.getId()%2==0)
      .filter(user -> user.getAge()>10)
      .map(user -> user.getName().toUpperCase())
      .sorted((o1,o2)->{return 1;})
      .forEach(System.out::println);

    //sorted 方法中,我们重写compare方法:如果return是1,则是按照原先的排序排。-1则是按照逆序排
    //
  }
   /**          a negative integer, zero, or a positive integer as the
     *         first argument is less than, equal to, or greater than the
     *         second.**/

}
package com.br.itwzhangzx02.learn.POJO;

public class User {
  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Integer getAge() {
    return age;
  }

  public void setAge(Integer age) {
    this.age = age;
  }

  public String getSchool() {
    return school;
  }

  public void setSchool(String school) {
    this.school = school;
  }

  private Long id;       //主键id
  private String name;   //姓名
  private Integer age;   //年龄
  private String school; //学校

  public User(Long id, String name, Integer age, String school) {
    this.id = id;
    this.name = name;
    this.age = age;
    this.school = school;
  }
}

一开始的疑惑:

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

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

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

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

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

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

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

 public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }

 比较规则很简单,就是从字符数组的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是倒数第二个元素,依次类推。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值