前言

数组比较特殊,一个数组属于一个对象,但是它的创建方式却不同于一般对象。

Java中的数组创建数组有以下三种方式:

// 第一种
int[] array = new int[5];
// 第二种
int[] array = {1, 2, 3, 4, 5};
// 第三种
int[] array = new int[]{1, 2, 3, 4, 5};

判断数组是否属于一个对象可使用下列语句:

System.out.println(new int[2] instanceof Object);

源码分析

接下来我们就来看一下对数据进行操作的工具类Arrays。

Arrays源代码看似很多,其实核心方法只有几个,Arrays给每种数据类型都提供了方法。

sort()

sort()方法有两种实现。第一种使用双轴快速排序算法。

public static void sort(int[] a, int fromIndex, int toIndex) {rangeCheck(a.length, fromIndex, toIndex);DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
}

第二种根据系统属性设置使用旧的归并排序算法或者带比较的分区排序算法。

public static void sort(Object[] a, int fromIndex, int toIndex) {rangeCheck(a.length, fromIndex, toIndex);if (LegacyMergeSort.userRequested)legacyMergeSort(a, fromIndex, toIndex);elseComparableTimSort.sort(a, fromIndex, toIndex, null, 0, 0);
}

parallelSort()

parallelSort()是Java8新增的并行排序算法,基于fork/join框架。PS:Fork/Join框架是Java7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。

public static void parallelSort(int[] a, int fromIndex, int toIndex) {rangeCheck(a.length, fromIndex, toIndex);int n = toIndex - fromIndex, p, g;if (n <= MIN_ARRAY_SORT_GRAN ||(p = ForkJoinPool.getCommonPoolParallelism()) == 1)DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);elsenew ArraysParallelSortHelpers.FJInt.Sorter(null, a, new int[n], fromIndex, n, 0,((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?MIN_ARRAY_SORT_GRAN : g).invoke();
}

ArraysParallelSortHelpers类中源码有些复杂,就先不探究它了。我们来比较一下sort()和parallelSort()的性能。从数组长度10开始,到长度100000000,打印俩个闹钟功能排序消耗的时间。

public static void main(String[] args) {for (int i = 10; i <= 100000000; i *= 10) {test(i);}
}static void test(int limit) {IntStream intStream = new Random().ints(limit);int[] arr1 = intStream.toArray();int[] arr2 = Arrays.copyOf(arr1, arr1.length);long t1 = System.currentTimeMillis();Arrays.sort(arr1);long t2 = System.currentTimeMillis();Arrays.parallelSort(arr2);long t3 = System.currentTimeMillis();System.out.println("数组长度:" + limit + "\tsort:" + (t2 - t1) + "ms\tparallelSort:" + (t3 - t2) + "ms");
}

输出结果:

数组长度:10   sort:1ms parallelSort:0ms
数组长度:100 sort:0ms parallelSort:0ms
数组长度:1000    sort:0ms parallelSort:1ms
数组长度:10000   sort:3ms parallelSort:10ms
数组长度:100000  sort:16ms    parallelSort:22ms
数组长度:1000000 sort:105ms   parallelSort:48ms
数组长度:10000000    sort:1235ms  parallelSort:412ms
数组长度:100000000   sort:10194ms parallelSort:4820ms

可以看出,从长度1000000开始,并行排序消耗的时间比串行排序消耗的时间变短。所以,在一般情况下,使用sort()方法即可,当数组长度很大时,使用parallelSort()方法。

parallelPrefix()

串行计算数组累加值。

public static <T> void parallelPrefix(T[] array, BinaryOperator<T> op) {Objects.requireNonNull(op);if (array.length > 0)new ArrayPrefixHelpers.CumulateTask<>(null, op, array, 0, array.length).invoke();
}

binarySearch()

二分查找。使用的前提是数组是已经从小到大排好序的。

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

equals()

判断两个数组是否相等,包括基本类型、对象的判等。基本类型的判等就是先判断结构上是否相等,然后调用ArraysSupport类的mismatch()方法判断内容的相等性。

public static boolean equals(long[] a, long[] a2) {if (a==a2)return true;if (a==null || a2==null)return false;int length = a.length;if (a2.length != length)return false;return ArraysSupport.mismatch(a, a2, length) < 0;
}

fill()

填充。

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

copyOf()和copyOfRange()

复制和复制指定范围。

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {@SuppressWarnings("unchecked")T[] copy = ((Object)newType == (Object)Object[].class)? (T[]) new Object[newLength]: (T[]) Array.newInstance(newType.getComponentType(), newLength);System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));return copy;
}public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) {int newLength = to - from;if (newLength < 0)throw new IllegalArgumentException(from + " > " + to);@SuppressWarnings("unchecked")T[] copy = ((Object)newType == (Object)Object[].class)? (T[]) new Object[newLength]: (T[]) Array.newInstance(newType.getComponentType(), newLength);System.arraycopy(original, from, copy, 0,Math.min(original.length - from, newLength));return copy;
}

asList()

返回List。这里返回的ArrayList是Arrays中的一个静态内部类。

public static <T> List<T> asList(T... a) {return new ArrayList<>(a);
}

