Java源码学习之集合系列四

Arrays

本系列的Java源码版本是官网最新版java 11

该类是一个工具类,从名字可以看出是对数组操作的工具类。java中还有很多这样的工具类,类名后面加s表示该类型的工具类,比如 Collections 等等。该类方法比较多,我会分几个主题来讲解。

排序

Arrays 中的排序是通过 DualPivotQuicksort 这个类实现的,首先我们看看 sort 这个方法的具体实现

	static void sort(int[] a, int left, int right,
                     int[] work, int workBase, int workLen) {
        // Use Quicksort on small arrays
        if (right - left < QUICKSORT_THRESHOLD) {
            sort(a, left, right, true);
            return;
        }
        ...
    }

QUICKSORT_THRESHOLD 这个变量是快速排序的阈值(286),当数组长度小于这个数的时候使用快速排序。为啥是这个值后续我们再探讨。

    private static void sort(int[] a, int left, int right, boolean leftmost) {
        int length = right - left + 1;

        // Use insertion sort on tiny arrays
        if (length < INSERTION_SORT_THRESHOLD) {
            ...
            return;
        }
    }

INSERTION_SORT_THRESHOLD 这个变量也是一个阈值(47),当数组长度小于这个数的时候使用插入排序。看看java是如何实现插入排序的

	/*
     * Traditional (without sentinel) insertion sort,
     * optimized for server VM, is used in case of
     * the leftmost part.
     */
    for (int i = left, j = i; i < right; j = ++i) {
        int ai = a[i + 1];
        while (ai < a[j]) {
            a[j + 1] = a[j];
            if (j-- == left) {
                break;
            }
        }
        a[j + 1] = ai;
    }

首先代码有个地方非常迷惑 j-- == left ,这个分成2部:

  • j == left
  • j = j - 1

我通过 javap -l -c QuicksortMain 查看了编译的字节码如下:

        ...
        53: iload         4 // 将j放入栈中
        55: iinc          4, -1 // 将本地变量j-1,但是不改变已经入栈的值
        58: iload_1 // 将left放入栈中
        59: if_icmpne     24 // 判断栈里面的j和left,如果不相等跳转到 int ai = a[i + 1]
        ...
        LocalVariableTable:
       Slot  Name
         1      left
         4      j

java中实现了2种插入排序,这种是传统的插入排序也称之为无哨兵模式,插入排序的代码思路如下:
算法图解
i和j左边的都是排好序的,每次从数组选择一个元素ai(i+1)依次同左边的每一个元素aj进行比较,如果ai<aj则将aj腾挪到右边相邻的位置上,否则将ai赋值给aj

下一节继续研究
未完待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值