美文网首页
Java 8 ArrayList新特性

Java 8 ArrayList新特性

作者: 但时间也偷换概念 | 来源:发表于2019-11-20 17:29 被阅读0次

引言:

今天主要分析一下Java 8版本中java.util.ArrayList集合类有何变化。

变化:

1.上层collection接口变化

        //1.8新增方法:提供了接口默认实现,返回分片迭代器
        @Override
        default Spliterator<E> spliterator() {
            return Spliterators.spliterator(this, 0);
        }
        //1.8新增方法:提供了接口默认实现,返回串行流对象
        default Stream<E> stream() {
            return StreamSupport.stream(spliterator(), false);
        }
        //1.8新增方法:提供了接口默认实现,返回并行流对象
        default Stream<E> parallelStream() {
            return StreamSupport.stream(spliterator(), true);
        }
        /**
         * Removes all of the elements of this collection that satisfy the given
         * predicate.  Errors or runtime exceptions thrown during iteration or by
         * the predicate are relayed to the caller.
         * 1.8新增方法:提供了接口默认实现,移除集合内所有匹配规则的元素,支持Lambda表达式
         */
        default boolean removeIf(Predicate<? super E> filter) {
            //空指针校验
            Objects.requireNonNull(filter);
            //注意:JDK官方推荐的遍历方式还是Iterator,虽然forEach是直接用for循环
            boolean removed = false;
            final Iterator<E> each = iterator();
            while (each.hasNext()) {
                if (filter.test(each.next())) {
                    each.remove();//移除元素必须选用Iterator.remove()方法
                    removed = true;//一旦有一个移除成功,就返回true
                }
            }
            //这里补充一下:由于一旦出现移除失败将抛出异常,因此返回false指的仅仅是没有匹配到任何元素而不是运行异常
            return removed;
        }
    }
    public interface Iterable<T>{
    .....
        //1.8新增方法:提供了接口默认实现,用于遍历集合
        default void forEach(Consumer<? super T> action) {
            Objects.requireNonNull(action);
            for (T t : this) {
                action.accept(t);
            }
        }
        //1.8新增方法:提供了接口默认实现,返回分片迭代器
        default Spliterator<T> spliterator() {
            return Spliterators.spliteratorUnknownSize(iterator(), 0);
        }
    }
    public interface List<E> extends Collection<E> {
        //1.8新增方法:提供了接口默认实现,用于对集合进行排序,主要是方便Lambda表达式
        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);
            }
        }
        //1.8新增方法:提供了接口默认实现,支持批量删除,主要是方便Lambda表达式
        default void replaceAll(UnaryOperator<E> operator) {
            Objects.requireNonNull(operator);
            final ListIterator<E> li = this.listIterator();
            while (li.hasNext()) {
                li.set(operator.apply(li.next()));
            }
        }
        /**
         * 1.8新增方法:返回ListIterator实例对象 
         * 1.8专门为List提供了专门的ListIterator,相比于Iterator主要有以下增强:
         *     1.ListIterator新增hasPrevious()和previous()方法,从而可以实现逆向遍历
         *     2.ListIterator新增nextIndex()和previousIndex()方法,增强了其索引定位的能力
         *     3.ListIterator新增set()方法,可以实现对象的修改
         *     4.ListIterator新增add()方法,可以向List中添加对象
         */
        ListIterator<E> listIterator();
    }

2.构造方法变化

/**
  * Constructs an empty list with an initial capacity of ten.
  * 1.8版的默认构造器,只会初始化一个空数组
  */
public ArrayList() {
    super();
    this.elementData = EMPTY_ELEMENTDATA;//初始化一个空数组
}
/**
  * Constructs an empty list with an initial capacity of ten.
  * 1.7版的默认构造器,会直接初始化一个10容量的数组
  */
public ArrayList() {
    this(10);
}

构造方法最大的改变就是变成懒加载了,当你调用add方法的时候才会真正分配数组的内存。

3.增加foreach

/**
  * Performs the given action for each element of the {@code Iterable}
  * until all elements have been processed or the action throws an
  * exception.  Unless otherwise specified by the implementing class,
  * actions are performed in the order of iteration (if an iteration order
  * is specified).  Exceptions thrown by the action are relayed to the
  * caller.
  * 1.8新增方法,重写Iterable接口的forEach方法
  * 提供对数组的遍历操作,由于支持Consumer因此在遍历时将执行传入的方法
  */
@Override
public void forEach(Consumer<? super E> action) {
    Objects.requireNonNull(action);
    final int expectedModCount = modCount;
    @SuppressWarnings("unchecked")
    final E[] elementData = (E[]) this.elementData;
    final int size = this.size;
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        action.accept(elementData[i]);//执行传入的自定义方法
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
}

4.增加removeIf

/**
  * Removes all of the elements of this collection that satisfy the given
  * predicate.  Errors or runtime exceptions thrown during iteration or by
  * the predicate are relayed to the caller.
  * 1.8新增方法,重写Collection接口的removeIf方法
  * 移除集合内所有复合匹配条件的元素,迭代时报错会抛出异常 或 把断言传递给调用者(即断言中断)
  * 该方法主要干了两件事情:
  *     1.根据匹配规则找到所有符合要求的元素
  *     2.移除元素并转移剩余元素位置
  * 补充:为了安全和快速,removeIf分成两步走,而不是直接找到就执行删除和转移操作,写法值得借鉴
  */
@Override
public boolean removeIf(Predicate<? super E> filter) {
    Objects.requireNonNull(filter);
    // figure out which elements are to be removed any exception thrown from
    // the filter predicate at this stage will leave the collection unmodified
    int removeCount = 0;
    //BitSet用于按位存储,这里用作存储待移除元素(即符合匹配规则的元素)
    //BitSet能够通过位图算法大幅减少数据占用存储空间和内存,尤其适合在海量数据方面,这里是个很明显的优化
    //有机会会在基础番中解析一下BitSet的奇妙之处
    final BitSet removeSet = new BitSet(size);
    final int expectedModCount = modCount;
    final int size = this.size;
    //每次循环都要判断modCount == expectedModCount!
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        @SuppressWarnings("unchecked")
        final E element = (E) elementData[i];
        if (filter.test(element)) {
            removeSet.set(i);
            removeCount++;
        }
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
    // shift surviving elements left over the spaces left by removed elements
    // 当有元素被移除,需要对剩余元素进行位移
    final boolean anyToRemove = removeCount > 0;
    if (anyToRemove) {
        final int newSize = size - removeCount;
        for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
            i = removeSet.nextClearBit(i);
            elementData[j] = elementData[i];
        }
        for (int k=newSize; k < size; k++) {
            elementData[k] = null;  // Let gc do its work
        }
        this.size = newSize;
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
        modCount++;
    }
    //正常情况下,一旦匹配到元素,应该删除成功,否则将抛出异常,当没有匹配到任何元素时,返回false
    return anyToRemove;
}

5.增加removeAll

/**
  * Replaces each element of this list with the result of applying the operator to that element.
  * Errors or runtime exceptions thrown by the operator are relayed to the caller.
  * 1.8新增方法,重写List接口的replaceAll方法
  * 提供支持一元操作的批量替换功能
  */
@Override
@SuppressWarnings("unchecked")
public void replaceAll(UnaryOperator<E> operator) {
    Objects.requireNonNull(operator);
    final int expectedModCount = modCount;
    final int size = this.size;
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        elementData[i] = operator.apply((E) elementData[i]);
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
    modCount++;
}

6.增加sort

/**
  * Sorts this list according to the order induced by the specified
  * 1.8新增方法,重写List接口的sort方法
  * 支持对数组进行排序,主要方便于Lambda表达式
  */
@Override
@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c) {
    final int expectedModCount = modCount;
    //Arrays.sort底层是结合归并排序和插入排序的混合排序算法,有不错的性能
    //有机会在基础番对Timsort(1.8版)和ComparableTimSort(1.7版)进行解析
    Arrays.sort((E[]) elementData, 0, size, c);
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
    modCount++;
}

参考地址
集合番@ArrayList一文通(1.8版)

相关文章

  • Java 8 ArrayList新特性

    引言: 今天主要分析一下Java 8版本中java.util.ArrayList集合类有何变化。 变化: 1.上层...

  • Java11的新特性

    Java语言特性系列 Java5的新特性 Java6的新特性 Java7的新特性 Java8的新特性 Java9的...

  • Java15的新特性

    Java语言特性系列 Java5的新特性 Java6的新特性 Java7的新特性 Java8的新特性 Java9的...

  • Java12的新特性

    Java语言特性系列 Java5的新特性 Java6的新特性 Java7的新特性 Java8的新特性 Java9的...

  • Java 8 新特性——检视阅读

    Java 8 新特性——检视阅读 参考 Java 8 新特性——菜鸟 Oracle 公司于 2014 年 3 月 ...

  • Java 8 新特性——实践篇

    Java 8 新特性——实践篇 参考Java8新特性[https://www.bilibili.com/video...

  • 关于java8的学习(一)

    Java 8 新特性 官网java8介绍地址菜鸟教程关于java8的介绍 Java 8 里面加了很多的新特性,在这...

  • Java 8 新特性

    Java 8 新特性 声明:java8新特性系列为个人学习笔记,参考地址点击这里,侵删!! Java 8 (又称为...

  • Java发展历史

    Java8新特性:

  • Java8 新特性

    Java8新特性

网友评论

      本文标题:Java 8 ArrayList新特性

      本文链接:https://www.haomeiwen.com/subject/yytaictx.html