概述

Arrays类位于java.util包下,是一个对数组操作的工具类。今天详细的看了看Arrays类的4千多行源码,现将Arrays类中的方法做一个总结(JDK版本:1.6.0_34)。Arrays类中的方法可以分为八类:

  • sort(对数组排序)
  • binarySearch(二分法查找数组中的元素)
  • equals(比较两个数组是否相等)
  • fill(对数组中的指定位置填充相同的内容)
  • copyOf(数组拷贝)
  • asList(将数组转换为一个固定的List对象)
  • hashCode(计算数组的哈希值)
  • toString(以特定格式输出数组)

举例说明

说明:以下的代码均为摘抄的java.util.Arrays类中的源码,注释为本人所加。

sort

//对数组a进行排序
public static void sort(long[] a) {
        sort1(a, 0, a.length);
    }
//对数组a中的从fromIndex(包含)至toIndex(不包含)的值进行排序
public static void sort(long[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        sort1(a, fromIndex, toIndex-fromIndex);
    }
/**
对基本类型数组的排序有以上两种方法,这里只摘出了long类型的。sort1方法篇幅原因没有摘出来,在sort1方法中使用的是经过调优的快速排序算法(tuned quicksort)。
**/
..........
..........
..........
//对对象类型进行排序
public static void sort(Object[] a) {
        Object[] aux = (Object[])a.clone();
        mergeSort(aux, a, 0, a.length, 0);
    }
//对对象a中的从fromIndex(包含)至toIndex(不包含)的值进行排序
public static void sort(Object[] a, int fromIndex, int toIndex) {
        rangeCheck(a.length, fromIndex, toIndex);
        Object[] aux = copyOfRange(a, fromIndex, toIndex);
        mergeSort(aux, a, fromIndex, toIndex, -fromIndex);
    }
/**
对对象类型数组的排序有以上两种方法,在mergeSort方法中使用的是经过修改的归并排序算法(modified mergesort)。
**/

binarySearch

 public static int binarySearch(long[] a, long key) {
    return binarySearch0(a, 0, a.length, key);
    }
 public static int binarySearch(long[] a, int fromIndex, int toIndex,
                   long key) {
    rangeCheck(a.length, fromIndex, toIndex);
    return binarySearch0(a, fromIndex, toIndex, key);
    }
/**
对数组中元素的查找有以上两种方法,在binarySearch0方法中使用的是二分查找法。并且对基本类型和对象类型的数组查找是同样的操作。
**/

equals

//比较基本类型数组是否相等
 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;

        for (int i=0; i<length; i++)
            if (a[i] != a2[i])
                return false;
/**
        对于double类型,使用的是:
        if (Double.doubleToLongBits(a[i])!=Double.doubleToLongBits(a2[i]))
        return false;
        对于float类型,使用的是:
         if (Float.floatToIntBits(a[i])!=Float.floatToIntBits(a2[i]))
                return false;
这样做是为了精确比较。
        **/
        return true;
    }
.....
.....
.....
//比较Object类型数组是否相等
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 boolean deepEquals(Object[] a1, Object[] a2) {
        if (a1 == a2)
            return true;
        if (a1 == null || a2==null)
            return false;
        int length = a1.length;
        if (a2.length != length)
            return false;

        for (int i = 0; i < length; i++) {
            Object e1 = a1[i];
            Object e2 = a2[i];

            if (e1 == e2)
                continue;
            if (e1 == null)
                return false;

            // Figure out whether the two elements are equal
            boolean eq;
            if (e1 instanceof Object[] && e2 instanceof Object[])
                eq = deepEquals ((Object[]) e1, (Object[]) e2);
            else if (e1 instanceof byte[] && e2 instanceof byte[])
                eq = equals((byte[]) e1, (byte[]) e2);
            else if (e1 instanceof short[] && e2 instanceof short[])
                eq = equals((short[]) e1, (short[]) e2);
            else if (e1 instanceof int[] && e2 instanceof int[])
                eq = equals((int[]) e1, (int[]) e2);
            else if (e1 instanceof long[] && e2 instanceof long[])
                eq = equals((long[]) e1, (long[]) e2);
            else if (e1 instanceof char[] && e2 instanceof char[])
                eq = equals((char[]) e1, (char[]) e2);
            else if (e1 instanceof float[] && e2 instanceof float[])
                eq = equals((float[]) e1, (float[]) e2);
            else if (e1 instanceof double[] && e2 instanceof double[])
                eq = equals((double[]) e1, (double[]) e2);
            else if (e1 instanceof boolean[] && e2 instanceof boolean[])
                eq = equals((boolean[]) e1, (boolean[]) e2);
            else
                eq = e1.equals(e2);

            if (!eq)
                return false;
        }
        return true;
    }

