jdk1.8包含的常用集合工具类,一般包括两个:
数组工具类:`java.util.Arrays `
结合工具类:`java.util.Collections`

今天就结合源码对`java.util.Arrays `的功能进行总结说明。

1、排序方法 `sort`


  • 8种基本类型数组排序

方法直接调用`java.util.DualPivotQuicksort`(双轴快速排序类)的相关方法进行排序。
而在该类的内部,又根据数组的大小和有序性的好坏,选择适合的排序算法。比如数组小于指定阈值,则采用使用双轴快排,如果顺序连续性好,直接使用TimSort算法,顺序连续性不好的数组直接使用了 双轴快排 + 成对插入排序。具体过程本文不叙述。可以参考:

双轴排序

  • object[]数组排序

对对象类型的数组的排序,其过程又有别于基本类型,jdk会借助于参数:LegacyMergeSort.userRequested
进行排序算法的选择,如果开启,那么采用传统的归并排序,否则采用[TimSort]的算法。

  • 并行排序方法`parallelSort`

parallelsort会把array分成不同的子数组,每个子数组用sort进行排序,最后再合并排序;整个过程用ForkJoin 
common pool(java.util.concurrent.ForkJoinPool)进行并发操作

2、并行累积方法`parallelPrefix`


使用提供的函数并行累积给定数组中的每个元素。例如,如果数组最初保存[2, 1, 0, 3]并且操作执行加法,则返回时数组成立[2, 3, 3, 6]。并行前缀计算通常比大型数组的顺序循环更有效。

    public static int[] intArrays ={55,45,23,11,10,88,102,99};

    public static void parallelPrefix(){

        System.out.println("*******调用前*******");
System.out.println(Arrays.toString(intArrays)); Arrays.parallelPrefix(intArrays,(x,y)->(x+y)); System.out.println("*******调用后*******");
System.out.println(Arrays.toString(intArrays));
}
 *******排序前*******
[55, 45, 23, 11, 10, 88, 102, 99]
*******排序后*******
[55, 100, 123, 134, 144, 232, 334, 433]
55=55
100=55+45
123=55+45+23
...
433=55+...+99

3、二叉查找`binarySearch`


在已排序数组中,找出指定值的元素所在的位置(如果为正数,返回从0开始的index,如果为负数,其绝对值-1为所找key最近的数组元素)。

     private static int binarySearch0(int[] a, int fromIndex, int toIndex,
int key) {
int low = fromIndex;
int high = toIndex - 1; while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = a[mid]; if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}

4、相等性判断`equals`


数组等于比较,过程相对简单:

     public static boolean equals(int[] a, int[] a2) {
//同一个对象,即引用地址一样
if (a==a2)
return true;
//一个为null
if (a==null || a2==null)
return false;
//长度不等,直接返回
int length = a.length;
if (a2.length != length)
return false;
//每个元素比较,有不同就返回
for (int i=0; i<length; i++)
if (a[i] != a2[i])
return false; return true;
}

5、批量赋值`fill`


填充数据指定或者全部位置的值为指定值,相对简单。

     public static void fill(long[] a, long val) {
for (int i = 0, len = a.length; i < len; i++)
a[i] = val;
}

6、复制`copyOf`


对数组元素进行复制,其中返回的是一个新的数组,但是数组元素还是对原先数组堆对象的引用(即元素浅复制)。
该方法底层调用的是native方法,进行快速复制:`system.arraycopy`

 //测试示例
ArraysDemo[] demos ={new ArraysDemo("a"),new ArraysDemo("b"),new ArraysDemo("c"),new ArraysDemo("d"),new ArraysDemo("e")}; ArraysDemo[] newDemos = Arrays.copyOf(demos,demos.length); //数组对象深复制 返回false
System.out.println(demos==newDemos);
//数组元素浅复制,元素引用的还是同一个地址,返回true
System.out.println(demos[1]==newDemos[1]); newDemos[0] = new ArraysDemo("f");
//地址改变 返回false
System.out.println(demos[0]==newDemos[0]);
//元素内容改变
newDemos[1].setClassVer("bb");
//原始对象同时改变 打印bb
System.out.println(demos[1].getClassVer());

7、范围复制`copyOfRange`


数组的局部复制,最终调用6的copyOf方法。

8、返回集合`asList`


返回Arrays内部类ArrayList<>对象

private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable

相比较于java.util.ArrayList,缺少List接口的相关方法。