hashCode()

返回哈希值。

public static int hashCode(long a[]) {if (a == null)return 0;int result = 1;for (long element : a) {int elementHash = (int)(element ^ (element >>> 32));result = 31 * result + elementHash;}return result;
}

toString()

返回字符串。

public static String toString(long[] a) {if (a == null)return "null";int iMax = a.length - 1;if (iMax == -1)return "[]";StringBuilder b = new StringBuilder();b.append('[');for (int i = 0; ; i++) {b.append(a[i]);if (i == iMax)return b.append(']').toString();b.append(", ");}
}

Java 源码--Arrays相关推荐

  1. 深入学习java源码之 Arrays.sort()与Arrays.parallelPrefix()

    深入学习java源码之 Arrays.sort()与Arrays.parallelPrefix() Comparator接口 能对不同类型的对象进行排序(当然排序依据还是基本类型),也不用自己实现排序 ...

  2. Java源码详解五:ArrayList源码分析--openjdk java 11源码

    文章目录 注释 类的继承与实现 构造函数 add操作 扩容函数 remove函数 subList函数 总结 本系列是Java详解,专栏地址:Java源码分析 ArrayList 官方文档:ArrayL ...

  3. Java源码阅读之String(4)

    Java源码阅读之String(4) 这一篇博客主要阅读String类的查找和替换相关的方法. /**查询当前对象的哈希码,如果当前对象没有计算过哈希码*则计算当前对象的哈希码并赋值给当前对象的has ...

  4. 【java集合框架源码剖析系列】java源码剖析之java集合中的折半插入排序算法

    注:关于排序算法,博主写过[数据结构排序算法系列]数据结构八大排序算法,基本上把所有的排序算法都详细的讲解过,而之所以单独将java集合中的排序算法拿出来讲解,是因为在阿里巴巴内推面试的时候面试官问过 ...

  5. Java源码之从零单排--ArrayList

    Java源码之从零单排–ArrayList 为什么取名从零单排呢?因为我喜欢打Dota,刚出天梯排名的那会儿,各路大神都开始做从零单排视频(好像是09先做的吧).这里我取名从零单排只是想告诉自己这是一 ...

  6. java源码之Vector(jdk8)

    java源码之Vector 前言 集成关系 源码 成员变量 elementData elementCount capacityIncrement MAX_ARRAY_SIZE 构造函数 Vector( ...

  7. java源码详解——String类

    java源码详解--String类目录: Java String 类 下面开始介绍主要方法: Java charAt() 方法 Java compareTo() 方法 int compareTo(St ...

  8. Java源码阅读学习后的浅析和感悟(JDK篇)(持续更新)

    目录 Java源码阅读学习后的浅析和感悟(JKD篇) - 为什么阅读源码 集合框架类 - 为什么会要引入集合 - 集合结构图(部分) ArrayList集合源码分析 - 扩容机制 - 关键方法解释(D ...

  9. Java源码安全审查

    Java源码安全审查 最近业务需要出一份Java Web应用源码安全审查报告, 对比了市面上数种工具及其分析结果, 基于结果总结了一份规则库. 本文目录结构如下: 检测工具 FindSecurityB ...

最新文章

  1. Spring学习(23)--- AOP之Introductions应用
  2. LeetCode-Unique Binary Search Trees
  3. PostgreSQL和Kingbase中设置search_path
  4. docker环境给elasticsearch安装ik分词
  5. python venv windows7_安装 Python、pip 和 venv
  6. Leetcode 1. 两数之和 (Python版)
  7. msys2安装gcc、g++编译器
  8. bfo java_Java操作PDF文件(BFO) | 学步园
  9. 留个脚印,证明我来过~!
  10. Wifidog 认证
  11. 微信公众号开发之消息的自动回复
  12. mysql 误删除数据恢复
  13. 怎么让背景铺满整个页面_css新手教程之背景图充满整个屏幕
  14. 抽样中误差的相关概念和种类
  15. vb如何测试连接mysql_测试是否和数据库连接成功! vbCode
  16. BI工具对比|Smartbi与亿信ABI两款BI数据看板软件对比
  17. 那么厉害的个人所得税计算器代码你竟然不点开看看,你膨胀了!
  18. 为什么静态成员函数可以访问私有成员变量?(访问控制是针对类而不是针对对象)
  19. 职场必备技之二阶堂红丸
  20. 阿里国际站年底询盘分析总结方法及步骤详解

热门文章

  1. 台式计算机技术方案,2017年4月自考02316计算机应用技术真题及答案
  2. 关于细分到字段的权限系统_操作系统中的细分
  3. linux sublime nodejs,Ubuntu环境下sublime3 nodejs安装与插件配置
  4. ruby中!!_Ruby反向! 功能
  5. Java PrintWriter close()方法与示例
  6. ruby 数组元素替换_从Ruby中的集合中删除并替换元素
  7. python 程序耗时记录_Python学校的学生身高记录程序
  8. 磊哥私藏书单分享,160买400的书!
  9. 重磅!阿里推出国产开源JDK!
  10. 厉害了,3万字的MySQL精华总结 + 面试100问!