fill

//使用val对a数组进行数据填充
  public static void fill(long[] a, long val) {
        fill(a, 0, a.length, val);
    }
//使用val对a数组从fromIndex(包含)至toIndex(不包含)位置进行数据填充
 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;
    }

copyOf

//拷贝从0开始的newLength个
public static byte[] copyOf(byte[] original, int newLength) {
        byte[] copy = new byte[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }
.....
.....
.....
//拷贝从from(包含)位置到to(不包含)的元素
public static byte[] copyOfRange(byte[] original, int from, int to) {
        int newLength = to - from;
        if (newLength < 0)
            throw new IllegalArgumentException(from + " > " + to);
        byte[] copy = new byte[newLength];
        System.arraycopy(original, from, copy, 0,
                         Math.min(original.length - from, newLength));
        return copy;
    }
/**
拷贝方法有以上两种,对于基本类型和对象操作是一样的。而System.arraycopy()方法为浅拷贝,故如果是对象数组的拷贝,只是拷贝了对象的引用,没有重新new每一个对象。
**/

asList

没有深究。。。。。。

hashCode

//对基本数据类型的hashcode的计算
    public static int hashCode(long a[]) {
        if (a == null)
            return 0;

        int result = 1;
        for (long element : a) {
        //对于不同的基本数据类型,计算hashcode的具体操作是不一样的
            int elementHash = (int)(element ^ (element >>> 32));
            result = 31 * result + elementHash;
        }

        return result;
    }
....
....
....
//对于Object类型数组的hashcode的计算
public static int hashCode(Object a[]) {
        if (a == null)
            return 0;

        int result = 1;

        for (Object element : a)
            result = 31 * result + (element == null ? 0 : element.hashCode());

        return result;
    }
....
....
....
//对于数组的hashcode值的深度计算
public static int deepHashCode(Object a[]) {
        if (a == null)
            return 0;

        int result = 1;

        for (Object element : a) {
            int elementHash = 0;
            if (element instanceof Object[])
                elementHash = deepHashCode((Object[]) element);
            else if (element instanceof byte[])
                elementHash = hashCode((byte[]) element);
            else if (element instanceof short[])
                elementHash = hashCode((short[]) element);
            else if (element instanceof int[])
                elementHash = hashCode((int[]) element);
            else if (element instanceof long[])
                elementHash = hashCode((long[]) element);
            else if (element instanceof char[])
                elementHash = hashCode((char[]) element);
            else if (element instanceof float[])
                elementHash = hashCode((float[]) element);
            else if (element instanceof double[])
                elementHash = hashCode((double[]) element);
            else if (element instanceof boolean[])
                elementHash = hashCode((boolean[]) element);
            else if (element != null)
                elementHash = element.hashCode();

            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(", ");
        }
    }
.....
.....
.....
//Object类型使用valueOf方法转字符串
public static String toString(Object[] 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(String.valueOf(a[i]));
            if (i == iMax)
        return b.append(']').toString();
        b.append(", ");
        }
    }
.....
.....
.....
//深度转换字符串
public static String deepToString(Object[] a) {
        if (a == null)
            return "null";

        int bufLen = 20 * a.length;
        if (a.length != 0 && bufLen <= 0)
            bufLen = Integer.MAX_VALUE;
        StringBuilder buf = new StringBuilder(bufLen);
        deepToString(a, buf, new HashSet());
        return buf.toString();
    }

private static void deepToString(Object[] a, StringBuilder buf,
                                     Set<Object[]> dejaVu) {
        if (a == null) {
            buf.append("null");
            return;
        }
        dejaVu.add(a);
        buf.append('[');
        for (int i = 0; i < a.length; i++) {
            if (i != 0)
                buf.append(", ");

            Object element = a[i];
            if (element == null) {
                buf.append("null");
            } else {
                Class eClass = element.getClass();

                if (eClass.isArray()) {
                    if (eClass == byte[].class)
                        buf.append(toString((byte[]) element));
                    else if (eClass == short[].class)
                        buf.append(toString((short[]) element));
                    else if (eClass == int[].class)
                        buf.append(toString((int[]) element));
                    else if (eClass == long[].class)
                        buf.append(toString((long[]) element));
                    else if (eClass == char[].class)
                        buf.append(toString((char[]) element));
                    else if (eClass == float[].class)
                        buf.append(toString((float[]) element));
                    else if (eClass == double[].class)
                        buf.append(toString((double[]) element));
                    else if (eClass == boolean[].class)
                        buf.append(toString((boolean[]) element));
                    else { // element is an array of object references
                        if (dejaVu.contains(element))
                            buf.append("[...]");
                        else
                            deepToString((Object[])element, buf, dejaVu);
                    }
                } else {  // element is non-null and not an array
                    buf.append(element.toString());
                }
            }
        }
        buf.append(']');
        dejaVu.remove(a);
    }

java.util.Arrays类详解(源码总结)的更多相关文章

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

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

  2. Java开源生鲜电商平台-盈利模式详解(源码可下载)

    Java开源生鲜电商平台-盈利模式详解(源码可下载) 该平台提供一个联合买家与卖家的一个平台.(类似淘宝购物,这里指的是食材的购买.) 平台有以下的盈利模式:(类似的平台有美菜网,食材网等) 1. 订 ...

  3. ArrayList详解-源码分析

    ArrayList详解-源码分析 1. 概述 在平时的开发中,用到最多的集合应该就是ArrayList了,本篇文章将结合源代码来学习ArrayList. ArrayList是基于数组实现的集合列表 支 ...

  4. java之AbstractStringBuilder类详解

    目录 AbstractStringBuilder类 字段 构造器 方法   public abstract String toString() 扩充容量 void  expandCapacity(in ...

  5. java之Matcher类详解

    在JDK 1.4中,Java增加了对正则表达式的支持. java与正则相关的工具主要在java.util.regex包中:此包中主要有两个类:Pattern.Matcher. Matcher  声明: ...

  6. 国际化,java.util.ResourceBundle使用详解

    java.util.ResourceBundle使用详解   一.认识国际化资源文件   这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以:          轻松地本地化或翻译成不同的 ...

  7. java之StringBuffer类详解

    StringBuffer 线程安全的可变字符序列. StringBuffer源码分析(JDK1.6): public final class StringBuffer extends Abstract ...

  8. java.util.ResourceBundle使用详解

    java.util.ResourceBundle使用详解   一.认识国际化资源文件   这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以:          轻松地本地化或翻译成不同的 ...

  9. java之StringBuilder类详解

    StringBuilder 非线程安全的可变字符序列 .该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍).如果可能,建议优先采用该类,因为在 ...

随机推荐

  1. Junit简单配置

    Junit简单配置的步骤如下: 1.在WEB-INF目录下的lib里面放一个junit包,我用的是junit-4.9.jar: 2.选定要测试的类,右键单击该类,新建一个Junit Test Case ...

  2. Python super使用

    一 基础使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如: #!/usr ...

  3. Codeforces Round#403 (Div. 1)

    唉,昨天晚上迷迷糊糊地去打cf,结果fst两题,掉回蓝了... A.Andryusha and Colored Balloons 题意:给定一棵树,任意两个距离小等于二的点不能染相同的颜色,求最小颜色 ...

  4. 配置mysql使其允许外部ip进行登录

    这两天在做一个数据库的项目,用到了mysql,需要通过外部的ip远程访问mysql,发现默认的mysql是不允许远程访问的,需要做简单的配置. 如下: 1. 打开一个终端(cmd)输入 mysql - ...

  5. 缓冲区(buffer)与缓存(cache)

    下面介绍缓冲区的知识. 一.什么是缓冲区 缓冲区(buffer),它是内存空间的一部分.也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区, ...

  6. 重新设置Eclipse的workspace路径

    有3中方法可以更改workspace的路径设置: 1. 启动Eclipse/MyEclipse后, 打开"Window -> Preferences -> General -&g ...

  7. bootstrap插件fileinput.js 出现出现$("#xxxx").fileinput({}); 不生效的情况解决

    如果出现$("#xxxx").fileinput({}); 不生效的情况请将fileinput.js中最后几行注释掉: /* $(document).ready(function ...

  8. Redis学习汇总

    [Redis教程目录] 1.redis是什么 2.redis的作者何许人也 3.谁在使用redis 4.学会安装redis 5.学会启动redis 6.使用redis客户端 7.redis数据结构 – ...

  9. Python小代码_7_字符串的字符次数统计

    生成包含 1000 个随机字符的字符串,并统计每个字符出现的次数. import string import random #获取字符 x = string.ascii_letters + strin ...

  10. sa账号无法登陆sqlserver2008

    今天遇到sa无法登陆sqlserver2008的问题,原来是sa账户未启用,混合验证模式没打开,太低端了. 具体解决过程将从百度文库里查到的文章张贴如下: 出现问题 : 标题: 连接到服务器 ---- ...