【Java】【常用类】 Arrays工具类 源码学习
虽然在数组的随笔中有说过,但实际上应该仔细深入一下源码进行分析
源码没有想象中的高大上,代码终究还是写给人看的,可读性大于执行性
最小阵列排序:1 乘 2的13次方 = 8192
学识浅薄,暂时还不明白这个常量在数组工具类的意义
通过翻译的介绍,说明这是并行排序最小长度的要求
【并行排序的最小数组长度】
- 算法不会进一步划分排序任务。使用
- 较小的大小通常会导致
- 使并行加速不太可能的任务。
private static final int MIN_ARRAY_SORT_GRAN = 1 << 13;
私有化的构造器,因为是工具类,设计者认为不应该产生实例
【抑制默认构造函数,确保不可实例化。】
// Suppresses default constructor, ensuring non-instantiability.
private Arrays() {}
一个固定的静态内部类 叫自然顺序类
实现了可比较接口,和重写了比较方法,暂时还不知道其中的用意
static final class NaturalOrder implements Comparator<Object> {
@SuppressWarnings("unchecked")
public int compare(Object first, Object second) {
return ((Comparable<Object>)first).compareTo(second);
}
static final NaturalOrder INSTANCE = new NaturalOrder();
}
长度范围检查
设计者认为所有工具方法,都应该先确认一下参数注入的数组的正确性
所以设计了长度检查,如果不符合描述,直接丢异常出去交给调用者处理检查
- 如果起始索引大于截至索引,抛出不合理的参数异常,并指明错误参数
- 如果起始位置小于0,也就是小于第一个元素的位置索引 ,抛出越界异常
- 如果截至位置大于数组的长度 抛出越界异常
/**
* Checks that {@code fromIndex} and {@code toIndex} are in
* the range and throws an exception if they aren't.
*/
private static void rangeCheck(int arrayLength, int fromIndex, int toIndex) {
if (fromIndex > toIndex) {
throw new IllegalArgumentException(
"fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
}
if (fromIndex < 0) {
throw new ArrayIndexOutOfBoundsException(fromIndex);
}
if (toIndex > arrayLength) {
throw new ArrayIndexOutOfBoundsException(toIndex);
}
}
可以看到这个排序调用的是一个名叫【双枢轴快速排序类的排序方法】
只看过快速排序,哪儿见过这算法,打个mark留意一下把,
因为只注入一个数组的参数,所以不需要上面范围检查
public static void sort(int[] a) {
DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}
如果是针对数组的一个片段的排序,这个排序的重载就会调用范围检查
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) {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a);
else
ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
}
/** To be removed in a future release. */
private static void legacyMergeSort(Object[] a) {
Object[] aux = a.clone();
mergeSort(aux, a, 0, a.length, 0);
}
并行排序、又称串行排序,用于多线程相关的排序
看不懂,我太菜了。。。。
备注说明了这个方法是从1.8开始有的
public static void parallelSort(byte[] a) {
int n = a.length, p, g;
if (n <= MIN_ARRAY_SORT_GRAN ||
(p = ForkJoinPool.getCommonPoolParallelism()) == 1)
DualPivotQuicksort.sort(a, 0, n - 1);
else
new ArraysParallelSortHelpers.FJByte.Sorter
(null, a, new byte[n], 0, n, 0,
((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g).invoke();
}
也是配备了基本类型和引用类型的重载

并行前缀方法
跟并行排序配套使用的方法... 依旧不懂
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();
}
对应的类型只有这么几个重载

官方的二分查找,在获取中轴游标时采用的位运算 无符号右移1,也就是除2
// Like public version, but without range checks.
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;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
对应的基本和引用类型的重载

比较两个数组之间是否相同 地址一样 或者 数组的长度和元素都是一样
public static boolean equals(int[] a, int[] a2) {
if (a==a2)
return true;
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;
}
引用类型数组增加了对元素对象的比较
public static boolean equals(Object[] a, Object[] a2) {
if (a==a2)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++) {
Object o1 = a[i];
Object o2 = a2[i];
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
return true;
}
比较的重载

填充数组的重载 ,增加了范围检查设置,可以选数组的一个片段进行填充
public static void fill(long[] a, int fromIndex, int toIndex, long val) {
rangeCheck(a.length, fromIndex, toIndex);
for (int i = fromIndex; i < toIndex; i++)
a[i] = val;
}

复制数组直接调用的是系统类给的
然而系统类的复制方法是调用C++的方法
关于native描述的方法
https://www.cnblogs.com/b3051/p/7484501.html
public static char[] copyOf(char[] original, int newLength) {
char[] copy = new char[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;
}
转换成List集合,List是一个接口,实际上应该是由实现类完成的转换
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
转换成字符串形式
- 空指针打印null
- 如果索引个数,也就是没有元素,返回空
- 使用Buider拼接字符串,遍历到最后返回
还有个深转换的,针对对象设计的方法...
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工具类 源码学习的更多相关文章
- Java常用API——Arrays工具类
介绍:Arrays工具类提供了一些可以直接操作数组的方法,以下是一些常用方法: int binarySearch(type[] a, type key):要求数组a元素升序排列,使用二分法搜索key的 ...
- Java容器类Collection,List,Set,Map.,Iterator,Collections工具类,Arrays工具类,Comparable
Java容器类Collection,List,Set,Map.,Iterator,Collections工具类,Arrays工具类,Comparable接口,泛型 Collection,List,Se ...
- java常用正则校验工具类
正则常用校验工具类 import java.util.regex.Pattern; /** * @program: * @description: 校验工具类 * @author: xujingyan ...
- java 常用Bean 转换工具类
package com.hnf.framework.utils; import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.data ...
- java内置线程池ThreadPoolExecutor源码学习记录
背景 公司业务性能优化,使用java自带的Executors.newFixedThreadPool()方法生成线程池.但是其内部定义的LinkedBlockingQueue容量是Integer.MAX ...
- http性能测试工具wrk源码学习之开篇
1.前言 最近工作需要测试nginx反向代理的性能,于是找了一些http测试工具,例如经典的Apache的ab.siege.wrk.wrk使用多线程事件驱动方式,支持lua脚本扩展.关于wrk介绍可以 ...
- 写一个java常用的加密工具类
1.叙述 java security包下有很多加密算法类,我们可以很简单的调用它们.他们虽然功能很全,但是使用起来步骤有些繁琐.我在这里封装来一些常用的加密算法及他们常用的一些方法,来简化代码. 工具 ...
- Java常用正则表达式验证工具类RegexUtils.java
import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexUtils{ /** * 正则表达式 ...
- java常用关键词关键字,方法源码解析
transient volatile native final Integer String Class &&Object newInstance Class.forName,Clas ...
- Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结
2017年的秋招彻底结束了,感觉Java上面的最常见的集合相关的问题就是hash--系列和一些常用并发集合和队列,堆等结合算法一起考察,不完全统计,本人经历:先后百度.唯品会.58同城.新浪微博.趣分 ...
随机推荐
- Mol Cell Proteomics. | Mapping Spatio-temporal Microproteomics Landscape in Experimental Model of Traumatic Brain Injury Unveils a link to Parkinson’s Disease
期刊:Molecular & Cellular Proteomics 发表时间:June 16, 2019 通讯作者:Michel Salzet,Isabelle Fournier 一. 概 ...
- Mol Cell Proteomics. | Elevated Hexokinase II Expression Confers Acquired Resistance to 4-Hydroxytamoxifen in Breast Cancer Cells(升高的己糖激酶II表达使得乳腺癌细胞获得对他莫昔芬的抗性)(解读人:黄旭蕾)
文献名:Elevated Hexokinase II Expression Confers Acquired Resistance to 4-Hydroxytamoxifen in Breast Ca ...
- (翻译) 使用Unity进行AOP对象拦截
Unity 是一款知名的依赖注入容器( dependency injection container) ,其支持通过自定义扩展来扩充功能. 在Unity软件包内 默认包含了一个对象拦截(Interce ...
- 用java分组查elasticsearch
哎,编程路漫漫,一坑又一坑,爬完还会掉,何时是尽头! 今朝有酒今朝醉,程序不对不敢睡! 还是接口昂,今天还是接口有问题,我是很菜,很笨,但是我还是要努力!! 正文: 接口需求是这样的,根据车型查询在线 ...
- MySQL优化之避免索引失效的方法
在上一篇文章中,通过分析执行计划的字段说明,大体说了一下索引优化过程中的一些注意点,那么如何才能避免索引失效呢?本篇文章将来讨论这个问题. 避免索引失效的常见方法 1.对于复合索引的使用,应按照索引建 ...
- 谷歌开发者:看可口可乐公司是怎么玩转 TensorFlow 的?
在这篇客座文章中,可口可乐公司的 Patrick Brandt 将向我们介绍他们如何使用 AI 和 TensorFlow 实现无缝式购买凭证. 可口可乐的核心忠诚度计划于 2006 年以 MyCoke ...
- Java 泛型数组问题
Java中不支持泛型数组, 以下代码会编译报错:generic array creation ArrayList<Integer>[] listArr = new ArrayList< ...
- 类加载机制之ClassLoader
1,类加载 每个编写的”.java”拓展名类文件都存储着需要执行的程序逻辑,这些”.java”文件经过Java编译器编译成拓展名为”.class”的文件,”.class”文件中保存着Java代码经转换 ...
- 读者来信 | 如果你家HBase集群Region太多请点进来看看,这个问题你可能会遇到
前言:<读者来信>是HBase老店开设的一个问答专栏,旨在能为更多的小伙伴解决工作中常遇到的HBase相关的问题.老店会尽力帮大家解决这些问题或帮你发出求救贴,老店希望这会是一个互帮互助的 ...
- JS 剑指Offer(四) 从尾到头打印链表
题目:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 首先定义一下链表中的节点,关于链表这个数据结构在另外一篇文章中会详细讲 function ListNode(val) { t ...