zoukankan      html  css  js  c++  java
  • java学习--工具类学习之Arrays(1)

     一、基本定义

      Arrays类,全路径java.util.Arrays,主要功能为操作数组,Arrays类的所有方法均为静态方法,所以

    调用方式全部为Arrays.方法名

    二、常用方法

    1. <T> List<T>  asList(T... a)

    可以将数组转化为相应的list集合,但是也只能转化为list,asList方法内部构建了一个内部静态类ArrayList,

    这个ArrayList也继承自AbstractList,但并不是我们集合中常用的ArrayList,这两者是有区别的,需注意,

    内部静态类AbstractList也实现了contains,forEach,replaceAll,sort,toArray等方法,但add,remove等方法则没有

    Integer[] array = new Integer[]{1,2,3};
    int[] array2 = new int[]{1,2,3};
    List<Integer> list1 = Arrays.asList(1,2,3);
    List<Integer> list2 = Arrays.asList(array);
    List<int[]> list3 = Arrays.asList(array2);

    2. void fill(int[] a, int val)、void fill(int[] a, int fromIndex, int toIndex, int val)、void fill(Object[] a, Object val)、void fill(Object[] a, int fromIndex, int toIndex, Object val)

    fill方法有多个重载,分别对应几种基本数据类型以及引用类型(Object),

    fill(int[] a, int val)会将整个数组的值全部覆盖为val

    fill(int[] a, int fromIndex, int toIndex, int val)则提供了可选的开头和结尾(不包括)

    int[] array = new int[]{1,2,3};
    Arrays.fill(array, 1);
    Arrays.fill(array, 0, 2, 1);//  {1,1,3}
    String[] str = {"123"};
    Arrays.fill(str, "1");

    源码如下:

    我们可以看到可选开头结尾的重载方法会先做数组越界的校验,防止非法输入

        /**
         * Assigns the specified double value to each element of the specified
         * range of the specified array of doubles.  The range to be filled
         * extends from index <tt>fromIndex</tt>, inclusive, to index
         * <tt>toIndex</tt>, exclusive.  (If <tt>fromIndex==toIndex</tt>, the
         * range to be filled is empty.)
         *
         * @param a the array to be filled
         * @param fromIndex the index of the first element (inclusive) to be
         *        filled with the specified value
         * @param toIndex the index of the last element (exclusive) to be
         *        filled with the specified value
         * @param val the value to be stored in all elements of the array
         * @throws IllegalArgumentException if <tt>fromIndex &gt; toIndex</tt>
         * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or
         *         <tt>toIndex &gt; a.length</tt>
         */
        public static void fill(double[] a, int fromIndex, int toIndex,double val){
            rangeCheck(a.length, fromIndex, toIndex);
            for (int i = fromIndex; i < toIndex; i++)
                a[i] = val;
        }
    
        /**
         * Assigns the specified float value to each element of the specified array
         * of floats.
         *
         * @param a the array to be filled
         * @param val the value to be stored in all elements of the array
         */
        public static void fill(float[] a, float val) {
            for (int i = 0, len = a.length; i < len; i++)
                a[i] = val;
        }
    
        /**
         * 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);
            }
        }

    3. int[] copyOf(int[] original, int newLength)、int[] copyOfRange(int[] original, int from, int to)

    存在多个重载方式,此处以int举例

    从样例中我i们看到,copyOf复制后的数组长度可以大于复制前的数组,根据源码发现,超出的元素被填充为0,引用类型则填充为null

    int[] array = new int[]{1,2,3};
    int[] array2 = Arrays.copyOf(array, 4);
        public static int[] copyOf(int[] original, int newLength) {
            int[] copy = new int[newLength];
            System.arraycopy(original, 0, copy, 0,
                             Math.min(original.length, newLength));
            return copy;
        }

    对于copyOfRange,可以选择复制的开头和结尾(不包括),且结尾下标可以大于原数组长度,超出的下标会被填充

    int[] array = new int[]{1,2,3,4,5,6,7,8,9};
    int[] array2 = Arrays.copyOfRange(array, 3, 6);
    int[] array3 = Arrays.copyOfRange(array, 3, 10);
        /**
         * Copies the specified range of the specified array into a new array.
         * The initial index of the range (<tt>from</tt>) must lie between zero
         * and <tt>original.length</tt>, inclusive.  The value at
         * <tt>original[from]</tt> is placed into the initial element of the copy
         * (unless <tt>from == original.length</tt> or <tt>from == to</tt>).
         * Values from subsequent elements in the original array are placed into
         * subsequent elements in the copy.  The final index of the range
         * (<tt>to</tt>), which must be greater than or equal to <tt>from</tt>,
         * may be greater than <tt>original.length</tt>, in which case
         * <tt>0</tt> is placed in all elements of the copy whose index is
         * greater than or equal to <tt>original.length - from</tt>.  The length
         * of the returned array will be <tt>to - from</tt>.
         *
         * @param original the array from which a range is to be copied
         * @param from the initial index of the range to be copied, inclusive
         * @param to the final index of the range to be copied, exclusive.
         *     (This index may lie outside the array.)
         * @return a new array containing the specified range from the original array,
         *     truncated or padded with zeros to obtain the required length
         * @throws ArrayIndexOutOfBoundsException if {@code from < 0}
         *     or {@code from > original.length}
         * @throws IllegalArgumentException if <tt>from &gt; to</tt>
         * @throws NullPointerException if <tt>original</tt> is null
         * @since 1.6
         */
        public static int[] copyOfRange(int[] original, int from, int to) {
            int newLength = to - from;
            if (newLength < 0)
                throw new IllegalArgumentException(from + " > " + to);
            int[] copy = new int[newLength];
            System.arraycopy(original, from, copy, 0,
                             Math.min(original.length - from, newLength));
            return copy;
        }

    4. boolean equals(int[] a, int[] a2)、boolean equals(Object[] a, Object[] a2)

    比较2个数组是否相等,基本类型的元素会依次进行==判断,引用类型则会在判空后使用equals

        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;
        }

    5.  String toString(int[] a)

    假设我们想输出一个数组的全部元素,一种方法是利用循环遍历所有元素后挨个输出

    但Arrays提供了一个方案可以直接调用,toString内部实现其实也是通过遍历来实现,

    利用可变字符串StringBuilder来构建

        public static String toString(int[] 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(", ");
            }
        }

    6. int binarySearch(int[] a, int key)

      Arrays内置的二分查找方法,使用条件为参数数组a是有序的,如无序

    会导致返回结果错误

     1     public static int binarySearch(int[] a, int fromIndex, int toIndex,
     2                                    int key) {
     3         rangeCheck(a.length, fromIndex, toIndex);
     4         return binarySearch0(a, fromIndex, toIndex, key);
     5     }
     6 
     7     // Like public version, but without range checks.
     8     private static int binarySearch0(int[] a, int fromIndex, int toIndex,
     9                                      int key) {
    10         int low = fromIndex;
    11         int high = toIndex - 1;
    12 
    13         while (low <= high) {
    14             int mid = (low + high) >>> 1;
    15             int midVal = a[mid];
    16 
    17             if (midVal < key)
    18                 low = mid + 1;
    19             else if (midVal > key)
    20                 high = mid - 1;
    21             else
    22                 return mid; // key found
    23         }
    24         return -(low + 1);  // key not found.
    25     }
    争取早日不再是一只菜鸡
  • 相关阅读:
    Qt 布局之二:水平、垂直布局的使用详解
    Qt 布局之一:布局初探
    [数据库] SQL 语法之进阶篇
    [数据库] SQL 语法之基础篇
    看图深入理解单链表的反转
    [数据结构
    (原)tslib的交叉编译
    (转) s-video vs. composite video vs. component video 几种视频格式详细说明和比较
    (转)BT1120接口及协议
    (转)Ubuntu12.04上NFS Server安装使用过程
  • 原文地址:https://www.cnblogs.com/jchen104/p/14649061.html
Copyright © 2011-2022 走看看