根据the docs

thenComparing

默认U扩展比较?超级U比较器然后比较超级T,?扩展U keyExtractor)

返回词典顺序比较器,该比较器具有提取Comparable排序键的函数.

因此,以下代码位的输出应该是"a:1"、"a:12"、"a:4".然而,生成的列表是按大小写排序的.

怎么会?我是不是误解了文档?

(s-属性只是为了具有初始排序键,以便可以应用thenComparing)

import java.util.*;

public class MyClass {
    public static void main(String[] args) {
      List<Container> list = new ArrayList<>();
      list.add(new Container("a", 4));
      list.add(new Container("a", 12));
      list.add(new Container("a", 1));
  
      list.sort(Comparator.comparing(Container::getS)
          .thenComparing(Container::getX)
      );
      
      for (Container c : list) {
          System.out.println(c.getS() + " : " + c.getX());
      }
    }
    
    public static class Container {
        private String s;
        private Integer x;
        
        public Container(String s, Integer x) {
            this.s = s;
            this.x = x;
        }
        
        public Integer getX() {
            return this.x;
        }
        
        public String getS() {
            return this.s;
        }
    }
}

推荐答案

Updated answer

"词典顺序"的字面意思是就像词典中一样的顺序(来自希腊词词典,意思是词典).词典顺序如下:

  1. 比较每个单词的第一个字母.如果它们不同,请停在这里.

  2. 由于两个单词的第一个字母相同,现在比较每个单词的第二个字母.如果它们不同,就停下来.

  3. 用第三个字母和后面的字母重复步骤2,直到发现差异.

因此,一个词被分解成元素(字母),然后依次比较每个元素,直到找到差异.这就是词典顺序的定义.Exactly the same happens with 100.如何?像这样:

Comparator.comparing(Container::getS)--这是一个比较

.thenComparing(Container::getX)--这将采用之前的比较器并返回新的比较器.

这里的关键是,由thenComparing返回的比较器不仅仅比较x.事实上,thenComparing返回一个比较器,该比较器首先比较s,然后比较x.这就是词典顺序的定义.但请注意,sx都是不可分割的元素.您使用自然顺序比较s,然后使用自然顺序比较x(这意味着作为一个整体进行比较).

词典顺序并不意味着将单个元素(x)拆分为子元素.这类似于英语词典试图通过将各个字母拆分为组成该字母的笔的各个笔画来比较单词.


Addendum by the OP of the question:

上面可以简洁地说:由.thenComparing产生的比较者引发了某个迦太基产品的词典顺序.(见the relevant section on Wikipedia for lex orders on cartesian products)

更准确地说,假设类C具有两个可比属性(即其类实现Comparabale)public S spublic T t. 然后Comparator.comparing(C::getS).thenComparing(C::getT)返回一个比较器,该比较器给出"ST的carriage积"的命令.这个顺序是词典编纂的,即"首先使用S的compareTo将S排序到桶中,然后使用T的compareTo对每个S-桶中的T对象排序".


Old answer (kept just because it's referenced in a comment)

词典顺序不仅仅是字母顺序.它也可以应用于数字,在这种情况下它是数字顺序.正如Online Encyclopedia of Integer Sequences中所说:

当应用于数字时,词典顺序就是数字顺序的增加

因此,thenComparing在12之前订购4是完全正确的,因为您正在比较Integer个实例.

这不仅仅与thenComparing有关:只需调用comparing即可获得相同的结果.请注意,调用comparingthenComparing并不会神奇地将两个字段放入字符串中.它比较第一个字段,然后,当且仅当两个实例的第一个字段相等,它使用该字段的(并且仅该字段的)自然顺序来分配第二个字段(由thenComparing指代).

Java相关问答推荐

如何在Spring Boot中创建500错误的响应正文?

Java应用程序崩溃时试图读取联系人从电话

Jooq外键关系

ApachePOI:不带换行的新行

Java记录的不同序列化/反序列化

Java中如何根据Font.canDisplay方法对字符串进行分段

Spark上下文在向Spark提交数据集时具有内容,但Spark在实际构建它时发现它为空

编译多个.Java文件并运行一个依赖于用户参数的文件

有没有办法让扩展变得多态?

与不同顺序的组进行匹配,不重复组但分开

继续收到错误SQLJDBC EXCEPTION执行";org.springframework.dao.InvalidDataAccessResourceUsageException:&

try 使用Spring集成和MySQL实现发件箱模式时,锁定等待超时

寻找Thread.sky()方法的清晰度

在Oracle db中,当我们提供字符串而不是数字时,比较是如何工作的?

除0错误/抱歉我的句子是PT

从12小时开始的日期模式

保持标题窗格的箭头可见,即使设置为不可折叠

如何在JSP中从select中获取值并将其放入另一个select

由于可为null,无法在kotlin中实现java接口

简化每个元素本身都是 map 列表的列表