java8List.sort()排序常用方法

Posted 沛沛老爹

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java8List.sort()排序常用方法相关的知识,希望对你有一定的参考价值。

常规操作

升序

普通升序

list.sort(Comparator.comparing(T::getSort))

多条件升序

先按照排序字段排序,如果排序字段值相等,则继续比较创建时间。

list.sort(Comparator.comparing(T::getSort).thenComparing(T::getCreatTime));

降序

使用reversed的方法进行反向排序

list.sort(Comparator.comparing(T::getSort).reversed());

升序+降序

list.sort(Comparator.comparing(T::getSort)
        .thenComparing(T::getCreateTime).reversed());


对象排序

内比较器-Comparable

Comparable在集合内部定义的方法实现的排序,位于java.lang下。Comparable支持自比较,自比较是指比如String等类里面本身就有CompareTo()方法,直接就可以进行String类对象的比较,也就是说,实现了Comparable接口的类的对象的列表或数组可以通过Collections.sort或Arrays.sort进行自动排序,也就是大家常说的自然排序

Comparable的源码

public interface Comparable<T> 
    /**
     * Compares this object with the specified object for order.  Returns a
     * negative integer, zero, or a positive integer as this object is less
     * than, equal to, or greater than the specified object.
     *
     * <p>The implementor must ensure
     * @code sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
     * for all @code x and @code y.  (This
     * implies that @code x.compareTo(y) must throw an exception iff
     * @code y.compareTo(x) throws an exception.)
     *
     * <p>The implementor must also ensure that the relation is transitive:
     * @code (x.compareTo(y) > 0 && y.compareTo(z) > 0) implies
     * @code x.compareTo(z) > 0.
     *
     * <p>Finally, the implementor must ensure that @code x.compareTo(y)==0
     * implies that @code sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for
     * all @code z.
     *
     * <p>It is strongly recommended, but <i>not</i> strictly required that
     * @code (x.compareTo(y)==0) == (x.equals(y)).  Generally speaking, any
     * class that implements the @code Comparable interface and violates
     * this condition should clearly indicate this fact.  The recommended
     * language is "Note: this class has a natural ordering that is
     * inconsistent with equals."
     *
     * <p>In the foregoing description, the notation
     * @code sgn(<i>expression</i>@code ) designates the mathematical
     * <i>signum</i> function, which is defined to return one of @code -1,
     * @code 0, or @code 1 according to whether the value of
     * <i>expression</i> is negative, zero, or positive, respectively.
     *
     * @param   o the object to be compared.
     * @return  a negative integer, zero, or a positive integer as this object
     *          is less than, equal to, or greater than the specified object.
     *
     * @throws NullPointerException if the specified object is null
     * @throws ClassCastException if the specified object's type prevents it
     *         from being compared to this object.
     */
    public int compareTo(T o);

整个内部只有一个接口方法:public int compareTo(T o);

它的作用主要是比较当前实现接口的对象与指定对象o的顺序。它根据比较的结果返回负数、0和正数。

相对应的关系如下:

1、如果 o1.compareTo(o2)<0  ==> o1<o2

2、o1.compareTo(o2)==0    ==> o1==o2

3、o1.compareTo(o2)>0   ==> o1>o2

实现方式

常规的实现方式,是类实现Comparable接口和实现对应的compareTo(T o) 方法。

假设我们要实现对User对象的比较。排序条件是根据用户年纪age的大小来区分。

示例代码如下

1、让User类实现Comparable接口

2、重新compareTo方法,使用当前对象的age-参数的年纪,得到返回结果来进行判定。

@Data
public class User implements Comparable<User>

    /**姓名*/
    private String name;
    /**年纪*/
    private Integer age;
 
    /**
    * 重写compareTo方法,根据年纪进行排序
    */
    @Override
    public int compareTo(User u)
    
        return this.age-u.getAge();
    

测试验证:

    public static void main(String[] args)
    
        User[] userArr=new User[]new User("Zhangsan", 20),new User("Lisi", 10);
        
        System.out.println("======排序前======");
       
         for (User user : userArr)
        
            System.out.print(user.getName()+":"+user.getAge());
        
     
        
        System.out.println("=======排序后======");

        Arrays.sort(userArr);

        for (User user : userArr)
        
            System.out.print(user.getName()+":"+user.getAge());
        
    