``` public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable

所以List接口的相关方法无法调用。正如《阿里巴巴java开发规约》所描述的:

使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportedOperationException异常。
asList的返回对象是一个Arrays内部类,并没有实现集合的修改方法,只是转换接口,后台数据仍旧是数组。

     public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
} //测试,异常 UnsupportedOperationException
List list = Arrays.asList(intArrays);
list.add(2);

其实asList内部是调用了抽闲类AbstractList的add方法,但内部类并没有重载实现。
所以:

     public void add(int index, E element) {
throw new UnsupportedOperationException();
}

9、hash计算`hashCode`


获取数组的hashcode,其内部是数组元素的hashcode的拼装,根据类型不同又有不同的拼装方式。

10、并行遍历迭代器`spliterator`


Spliterator可以理解为Iterator的Split版本(但用途要丰富很多)。使用Iterator的时候,我们可以顺序地遍历容器中的元素,使用Spliterator的时候,我们可以将元素分割成多份,分别交于不于的线程去遍历,以提高效率。使用 Spliterator 每次可以处理某个元素集合中的一个元素 — 不是从 Spliterator 中获取元素,而是使用 tryAdvance() 或 forEachRemaining() 方法对元素应用操作。但Spliterator 还可以用于估计其中保存的元素数量,而且还可以像细胞分裂一样变为一分为二。这些新增加的能力让流并行处理代码可以很方便地将工作分布到多个可用线程上完成。

11、流式处理`stream`


     public static void stream(){
String [] strArray = new String[] {"a", "b", "c","d"}; //过滤操作,过滤掉为a的字符串
List afterFilterLists =Arrays.stream(strArray).filter(s -> !s.equals("a"))
.collect(Collectors.toList()); System.out.println(afterFilterLists);
//输出[b, c, d] //foreach操作 输出 a b c d
Arrays.stream(strArray).forEach(s-> System.out.println(s)); }

JDK1.8源码泛读之Arrays的更多相关文章

  1. JDK1.8源码(四)——java.util.Arrays类

    一.概述 1.介绍 Arrays 类是 JDK1.2 提供的一个工具类,提供处理数组的各种方法,基本上都是静态方法,能直接通过类名Arrays调用. 二.类源码 1.asList()方法 将一个泛型数 ...

  2. 【集合框架】JDK1.8源码分析之Collections && Arrays(十)

    一.前言 整个集合框架的常用类我们已经分析完成了,但是还有两个工具类我们还没有进行分析.可以说,这两个工具类对于我们操作集合时相当有用,下面进行分析. 二.Collections源码分析 2.1 类的 ...

  3. JDK1.8源码(四)——java.util.Arrays 类

    java.util.Arrays 类是 JDK 提供的一个工具类,用来处理数组的各种方法,而且每个方法基本上都是静态方法,能直接通过类名Arrays调用. 1.asList public static ...

  4. AQS源码泛读,梳理设计流程(jdk8)

    一.AQS介绍 AQS(AbstractQueuedSynchronizer)抽象队列同步器,属于多线程编程的基本工具:JDK对其定义得很详细,并提供了多种常用的工具类(重入锁,读写锁,信号量,Cyc ...

  5. JDK1.8源码学习-String

    JDK1.8源码学习-String 目录 一.String简介 String类是Java中最常用的类之一,所有字符串的字面量都是String类的实例,字符串是常量,在定义之后不能被改变. 二.定义 p ...

  6. 【JUC】JDK1.8源码分析之ArrayBlockingQueue(三)

    一.前言 在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看Arra ...

  7. JDK1.8源码阅读系列之三:Vector

    本篇随笔主要描述的是我阅读 Vector 源码期间的对于 Vector 的一些实现上的个人理解,用于个人备忘,有不对的地方,请指出- 先来看一下 Vector 的继承图: 可以看出,Vector 的直 ...

  8. 【集合框架】JDK1.8源码分析之ArrayList详解(一)

    [集合框架]JDK1.8源码分析之ArrayList详解(一) 一. 从ArrayList字表面推测 ArrayList类的命名是由Array和List单词组合而成,Array的中文意思是数组,Lis ...

  9. 【1】【JUC】JDK1.8源码分析之ArrayBlockingQueue,LinkedBlockingQueue

    概要: ArrayBlockingQueue的内部是通过一个可重入锁ReentrantLock和两个Condition条件对象来实现阻塞 注意这两个Condition即ReentrantLock的Co ...

随机推荐

  1. bzoj [POI2005]Kos-Dicing 二分+网络流

    [POI2005]Kos-Dicing Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1835  Solved: 661[Submit][Status][ ...

  2. ACM3018欧拉回路

    欧拉回路 欧拉回路:图G,若存在一条路,经过G中每条边有且仅有一次,称这条路为欧拉路,如果存在一条回路经过G每条边有且仅有一次, 称这条回路为欧拉回路.具有欧拉回路的图成为欧拉图. 判断欧拉路是否存在 ...

  3. 分别利用并查集,DFS和BFS方法求联通块的数量

    联通块是指给定n个点,输入a,b(1<=a,b<=n),然后将a,b连接,凡是连接在一起的所有数就是一个联通块: 题意:第一行输入n,m,分别表示有n个数,有输入m对连接点,以下将要输入m ...

  4. HRBUST 1819

    石子合并问题--圆形版 Time Limit: 1000 MS Memory Limit: 32768 K Total Submit: 61(27 users) Total Accepted: 26( ...

  5. 隐藏Nginx版本号

    一般来说,黑客攻击服务器的首要步骤就是收集信息,比如说你的软件版本,这些将成为下一步有针对性攻击的依据.所以说一定程度的隐藏这些信息就显得非常有必要了,本文将简单介绍如何在网络上隐藏Nginx版本号以 ...

  6. Linux目录结构nginx

    alias 别名( 永久 ) 1.vim /root/.bashrc 2. alias vimens33='vim /etc/sysconfig/network-scripts/ifcfg-ens33 ...

  7. Sass 基本特性-运算 感觉满满都是坑

    Sass中的基本运算 一.加法 在 CSS 中能做运算的,到目前为止仅有 calc() 函数可行.但在 Sass 中,运算只是其基本特性之一.      sass做加法运算是可以不考虑参数带单位,但需 ...

  8. onCreateView的一个细节--Fragment

    public View onCreateView(LayoutInflater inflater, ViewGroup contaiiner, Bundle savedInstanceState) 在 ...

  9. 【bzoj3648】环套树+点分治+树状数组

    tree 1s 128M  by hzw czy神犇种了一棵树,他想知道地球的质量 给定一棵n个点的树,求树上经过点的个数≥K的路径数量ans 对于部分数据,树上某两点间会多出最多一条无向边 输入数据 ...

  10. 【bzoj3376-方块游戏】带权并查集

    题意: n块积木,m个操作或询问.每次移动积木的时候,约翰会选择两块积木X,Y,把X搬到Y的上方.如果X已经和其它积木叠在一起了,那么应将这叠积木整体移动到Y的上方:如果Y已经和其它积木叠在一起了的, ...