博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
List,Collection,Iterable源码简单分析
阅读量:4603 次
发布时间:2019-06-09

本文共 6497 字,大约阅读时间需要 21 分钟。

  集合是个庞大的家族。层次关系如下:(图片取自:https://www.cnblogs.com/leeplogs/p/5891861.html)

     

 

  经常用List集合来存取数据,底层代码是怎么写的呢,开始看看,简单分析一下。

  

public interface List
extends Collection
{}

  List是个泛型接口,继承Collection,看一下Collection。

public interface Collection
extends Iterable
{}

Collection继承Iterable<E>。

一、Iterable

Iterable<T>接口的作用呢,也就是继承了Iterable类的接口或者类都可以进行 “foreach”来循环遍历。看一下Iterable的源码。

public interface Iterable
{
//1 Iterator
iterator(); //2 default void forEach(Consumer
action) {
Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } //3 default Spliterator
spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); }}

其中API如下:

1.  返回类型为 T元素的迭代器。

2.  对Iterable的每个元素执行给定的操作,直到所有元素都被处理或动作引发异常。 除非实现类另有规定,否则按照迭代的顺序执行操作(如果指定了迭代顺序)。 动作抛出的异常被转发给呼叫者。

3.  在的元素上创建一个Iterable 。百度一下Spliterator是java8中的新的迭代器,具体以后Spliterator单独分析。(没看懂...)

注:JDK1.8中为了加强接口的能力,使得接口可以存在具体的方法,前提是方法需要被default或static关键字所修饰,接口可以有一些默认的方法。

二、Collection(集合)

 

package java.util;

 

import java.util.function.Predicate;

import java.util.stream.Stream;
import java.util.stream.StreamSupport;

public interface Collection
extends Iterable
{ int size(); boolean isEmpty(); boolean contains(Object o); Iterator
iterator(); Object[] toArray();
T[] toArray(T[] a); boolean add(E e); boolean remove(Object o); boolean containsAll(Collection
c); boolean addAll(Collection
c); boolean removeAll(Collection
c);  //2 default boolean removeIf(Predicate
filter) { Objects.requireNonNull(filter); boolean removed = false; final Iterator
each = iterator(); while (each.hasNext()) { if (filter.test(each.next())) { each.remove(); removed = true; } } return removed; }  //1 boolean retainAll(Collection
c); void clear(); boolean equals(Object o); int hashCode();  //3 @Override default Spliterator
spliterator() { return Spliterators.spliterator(this, 0); }  //4 default Stream
stream() { return StreamSupport.stream(spliterator(), false); }  //5 default Stream
parallelStream() { return StreamSupport.stream(spliterator(), true); }}

Collection是集合,它相当于可以容纳相同类型的元素的一个容器,提供了存,取,删除容器中元素的方法。

其中大部分方法都是大多数java工程师比较熟悉的方法。具体方法的区别或者重写在具体的实现类中区分。

1.retainAll  这个方法有些陌生。

 这个方法在实现类里有具体的实现。大概意思是   A集合调用该方法,参数传入B集合。

那么 (1).A集合与 A和B的交集相同 ,则返回true,否则返回false。(2).A集合变为A与B的交集。

其中有一些方法是java1.8的新方法:

2.removeIf

描述:删除满足给定谓词的此集合的所有元素,删除了返回true,否则返回false。其中可以Predicate可以用lambda表达式,例如:

Predicate<String> predicateTestOne = value-> value.equals(3);

Predicate<Integer> predicateTestTwo = value-> value > 0;
System.out.println(predicateTestOne.test("12345"));
System.out.println(predicateTestTwo.test(1));

输出true和false。

调用removeIf方法,删除集合中满足条件的元素。

3.spliterator 

4.stream 5.parallelStream

大概是可以将数组通过一些条件来转化为流,或某些功能可以作为流来使用。

java8中的新特性以后单独看书学习。

三、List(有序集合)

List接口继承了Collection接口。以下源码的方法显示不同的部分。

package java.util;import java.util.function.UnaryOperator;public interface List
extends Collection
{
  .......................   .......................
  //在集合中指定位置插入一个集合   boolean addAll(int index, Collection
c);   

    default void replaceAll(UnaryOperator<E> operator) {

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

  

    @SuppressWarnings({"unchecked", "rawtypes"})

    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);
      }
    }

   E get(int index);         E set(int index, E element);        void add(int index, E element);     E remove(int index);
    int indexOf(Object o);      int lastIndexOf(Object o);       ListIterator