测试结果就不输出了,您可以复制代码自己试下看看。

说到这里了,大家有可能就会问了。如果我有已经写好的类了,没有实现Comparable接口,但是我不想去改它了。还可以实现排序么?

当然是可以的,这个时候,我们的Comparator就可以拿出来比划比划了。。。

外比较器-Comparator

Comparator是在集合外部实现的排序,位于java.util下。它

源代码(代码有点长,建议跳过该步骤)

/*
 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.util;

import java.io.Serializable;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.ToDoubleFunction;
import java.util.Comparators;

/**
 * A comparison function, which imposes a <i>total ordering</i> on some
 * collection of objects.  Comparators can be passed to a sort method (such
 * as @link Collections#sort(List,Comparator) Collections.sort or @link
 * Arrays#sort(Object[],Comparator) Arrays.sort) to allow precise control
 * over the sort order.  Comparators can also be used to control the order of
 * certain data structures (such as @link SortedSet sorted sets or @link
 * SortedMap sorted maps), or to provide an ordering for collections of
 * objects that don't have a @link Comparable natural ordering.<p>
 *
 * The ordering imposed by a comparator @code c on a set of elements
 * @code S is said to be <i>consistent with equals</i> if and only if
 * @code c.compare(e1, e2)==0 has the same boolean value as
 * @code e1.equals(e2) for every @code e1 and @code e2 in
 * @code S.<p>
 *
 * Caution should be exercised when using a comparator capable of imposing an
 * ordering inconsistent with equals to order a sorted set (or sorted map).
 * Suppose a sorted set (or sorted map) with an explicit comparator @code c
 * is used with elements (or keys) drawn from a set @code S.  If the
 * ordering imposed by @code c on @code S is inconsistent with equals,
 * the sorted set (or sorted map) will behave "strangely."  In particular the
 * sorted set (or sorted map) will violate the general contract for set (or
 * map), which is defined in terms of @code equals.<p>
 *
 * For example, suppose one adds two elements @code a and @code b such that
 * @code (a.equals(b) && c.compare(a, b) != 0)
 * to an empty @code TreeSet with comparator @code c.
 * The second @code add operation will return
 * true (and the size of the tree set will increase) because @code a and
 * @code b are not equivalent from the tree set's perspective, even though
 * this is contrary to the specification of the
 * @link Set#add Set.add method.<p>
 *
 * Note: It is generally a good idea for comparators to also implement
 * @code java.io.Serializable, as they may be used as ordering methods in
 * serializable data structures (like @link TreeSet, @link TreeMap).  In
 * order for the data structure to serialize successfully, the comparator (if
 * provided) must implement @code Serializable.<p>
 *
 * For the mathematically inclined, the <i>relation</i> that defines the
 * <i>imposed ordering</i> that a given comparator @code c imposes on a
 * given set of objects @code S is:<pre>
 *       (x, y) such that c.compare(x, y) &lt;= 0.
 * </pre> The <i>quotient</i> for this total order is:<pre>
 *       (x, y) such that c.compare(x, y) == 0.
 * </pre>
 *
 * It follows immediately from the contract for @code compare that the
 * quotient is an <i>equivalence relation</i> on @code S, and that the
 * imposed ordering is a <i>total order</i> on @code S.  When we say that
 * the ordering imposed by @code c on @code S is <i>consistent with
 * equals</i>, we mean that the quotient for the ordering is the equivalence
 * relation defined by the objects' @link Object#equals(Object)
 * equals(Object) method(s):<pre>
 *     (x, y) such that x.equals(y). </pre>
 *
 * <p>Unlike @code Comparable, a comparator may optionally permit
 * comparison of null arguments, while maintaining the requirements for
 * an equivalence relation.
 *
 * <p>This interface is a member of the
 * <a href="@docRoot/java.base/java/util/package-summary.html#CollectionsFramework">
 * Java Collections Framework</a>.
 *
 * @param <T> the type of objects that may be compared by this comparator
 *
 * @author  Josh Bloch
 * @author  Neal Gafter
 * @see Comparable
 * @see java.io.Serializable
 * @since 1.2
 */
