虽然在数组的随笔中有说过,但实际上应该仔细深入一下源码进行分析

源码没有想象中的高大上,代码终究还是写给人看的,可读性大于执行性

最小阵列排序: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(", ");
}
}

就先看到这儿了,剩下的几个方法都还没看懂是干嘛的

最新文章

  1. GridView/DataGrid行单击和双击事件实现代码_.Net教程
  2. Daily Scrum02 12.14
  3. [Linux] - CentOS中文乱码解决办法
  4. XE3随笔15:从XML中解析
  5. [C] 关于表达式求值
  6. dbVisualizer破解
  7. Akka学习博客
  8. Linux下如何使CP命令不提示覆盖
  9. python网络爬虫(一):网络爬虫科普与URL含义
  10. .NET Page页面事件执行顺序,以及其作用(OnPreInit()、OnInit()等)
  11. BZOJ 1096 ZJOI2007 仓库建设 边坡优化
  12. phalcon——调度控制器
  13. Java线程和进程相关面试题与答案总结
  14. 【转】shell脚本中如何传入参数
  15. SonarQube与Jenkins结合提高代码质量
  16. codeforce 489d bfs分层处理
  17. mongoDB开发规范
  18. Weblogic 12c 一个domain建多个server(端口)
  19. 洛咕 P2465 [SDOI2008]山贼集团
  20. 用Micro:bit控制遥控车

热门文章

  1. 为arm-unknown-linux-gnueabi-gcc工具链添加常用库(zlib、libpng、libjpeg、libtiff、libtool)(转载)
  2. Java ServerSocket详解
  3. 从数据结构分析mysql为何使用B+tree
  4. ElasticSearch 32766 的限制
  5. 使用PyTorch进行迁移学习
  6. python运算符&amp;条件语句
  7. mybatis入门二-----增删改查
  8. 听说你还搞不定java中的==和equals?
  9. Android ConstraintLayout 构建自适应界面
  10. 监听窗口大小变化,改变画面大小-[Three.js]-[onResize]