listIterator();    ListIterator
listIterator(int index);         List
subList(int fromIndex, int toIndex);

    @Override

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

}

 List是有序集合(又称为序列);

 List可以精确的控制每个元素的位置,包括插入,搜索,移除等。

 List允许重复的元素,允许有多个空元素。
 List接口提供 ListIterator这个特殊的迭代器,来进行元素的插入和更换。

其中有些特殊的陌生的方法如下:

1.replaceAll   将该列表的每个元素替换为将该运算符应用于该元素的结果。方法很简单,就是利用ListIterator迭代器循环遍历进行修改值。其中涉及了UnaryOperator这个接口,这个接口的中文翻译为是一元运算符。继承了Function接口。

可以使用lambda表达式的例子来简单说明。

List
testOne = new ArrayList<>();testOne.add(2);testOne.add(3);testOne.replaceAll(t -> t + 2);System.out.println(testOne);

输出 [4,5].

2.sort   根据Comparator中的排序规则重新排序该集合。

关键代码

Arrays.sort(a, (Comparator) c);

下面来一点儿一点儿分析代码的执行逻辑。

public class Arrays {
...   public static
void sort(T[] a, Comparator
c) { if (c == null) {
        //(1) sort(a); } else {
       //(2) if (LegacyMergeSort.userRequested)        //(3) legacyMergeSort(a, c); else        //(4) TimSort.sort(a, 0, a.length, c, null, 0, 0); } } ... }

如果比较器为空,则进行(1),如下:

public static void sort(Object[] a) {
  //(2) if (LegacyMergeSort.userRequested)   //(5) legacyMergeSort(a); else   //(6) ComparableTimSort.sort(a, 0, a.length, null, 0, 0);//java8} private static void legacyMergeSort(Object[] a) {
  Object[] aux = a.clone();

   mergeSort(aux, a, 0, a.length, 0);

}

 

接下来判断(2)中的表达式,LegacyMergeSort是内部类(将来会废除的类)。

static final class LegacyMergeSort {        private static final boolean userRequested =            java.security.AccessController.doPrivileged(                new sun.security.action.GetBooleanAction(                    "java.util.Arrays.useLegacyMergeSort")).booleanValue();    }

其中的含义具体参考了API注释和博客 。

   

    但是怎么控制是否使用老版,还是jdk1.8新的排序,以及设置参数的意义,以及其中AccessController.doPrivileged的安全检查在开发中的意义还是没有理解。表达式为true执行legacyMergeSort()进行归并排序或者为false执行java8中新提供的ComparableTimSort.sort()来采用优化更好的归并排序算法进行排序。

    所以有序集合的sort()方法参数为null的话,默认用归并算法进行正序排列。如果sort()中的参数不为空,则按照Comparator比较器中的规则来进行排序。

转载于:https://www.cnblogs.com/LiNai-home/p/11150792.html

你可能感兴趣的文章
<五>初探opengl,编写我们的镜头
查看>>
大数据操作:删除和去重
查看>>
C# 程序集
查看>>
《那些年啊,那些事——一个程序员的奋斗史》——28
查看>>
2、JDBC-CURD
查看>>
【C语言零碎知识点】变量的存储类型
查看>>
编程时 对 用途这个字段定义时 不要用using 这个英文
查看>>
剑指offer-从尾到头打印链表
查看>>
poj3517 And Then There Was One
查看>>
Redis集群部署
查看>>
[Jobdu] 题目1373:整数中1出现的次数(从1到n整数中1出现的次数)
查看>>
【剑指offer】字符串的排列
查看>>
数字变成大写汉字js
查看>>
潭州课堂25班:Ph201805201 django 项目 第二十一课 文章主页 新闻列表页面功能 (课堂笔记)...
查看>>
centos7安装jdk
查看>>
Java中IO对象的输入输出流
查看>>
JQ实现accordion(可折叠)效果
查看>>
javascript方式实现无缝滚动(两种方式)
查看>>
Sumsets(数学)
查看>>
sgu 181 X-Sequence
查看>>