@FunctionalInterface
public interface Comparator<T> 
    /**
     * Compares its two arguments for order.  Returns a negative integer,
     * zero, or a positive integer as the first argument is less than, equal
     * to, or greater than the second.<p>
     *
     * The implementor must ensure that @code sgn(compare(x, y)) ==
     * -sgn(compare(y, x)) for all @code x and @code y.  (This
     * implies that @code compare(x, y) must throw an exception if and only
     * if @code compare(y, x) throws an exception.)<p>
     *
     * The implementor must also ensure that the relation is transitive:
     * @code ((compare(x, y)>0) && (compare(y, z)>0)) implies
     * @code compare(x, z)>0.<p>
     *
     * Finally, the implementor must ensure that @code compare(x, y)==0
     * implies that @code sgn(compare(x, z))==sgn(compare(y, z)) for all
     * @code z.<p>
     *
     * It is generally the case, but <i>not</i> strictly required that
     * @code (compare(x, y)==0) == (x.equals(y)).  Generally speaking,
     * any comparator that violates this condition should clearly indicate
     * this fact.  The recommended language is "Note: this comparator
     * imposes orderings that are inconsistent with equals."<p>
     *
     * In the foregoing description, the notation
     * @code sgn(<i>expression</i>@code ) designates the mathematical
     * <i>signum</i> function, which is defined to return one of @code -1,
     * @code 0, or @code 1 according to whether the value of
     * <i>expression</i> is negative, zero, or positive, respectively.
     *
     * @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);

    /**
     * Indicates whether some other object is &quot;equal to&quot; this
     * comparator.  This method must obey the general contract of
     * @link Object#equals(Object).  Additionally, this method can return
     * @code true <i>only</i> if the specified object is also a comparator
     * and it imposes the same ordering as this comparator.  Thus,
     * @code comp1.equals(comp2) implies that @code sgn(comp1.compare(o1,
     * o2))==sgn(comp2.compare(o1, o2)) for every object reference
     * @code o1 and @code o2.<p>
     *
     * Note that it is <i>always</i> safe <i>not</i> to override
     * @code Object.equals(Object).  However, overriding this method may,
     * in some cases, improve performance by allowing programs to determine
     * that two distinct comparators impose the same order.
     *
     * @param   obj   the reference object with which to compare.
     * @return  @code true only if the specified object is also
     *          a comparator and it imposes the same ordering as this
     *          comparator.
     * @see Object#equals(Object)
     * @see Object#hashCode()
     */
    boolean equals(Object obj);

    /**
     * Returns a comparator that imposes the reverse ordering of this
     * comparator.
     *
     * @return a comparator that imposes the reverse ordering of this
     *         comparator.
     * @since 1.8
     */
    default Comparator<T> reversed() 
        return Collections.reverseOrder(this);
    

    /**
     * Returns a lexicographic-order comparator with another comparator.
     * If this @code Comparator considers two elements equal, i.e.
     * @code compare(a, b) == 0, @code other is used to determine the order.
     *
     * <p>The returned comparator is serializable if the specified comparator
     * is also serializable.
     *
     * @apiNote
     * For example, to sort a collection of @code String based on the length
     * and then case-insensitive natural ordering, the comparator can be
     * composed using following code,
     *
     * <pre>@code
     *     Comparator<String> cmp = Comparator.comparingInt(String::length)
     *             .thenComparing(String.CASE_INSENSITIVE_ORDER);
     * </pre>
     *
     * @param  other the other comparator to be used when this comparator
     *         compares two objects that are equal.
     * @return a lexicographic-order comparator composed of this and then the
     *         other comparator
     * @throws NullPointerException if the argument is null.
     * @since 1.8
     */
    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);
        ;
    

    /**
     * Returns a lexicographic-order comparator with a function that
     * extracts a key to be compared with the given @code Comparator.
     *
     * @implSpec This default implementation behaves as if @code
     *           thenComparing(comparing(keyExtractor, cmp)).
     *
     * @param  <U>  the type of the sort key
     * @param  keyExtractor the function used to extract the sort key
     * @param  keyComparator the @code Comparator used to compare the sort key
     * @return a lexicographic-order comparator composed of this comparator
     *         and then comparing on the key extracted by the keyExtractor function
     * @throws NullPointerException if either argument is null.
     * @see #comparing(Function, Comparator)
     * @see #thenComparing(Comparator)
     * @since 1.8
     */
    default <U> Comparator<T> thenComparing(
            Function<? super T, ? extends U> keyExtractor,
            Comparator<? super U> keyComparator)
    
        return thenComparing(comparing(keyExtractor, keyComparator));
    

    /**
     * Returns a lexicographic-order comparator with a function that
     * extracts a @code Comparable sort key.
     *
     * @implSpec This default implementation behaves as if @code
     *           thenComparing(comparing(keyExtractor)).
     *
     * @param  <U>  the type of the @link Comparable sort key
     * @param  keyExtractor the function used to extract the @link
     *         Comparable sort key
     * @return a lexicographic-order comparator composed of this and then the
     *         @link Comparable sort key.
     * @throws NullPointerException if the argument is null.
     * @see #comparing(Function)
     * @see #thenComparing(Comparator)
     * @since 1.8
     */
    default <U extends Comparable<? super U>> Comparator<T> thenComparing(
            Function<? super T, ? extends U> keyExtractor)
    
        return thenComparing(comparing(keyExtractor));
    

    /**
     * Returns a lexicographic-order comparator with a function that
     * extracts an @code int sort key.
     *
     * @implSpec This default implementation behaves as if @code
     *           thenComparing(comparingInt(keyExtractor)).
     *
     * @param  keyExtractor the function used to extract the integer sort key
     * @return a lexicographic-order comparator composed of this and then the
     *         @code int sort key
     * @throws NullPointerException if the argument is null.
     * @see #comparingInt(ToIntFunction)
     * @see #thenComparing(Comparator)
     * @since 1.8
     */
    default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) 
        return thenComparing(comparingInt(keyExtractor));
    

    /**
     * Returns a lexicographic-order comparator with a function that
     * extracts a @code long sort key.
     *
     * @implSpec This default implementation behaves as if @code
     *           thenComparing(comparingLong(keyExtractor)).
     *
     * @param  keyExtractor the function used to extract the long sort key
     * @return a lexicographic-order comparator composed of this and then the
     *         @code long sort key
     * @throws NullPointerException if the argument is null.
     * @see #comparingLong(ToLongFunction)
     * @see #thenComparing(Comparator)
     * @since 1.8
     */
    default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) 
        return thenComparing(comparingLong(keyExtractor));
    

    /**
     * Returns a lexicographic-order comparator with a function that
     * extracts a @code double sort key.
     *
     * @implSpec This default implementation behaves as if @code
     *           thenComparing(comparingDouble(keyExtractor)).
     *
     * @param  keyExtractor the function used to extract the double sort key
     * @return a lexicographic-order comparator composed of this and then the
     *         @code double sort key
     * @throws NullPointerException if the argument is null.
     * @see #comparingDouble(ToDoubleFunction)
     * @see #thenComparing(Comparator)
     * @since 1.8
     */
    default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) 
        return thenComparing(comparingDouble(keyExtractor));
    

    /**
     * Returns a comparator that imposes the reverse of the <em>natural
     * ordering</em>.
     *
     * <p>The returned comparator is serializable and throws @link
     * NullPointerException when comparing @code null.
     *
     * @param  <T> the @link Comparable type of element to be compared
     * @return a comparator that imposes the reverse of the <i>natural
     *         ordering</i> on @code Comparable objects.
     * @see Comparable
     * @since 1.8
     */
    public static <T extends Comparable<? super T>> Comparator<T> reverseOrder() 
        return Collections.reverseOrder();
    

    /**
     * Returns a comparator that compares @link Comparable objects in natural
     * order.
     *
     * <p>The returned comparator is serializable and throws @link
     * NullPointerException when comparing @code null.
     *
     * @param  <T> the @link Comparable type of element to be compared
     * @return a comparator that imposes the <i>natural ordering</i> on @code
     *         Comparable objects.
     * @see Comparable
     * @since 1.8
     */
    @SuppressWarnings("unchecked")
    public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() 
        return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
    

    /**
     * Returns a null-friendly comparator that considers @code null to be
     * less than non-null. When both are @code null, they are considered
     * equal. If both are non-null, the specified @code Comparator is used
     * to determine the order. If the specified comparator is @code null,
     * then the returned comparator considers all non-null values to be equal.
     *
     * <p>The returned comparator is serializable if the specified comparator
     * is serializable.
     *
     * @param  <T> the type of the elements to be compared
     * @param  comparator a @code Comparator for comparing non-null values
     * @return a comparator that considers @code null to be less than
     *         non-null, and compares non-null objects with the supplied
     *         @code Comparator.
     * @since 1.8
     */
    public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) 
        return new Comparators.NullComparator<>(true, comparator);
    

    /**
     * Returns a null-friendly comparator that considers @code null to be
     * greater than non-null. When both are @code null, they are considered
     * equal. If both are non-null, the specified @code Comparator is used
     * to determine the order. If the specified comparator is @code null,
     * then the returned comparator considers all non-null values to be equal.
     *
     * <p>The returned comparator is serializable if the specified comparator
     * is serializable.
     *
     * @param  <T> the type of the elements to be compared
     * @param  comparator a @code Comparator for comparing non-null values
     * @return a comparator that considers @code null to be greater than
     *         non-null, and compares non-null objects with the supplied
     *         @code Comparator.
     * @since 1.8
     */
    public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) 
        return new Comparators.NullComparator<>(false, comparator);
    

    /**
     * Accepts a function that extracts a sort key from a type @code T, and
     * returns a @code Comparator<T> that compares by that sort key using
     * the specified @link Comparator.
      *
     * <p>The returned comparator is serializable if the specified function
     * and comparator are both serializable.
     *
     * @apiNote
     * For example, to obtain a @code Comparator that compares @code
     * Person objects by their last name ignoring case differences,
     *
     * <pre>@code
     *     Comparator<Person> cmp = Comparator.comparing(
     *             Person::getLastName,
     *             String.CASE_INSENSITIVE_ORDER);
     * </pre>
     *
     * @param  <T> the type of element to be compared
     * @param  <U> the type of the sort key
     * @param  keyExtractor the function used to extract the sort key
     * @param  keyComparator the @code Comparator used to compare the sort key
     * @return a comparator that compares by an extracted key using the
     *         specified @code Comparator
     * @throws NullPointerException if either argument is null
     * @since 1.8
     */
    public static <T, U> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor,
            Comparator<? super U> keyComparator)
    
        Objects.requireNonNull(keyExtractor);
        Objects.requireNonNull(keyComparator);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),
                                              keyExtractor.apply(c2));
    

    /**
     * Accepts a function that extracts a @link java.lang.Comparable
     * Comparable sort key from a type @code T, and returns a @code
     * Comparator<T> that compares by that sort key.
     *
     * <p>The returned comparator is serializable if the specified function
     * is also serializable.
     *
     * @apiNote
     * For example, to obtain a @code Comparator that compares @code
     * Person objects by their last name,
     *
     * <pre>@code
     *     Comparator<Person> byLastName = Comparator.comparing(Person::getLastName);
     * </pre>
     *
     * @param  <T> the type of element to be compared
     * @param  <U> the type of the @code Comparable sort key
     * @param  keyExtractor the function used to extract the @link
     *         Comparable sort key
     * @return a comparator that compares by an extracted key
     * @throws NullPointerException if the argument is null
     * @since 1.8
     */
    public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)
    
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    

    /**
     * Accepts a function that extracts an @code int sort key from a type
     * @code T, and returns a @code Comparator<T> that compares by that
     * sort key.
     *
     * <p>The returned comparator is serializable if the specified function
     * is also serializable.
     *
     * @param  <T> the type of element to be compared
     * @param  keyExtractor the function used to extract the integer sort key
     * @return a comparator that compares by an extracted key
     * @see #comparing(Function)
     * @throws NullPointerException if the argument is null
     * @since 1.8
     */
    public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) 
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));
    

    /**
     * Accepts a function that extracts a @code long sort key from a type
     * @code T, and returns a @code Comparator<T> that compares by that
     * sort key.
     *
     * <p>The returned comparator is serializable if the specified function is
     * also serializable.
     *
     * @param  <T> the type of element to be compared
     * @param  keyExtractor the function used to extract the long sort key
     * @return a comparator that compares by an extracted key
     * @see #comparing(Function)
     * @throws NullPointerException if the argument is null
     * @since 1.8
     */
    public static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) 
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> Long.compare(keyExtractor.applyAsLong(c1), keyExtractor.applyAsLong(c2));
    

    /**
     * Accepts a function that extracts a @code double sort key from a type
     * @code T, and returns a @code Comparator<T> that compares by that
     * sort key.
     *
     * <p>The returned comparator is serializable if the specified function
     * is also serializable.
     *
     * @param  <T> the type of element to be compared
     * @param  keyExtractor the function used to extract the double sort key
     * @return a comparator that compares by an extracted key
     * @see #comparing(Function)
     * @throws NullPointerException if the argument is null
     * @since 1.8
     */
    public static<T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) 
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> Double.compare(keyExtractor.applyAsDouble(c1), keyExtractor.applyAsDouble(c2));
    

