繁体   English   中英

Java 8 List.sort用法

[英]Java 8 List.sort usage

Java 8中的List类添加了一个新的方法sort 任何人都可以澄清我应该何时更喜欢使用它而不是Collections.sort(..)方法?

没有功能差异,因为Collections.sort(list)调用list.sort(null)Collections.sort(list, comparator)调用list.sort(comparator)

所以这只是一种风格问题 - 当提供自己的比较器时,在列表上调用sort可能比使用外部静态方法更自然和可读。

但是,如果您只想按自然顺序对列表进行排序,则Collections.sort(list)可能比list.sort(null)更清晰。

你应该去List.sort

使用List.sort示例,根据元素的长度对String列表进行排序:

List<String> list = new ArrayList<>(Arrays.asList("aa", "aaa", "a"));
list.sort(comparing(String::length));

Collections.sort()是Java 8之前的做法。 请注意,两者之间没有真正的区别。 如果您查看Collections.sort源代码,您会注意到它调用list.sort

public static <T extends Comparable<? super T>> void sort(List<T> list, Comparator<? super T> c) {
    list.sort(c);
}

虽然您可以使用List.sort(Comparator)方法,但此方法的主要目的是重写。 在Java-8之前,每个List的排序都有些无效。 首先通过toArray()方法将列表转储到数组中,然后对数组进行排序,最后通过ListIterator.set更新列表。 在Java-8中,这是List.sort(Comparator)默认方法中实现的默认行为。 但是,如果可以提供更有效的算法,则可以在子类中更改它。 例子:

  • ArrayListArrays.asList()提供自己的sort实现,直接对内部数组进行排序,因此您无需来回复制。

  • CopyOnWriteArrayList现在就可以排序了! 请尝试以下代码:

     List<String> list = new CopyOnWriteArrayList<>(Arrays.asList("a", "c", "b")); Collections.sort(list); 

    在Java-7中,它抛出UnsupportedOperationException ,因为支持ListIterator.set与此列表的思想相矛盾(每个迭代器都迭代独立快照)。 在Java-8中, ListIterator.set仍然不受支持,但由于自定义排序实现,此代码可以正常工作。

  • Collections.singletonListCollections.emptyList什么都不做(排序0或1元素是无操作),这肯定比创建单元素或零元素数组更快,对其进行排序并迭代列表以设置值。

  • Collections.unmodifiableList现在只抛出UnsupportedOperationException 在Java-8之前,只有在将不可变列表转储到数组之后才会获得异常,对数组进行排序并开始将其写回。


这是一个可能在用户代码中有用的示例。 假设您要创建某个列表的映射视图:

public class MappedList<T, R> extends AbstractList<R> {
    private final List<T> source;
    private final Function<? super T, ? extends R> mapper;

    public MappedList(List<T> source, Function<? super T, ? extends R> mapper) {
        this.source = source;
        this.mapper = mapper;
    }

    @Override
    public R get(int index) {
        return mapper.apply(source.get(index));
    }

    @Override
    public int size() {
        return source.size();
    }
}

用法示例:

List<String> list = Arrays.asList("a", "foo", "bb", "bar", "qq");
List<Integer> mappedList = new MappedList<>(list, String::length);
System.out.println(mappedList); // prints [1, 3, 2, 3, 2]

工作正常,但尝试Collections.sort(mappedList); 你将得到UnsupportedOperationExceptionset操作不起作用,因为你无法反转映射功能)。 但是,如果在MappedList实现sort()方法,则可以对其进行正确排序(更改原始列表):

@Override
public void sort(Comparator<? super R> c) {
    @SuppressWarnings("unchecked")
    Comparator<? super T> comparator = c == null ? 
        Comparator.comparing((Function<? super T, ? extends Comparable<Object>>) mapper) : 
        Comparator.comparing(mapper, c);
    source.sort(comparator);
}

List<String> list = Arrays.asList("a", "foo", "bb", "bar", "qq");
List<Integer> mappedList = new MappedList<>(list, String::length);
Collections.sort(mappedList);
System.out.println(mappedList); // prints [1, 2, 2, 3, 3]
System.out.println(list); // prints [a, bb, qq, foo, bar]

在提供自己的比较器时应该使用它。 例如:

list.sort(Comparator.reverseOrder());

代替:

Collections.sort(list);
Collections.reverse(list);

列表类作为JSR 335更改的一部分,我们可以使用该方法对列表进行排序:

//在List中使用sort方法。

personList.sort((p1,p2) - > p1.firstName.compareTo(p2.firstName));

- 在java 8之前我们只能使用这个tye --- Collections.sort(personList,(p1,p2) - > p1.firstName.compareTo(p2.firstName));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM