资讯专栏INFORMATION COLUMN

Java容器类研究2:List

zzzmh / 1982人阅读

摘要:在中引入该方法,用来替换中的每个元素。的方法,只能在或之后使用,也就是确保当前指向了一个存在的项。这里使用了,该方法可以将非对象先映射为型,然后进行比较。存储的是有序的数组,所以划分时会按照顺序进行划分。

java.util.List

replaceAll

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

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

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

public class Ripper {
    public static void main(String[] args) {
        List 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 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型,然后进行比较。

具体实现:

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

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

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

public class Ripper {
    int value;

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

    public static void main(String[] args) {
        List 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 spliterator() {
        return Spliterators.spliterator(this, Spliterator.ORDERED);
    }

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67707.html

相关文章

  • Java 基础 | Collection 集合概览

    摘要:说到复盘基础,并不是所有的都会复盘,没那个时间更没那个必要。比如,一些基础的语法以及条件语句,极度简单。思前想后,我觉得整个计划应该从集合开始,而复盘的方式就是读源码。通常,队列不允许随机访问队列中的元素。 ​showImg(https://segmentfault.com/img/remote/1460000020029737?w=1080&h=711); 老读者都知道,我是自学转行...

    codergarden 评论0 收藏0
  • Java容器研究1:Collection

    摘要:集合类关系是和的父接口。相等必须是对称的,约定只能和其它相等,亦然。和接口在中引入,这个单词是和的合成,用来分割集合以给并行处理提供方便。这些并不立即执行,而是等到最后一个函数,统一执行。 集合类关系: Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set Map ...

    AprilJ 评论0 收藏0
  • Java容器研究4:ArrayList

    摘要:显然,开发人员认为通过下标遍历的数组结构更加高效。在进行分裂时,原始保留中部至末尾的元素,新的保留原起始位置到中部的元素。同样,也会进行重新赋值,使得在使用前与保持一致。在遍历时,会调用方法,将动作施加于元素之上。 java.util.ArrayList ArrayList继承自AbstractList,AbstractList为随机访问数据的结构,如数组提供了基本实现,并且提供了It...

    xfee 评论0 收藏0
  • Java容器研究5:LinkedList

    摘要:提供了顺序访问的方法,当然,大部分方法都依赖于来实现,所以将锅甩给了子类。实现了自己的遍历方法利用了链表结构的特性,进行遍历。其中有如下属性记录遍历状态。该方法位于中到数组中这里返回的不是,其实是 java.util.LinkedList Java中有现成的队列可以用吗 有,就是LinkedList。LinkedList实现的接口如下,其实也可以当做stack使用: public cl...

    frank_fun 评论0 收藏0
  • 容器之Collection、Iterable、List、Vector(Stack)分析(三)

    摘要:容器相关的操作及其源码分析说明本文是基于分析的。通常,我们通过迭代器来遍历集合。是接口所特有的,在接口中,通过返回一个对象。为了偷懒啊,底层使用了迭代器。即返回的和原在元素上保持一致,但不可修改。 容器相关的操作及其源码分析 说明 1、本文是基于JDK 7 分析的。JDK 8 待我工作了得好好研究下。Lambda、Stream。 2、本文会贴出大量的官方注释文档,强迫自己学英语,篇幅...

    liaosilzu2007 评论0 收藏0

发表评论

0条评论

zzzmh

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<