方法有点多,这里就简单说下要实现的方法。int compare(T o1, T o2),此方法是比较o1和o2的大小。返回的和compareTo的结果方式差不多

1、如果 compare(o1,o2)<0  ==> o1<o2

2、compare(o1,o2)==0    ==> o1==o2

3、compare(o1,o2)>0   ==> o1>o2

假如我们的User类,我们不想修改原来的代码了。我们可以按照下面的思路来解决:

1、创建一个新的类,让它实现Comparator接口。然后sort的时候使用其来作为比较器使用。

代码

1、实体类

@Data
public class User
    /**姓名*/
    private String name;
    /**年纪*/
    private Integer age;
 
    /**
    * 重写compareTo方法,根据年纪进行排序
    */a
    @Override
    public int compareTo(User u)
    
        return this.age-u.getAge();
    

2、比较器

public class UserCompartor implements Comparator<User>

    @Override
    public int compare(User o1, User o2)
    
        return o1.getAge()-o2.getAge();
    

3、验证代码

    public static void main(String[] args)
    
        User[] userArr=new User[]new User("Zhangsan", 20),new User("Lisi", 10);
        
        System.out.println("======排序前======");
       
         for (User user : userArr)
        
            System.out.print(user.getName()+":"+user.getAge());
        
     
        
        System.out.println("=======排序后======");

        Arrays.sort(userArr,new UserCompartor());

        for (User user : userArr)
        
            System.out.print(user.getName()+":"+user.getAge());
        
    

