Java容器类研究2:List

java.util.Listjava

replaceAll

在Java8中引入该方法,用来替换list中的每一个元素。数组

default void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        final ListIterator<E> li = this.listIterator();
        while (li.hasNext()) {
            li.set(operator.apply(li.next()));
        }
    }

Iterator的set方法,只能在next或previous以后使用,也就是确保当前Iterator指向了一个存在的项。该方法使用很方便,使用lambda运算能够很清晰的表达想要进行的替换操做。app

public class Ripper {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            numbers.add(i);
        }
        numbers.replaceAll(item -> item * item);
    }
}

sort

public class Ripper {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        for (int i = 10; i > 0; i--) {
            numbers.add(i);
        }

        numbers.sort(Integer::compare);

        numbers.sort(null);

        numbers.sort((a, b) -> a - b);

        numbers.sort(Comparator.comparingInt(a -> a * a));
    }
}

一样sort函数也是在1.8中引入,而且能够使用lambda表达式定义本身的比较规则,上面四种排序结果都是同样的。这里使用了Comparator.comparingInt,该方法能够将非int对象先映射为int型,而后进行比较。函数

具体实现:ui

default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }

这里首先将原来的list的copy为一个数组,而后再进行排序,这里采用的是merge sort。为何要先copy下来,排序完成后再设置原list?官方解释是在原数组上进行排序可能会致使n2log(n)的复杂度。this

toArray函数将基于Collection的结构转化成了数组结构,这里的ListArray的toArray方法是浅拷贝,从下面例子能够看出:code

public class Ripper {
    int value;

    public Ripper(int v) {
        value = v;
    }

    public static void main(String[] args) {
        List<Ripper> numbers = new ArrayList<>();
        for (int i = 10; i > 0; i--) {
            numbers.add(new Ripper(i));
        }
        Object[] array = numbers.toArray();
        array[0] = array[1];
        System.out.println(numbers.get(0).value);
        Ripper a1 = (Ripper) array[0];
        a1.value = 100;
        System.out.println(numbers.get(0).value);
        System.out.println(numbers.get(1).value);

    }
}

输出是:对象

10
10
100

说明建立的array是指向一个新的数组对象,可是数组中每一项保留的引用是指向原来的对象的。排序

spliterator

default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.ORDERED);
    }

List存储的是有序的数组,因此划分时会按照顺序进行划分。ip

相关文章
相关标签/搜索