有多个比较器被返回吗?

huangapple go评论85阅读模式
英文:

Are multiple comparators being returned?

问题

优先队列<Student> pq = new 优先队列<>(
        比较器.按照(Student::getCgpa).倒序()
        .然后比较(Student::getFname)
        .然后比较(Student::getToken)
        );
多个比较器被返回了吗如果是这样是如何实现的呢
因为这个构造函数只会返回一个比较器
英文:
PriorityQueue&lt;Student&gt; pq = new PriorityQueue&lt;(
    Comparator.comparing(Student::getCgpa).reversed()
    .thenComparing(Student::getFname)
    .thenComparing(Student::getToken)
    );

Are multiple comparators being returned? If so, how,
because this constructor only returns one.

答案1

得分: 1

"是否返回了多个比较器?" - 是的,在技术层面上是这样的。除了链中的最后一个Comparator之外,每个Comparator都用于创建另一个Comparator(通过调用reversed()thenComparing()方法)。但只有一个作为参数传递给了PriorityQueue

Comparator.comparing(Student::getCgpa) // <- 第一个比较器被创建并返回
    .reversed()                        // <- 第二个比较器被创建并返回
    .thenComparing(Student::getFname)  // <- 第三个比较器被创建并返回
    .thenComparing(Student::getToken)  // <- 第四个比较器被创建、返回,并作为参数传递
英文:

"Are multiple comparators being returned?" - Yes, on a techical level. Each Comparator except for the last in the chain is used to create another Comparator (through the calls reversed() and thenComparing()). But only one is passed along as a parameter to the PriorityQueue:

Comparator.comparing(Student::getCgpa) // &lt;- 1st comparator created &amp; returned
    .reversed()                        // &lt;- 2nd comparator created &amp; returned
    .thenComparing(Student::getFname)  // &lt;- 3nd comparator created &amp; returned
    .thenComparing(Student::getToken)  // &lt;- 4th comparator created, returned &amp; passed along as argument

答案2

得分: 0

  • 是否返回多个比较器?

  • 如果是这样,是怎么做到的?因为这个构造函数只返回一个比较器?

    根据thenComparing文档,给定的比较器会与前一个比较器链接在一起,形成一个可以使用多个规则对值进行排序的比较器。


从代码中:

default Comparator<T> thenComparing(Comparator<? super T> other) {
    Objects.requireNonNull(other);
    return (Comparator<T> & Serializable) (c1, c2) -> {
        int res = compare(c1, c2);
        return (res != 0) ? res : other.compare(c1, c2);
    };
}

这个新的比较器应用了以下规则:

  • 使用自身的比较测试
  • 如果值为0(元素相等),则使用传入的参数来决定结果

因此,实际上,使用多个链接的比较器会导致递归测试:

Comparator<Foo> cmp = Comparator.comparingInt(Foo::getA)
        .thenComparing(Foo::getB)
        .thenComparing(Foo::getC)
        .thenComparing(Foo::getD);

getA ->  1
     -> -1
     ->  0 -> getB ->  1
                   -> -1
                   ->  0 -> getC ->  1
                                 -> -1
                                 ->  0 -> getD -> ...
                                         -> ...
                   -> ...
     -> ...
英文:
  • Are multiple comparators being returned?

    No

  • if so how because this constructoronly returns one?

    From the thenComparing documentation, the given comparator is chained with the previous in one Comparator that can use several rules to sort values


From the code

default Comparator&lt;T&gt; thenComparing(Comparator&lt;? super T&gt; other) {
    Objects.requireNonNull(other);
    return (Comparator&lt;T&gt; &amp; Serializable) (c1, c2) -&gt; {
        int res = compare(c1, c2);
        return (res != 0) ? res : other.compare(c1, c2);
    };
}

The new comparator apply this

  • use its own comparing test
  • if value is 0 (equals element) then the parameter one is used to return its decision

So in fact, using multiple chaining results in recursivse tests

Comparator&lt;Foo&gt; cmp = Comparator.comparingInt(Foo::getA)
        .thenComparing(Foo::getB)
        .thenComparing(Foo::getC)
        .thenComparing(Foo::getD);

getA -&gt;  1
     -&gt; -1
     -&gt;  0 -&gt; getB -&gt;  1
                   -&gt; -1
                   -&gt;  0 -&gt; getC -&gt;  1
                                 -&gt; -1
                                 -&gt;  0 -&gt; getC -&gt;  1
                                               -&gt; -1
                                                ...

huangapple
  • 本文由 发表于 2020年8月30日 20:32:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/63657440.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定