总结

Java 中的两种对象排序方式:

  1. Comparable 自然排序。(由实体类实现)
  2. Comparator 是定制排序。(无法修改实体类时,直接在调用方创建)

到了这里,大家是否有个疑问?为什么前面简单的String,Integer这些可以直接使用sort的排序来实现,而自定义的对象却需要去重写对应的方法?

这是因为,普通的数据类型它们默认实现了Comparable 接口,实现了 compareTo 方法,所以我们可以直接使用。不信的话,你可以查找对应的基础数据类型的类看下。

下面Integer的这个大家可以看下

package java.lang;

import java.lang.annotation.Native;
import java.util.Objects;
import jdk.internal.HotSpotIntrinsicCandidate;
import jdk.internal.misc.VM;

import static java.lang.String.COMPACT_STRINGS;
import static java.lang.String.LATIN1;
import static java.lang.String.UTF16;

/**
 * The @code Integer class wraps a value of the primitive type
 * @code int in an object. An object of type @code Integer
 * contains a single field whose type is @code int.
 *
 * <p>In addition, this class provides several methods for converting
 * an @code int to a @code String and a @code String to an
 * @code int, as well as other constants and methods useful when
 * dealing with an @code int.
 *
 * <p>Implementation note: The implementations of the "bit twiddling"
 * methods (such as @link #highestOneBit(int) highestOneBit and
 * @link #numberOfTrailingZeros(int) numberOfTrailingZeros) are
 * based on material from Henry S. Warren, Jr.'s <i>Hacker's
 * Delight</i>, (Addison Wesley, 2002).
 *
 * @author  Lee Boynton
 * @author  Arthur van Hoff
 * @author  Josh Bloch
 * @author  Joseph D. Darcy
 * @since 1.0
 */
public final class Integer extends Number implements Comparable<Integer> 

以上是关于java8List.sort()排序常用方法的主要内容,如果未能解决你的问题,请参考以下文章

Java Array.sort的六种常用方法总结

Java Array.sort的六种常用方法总结

集合Collections 常用的排序方法

Colletions工具类常用方法

php数组常用函数

100天精通Python(数据分析篇)——第70天:Pandas常用排序排名方法(sort_indexsort_valuesrank)