Thinking in java Chapter16 数组

数组和容器很像

但数组的尺寸不能改变

1 数组为什么特殊

数组与容器区别

效率:数组是简单的线性序列,使得访问非常迅速。但数组长度固定,并且在生命周期内不可改变。容器的灵活,需要付出更多开销。

存储类型:没有泛型前,数组可以存储固定类型元素,容器只能存储Object类型。容器一开始也不能存储基本类型,但新增包装类,容器也能存储基本类型。

新增的泛型和包装类 数组和容器在这点的区别已经不明显

数组仅存优点,就是效率

容器比数组功能更多

package arrays;

import java.util.*;
import static net.mindview.util.Print.*;

class BerylliumSphere {//铍球体
    private static long counter;
    private final long id = counter++;
    public String toString() { return "Sphere " + id; }
}
public class ContainerComparison {
    public static void main(String[] args) {
        BerylliumSphere[] spheres = new BerylliumSphere[10];//新建一个有10个槽的数组,初始化为null
        for(int i = 0; i < 5; i++)
            spheres[i] = new BerylliumSphere();//初始化第0-4个槽元素
        print(Arrays.toString(spheres));//打印全部槽内元素
        print(spheres[4]);//打印第5个槽的元素
        List<BerylliumSphere> sphereList =
                new ArrayList<BerylliumSphere>();// 新建ArrayList
        for(int i = 0; i < 5; i++)
            sphereList.add(new BerylliumSphere());//ArrayList 加入5个元素
        print(sphereList);//打印整个ArrayList
        print(sphereList.get(4));//读取第5个元素
        int[] integers = { 0, 1, 2, 3, 4, 5 };
        print(Arrays.toString(integers));
        print(integers[4]);
        List<Integer> intList = new ArrayList<Integer>(
                Arrays.asList(0, 1, 2, 3, 4, 5));
        intList.add(97);
        print(intList);
        print(intList.get(4));
    }
}
/*
[Sphere 0, Sphere 1, Sphere 2, Sphere 3, Sphere 4, null, null, null, null, null]
Sphere 4
[Sphere 5, Sphere 6, Sphere 7, Sphere 8, Sphere 9]
Sphere 9
[0, 1, 2, 3, 4, 5]
4
[0, 1, 2, 3, 4, 5, 97]
4
 */

2 数组是第一级对象

数组标识符是一个引用,它指向堆中创建的一个真实对象

数组没有初始化之前 不能做任何事情

该对象保存指向其他对象的引用,该对象还有一个只读成员length,是能够容纳元素,不是实际保存的元素个数

下标[]是访问数组的唯一方式

数组类型 存储 初始化
对象数组 引用 null
基本类型数组 数值 数值型 0 字符型char('u0000' 0) 布尔型false
package arrays;

import java.util.Arrays;

import static net.mindview.util.Print.*;

public class ArrayOptions {
    public static void main(String[] args) {
        // Arrays of objects:存储对象数组,保存的是引用
        BerylliumSphere[] a; // Local uninitialized variable 本地未进行初始化
        BerylliumSphere[] b = new BerylliumSphere[5];//创建长度为5的数组
        // The references inside the array are  指向的5个对象的引用初始化为空
        // automatically initialized to null:
        print("b: " + Arrays.toString(b));
        BerylliumSphere[] c = new BerylliumSphere[4];
        for(int i = 0; i < c.length; i++)
            if(c[i] == null) // Can test for null reference
                c[i] = new BerylliumSphere();
        // Aggregate initialization:"聚集初始化"语法
        BerylliumSphere[] d = { new BerylliumSphere(),
                new BerylliumSphere(), new BerylliumSphere()
        };
        // Dynamic aggregate initialization:动态的聚集初始化
        a = new BerylliumSphere[]{//初始长度为2
                new BerylliumSphere(), new BerylliumSphere(),
        };
        // (Trailing comma is optional in both cases)这两种情况下,尾随逗号可选
        print("a.length = " + a.length);
        print("b.length = " + b.length);
        print("c.length = " + c.length);
        print("d.length = " + d.length);
        a = d;
        print("a.length = " + a.length);

        // Arrays of primitives:基本类型数组,保存基本类型的值
        int[] e; // Null reference 空引用
        int[] f = new int[5];
        // The primitives inside the array are  基本类型数组初始化值为0
        // automatically initialized to zero:
        print("f: " + Arrays.toString(f));
        int[] g = new int[4];
        for(int i = 0; i < g.length; i++)
            g[i] = i*i;
        int[] h = { 11, 47, 93 };
        // Compile error: variable e not initialized:
        //!print("e.length = " + e.length);
        print("f.length = " + f.length);
        print("g.length = " + g.length);
        print("h.length = " + h.length);
        e = h;
        print("e.length = " + e.length);
        e = new int[]{ 1, 2 };
        print("e.length = " + e.length);
    }
}
/*
b: [null, null, null, null, null]
a.length = 2
b.length = 5
c.length = 4
d.length = 3
a.length = 3
f: [0, 0, 0, 0, 0]
f.length = 5
g.length = 4
h.length = 3
e.length = 3
e.length = 2
 */
作业1
package arrays.e1;

class BerylliumSphere {//铍球体
    private static long counter;
    private final long id = counter++;
    public String toString() { return "Sphere " + id; }
}

public class E1 {
    public static void E1Method(BerylliumSphere[] berylliumSpheres){
        System.out.println(berylliumSpheres);
        System.out.println();
    }

    public static void main(String[] args) {
        //最常规初始化
        BerylliumSphere[] berylliumSphere = new BerylliumSphere[5];
        for(int i = 0; i< berylliumSphere.length;i++)
            berylliumSphere[i] = new BerylliumSphere();

        //聚集初始化

        //普通的聚集数组初始化不能奏效,不允许数组初始化,需要加上new BerylliumSphere[]
        //E1.E1Method({new BerylliumSphere(),new BerylliumSphere(),});
        // 但可以这样
        BerylliumSphere[] b = {new BerylliumSphere(),new BerylliumSphere(),};
        E1Method(b);
        
        //动态聚集初始化
        
        E1.E1Method(new BerylliumSphere[]{new BerylliumSphere(),new BerylliumSphere(),});
        // 这里显的多余
        BerylliumSphere[] c = new BerylliumSphere[]{new BerylliumSphere(),new BerylliumSphere(),};
        E1Method(c);
    }
}

3 返回一个数组

Java中返回String数组

package arrays;

import java.util.*;

public class IceCream {
    private static Random rand = new Random(47);
    //创建一个String数组
    static final String[] FLAVORS = {//“巧克力”、“草莓”、“香草软糖漩涡”、“薄荷片”、
            // “摩卡杏仁软糖”、“朗姆酒葡萄干”、“果仁奶油”、“泥饼”
            "Chocolate", "Strawberry", "Vanilla Fudge Swirl",
            "Mint Chip", "Mocha Almond Fudge", "Rum Raisin",
            "Praline Cream", "Mud Pie"
    };
    //返回一个String数组
    public static String[] flavorSet(int n) {
        if(n > FLAVORS.length)//如果种类大于数组长度
            throw new IllegalArgumentException("Set too big");
        String[] results = new String[n];//创建一个要返回的数组
        boolean[] picked = new boolean[FLAVORS.length];//创建一个长度和FLAVORS相等的boolean数组,初始化为false,即未添加过此口味
        for(int i = 0; i < n; i++) {//遍历result数组,进行初始化
            int t; do
                t = rand.nextInt(FLAVORS.length);
            while(picked[t]);//如果被标记过,则重复生成
            results[i] = FLAVORS[t];//初始化result
            picked[t] = true;//标记当前下标的String已经被初始化,避免重复
        }
        return results;
    }
    public static void main(String[] args) {
        for(int i = 0; i < 7; i++)
            System.out.println(Arrays.toString(flavorSet(3)));// 随机选择3种味道,选择7组
    }
}
/*
[Rum Raisin, Mint Chip, Mocha Almond Fudge]
[Chocolate, Strawberry, Mocha Almond Fudge]
[Strawberry, Mint Chip, Mocha Almond Fudge]
[Rum Raisin, Vanilla Fudge Swirl, Mud Pie]
[Vanilla Fudge Swirl, Chocolate, Mocha Almond Fudge]
[Praline Cream, Strawberry, Mocha Almond Fudge]
[Mocha Almond Fudge, Strawberry, Mint Chip]
 */

作业2
package arrays.e2;

import arrays.BerylliumSphere;

import java.util.Arrays;

public class E2 {
     static BerylliumSphere[] createArray(int size) {
        if (size < 0 ) return null;
        BerylliumSphere[] result = new BerylliumSphere[size];
        for (int i = 0; i < size; i++) {
            result[i] = new BerylliumSphere();
        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println(Arrays.toString(createArray(3)));
        System.out.println(Arrays.toString(createArray(0))); //0 为[]  负数 NegativeArraySizeException
    }
}
/*
[Sphere 0, Sphere 1, Sphere 2]
[]
 */

4 多维数组

基本类型数组

package arrays;

import java.util.Arrays;

public class MultidimensionalPrimitiveArray {
    public static void main(String[] args) {
        int[][] a = {//2*3数组
                { 1, 2, 3, },
                { 4, 5, 6, },
        };
        System.out.println(Arrays.deepToString(a));//打印基本类型或者object
    }
}
/*
[[1, 2, 3], [4, 5, 6]]
 */

三维数组

package arrays;

import java.util.Arrays;

public class ThreeDWithNew {
    public static void main(String[] args) {
        // 3-D array with fixed length:
        int[][][] a = new int[2][2][4];
        System.out.println(Arrays.deepToString(a));// 基本类型数组初始化为0,对象数组初始化为null
    }
}
/*
[[[0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0]]]
 */

粗糙数组:构成矩阵的每个向量都可以具有任意长度。

package arrays;

import java.util.*;

public class RaggedArray {
    public static void main(String[] args) {
        Random rand = new Random(47);
        // 3-D array with varied-length vectors:
        int[][][] a = new int[rand.nextInt(7)][][];//一维长度
        for(int i = 0; i < a.length; i++) {
            a[i] = new int[rand.nextInt(5)][];//二维长度
            for(int j = 0; j < a[i].length; j++)
                a[i][j] = new int[rand.nextInt(5)];//三维长度
        }

        System.out.println(Arrays.deepToString(a));
        System.out.println(a.length);
    }
}
/*
[
[], 
[[0], [0], [0, 0, 0, 0]],
 [[], [0, 0], [0, 0]], 
 [[0, 0, 0], [0], [0, 0, 0, 0]], 
 [[0, 0, 0], [0, 0, 0], [0], []], 
 [[0], [], [0]]
 ]
 */

非基本类型的对象数组,粗糙数组

package arrays;

import java.util.Arrays;

public class MultidimensionalObjectArrays {
    public static void main(String[] args) {
        BerylliumSphere[][] spheres = {
                { new BerylliumSphere(), new BerylliumSphere() },
                { new BerylliumSphere(), new BerylliumSphere(),
                        new BerylliumSphere(), new BerylliumSphere() },
                { new BerylliumSphere(), new BerylliumSphere(),
                        new BerylliumSphere(), new BerylliumSphere(),
                        new BerylliumSphere(), new BerylliumSphere(),
                        new BerylliumSphere(), new BerylliumSphere() },
        };
        System.out.println(Arrays.deepToString(spheres));
    }
}
/*
[
[Sphere 0, Sphere 1],
 [Sphere 2, Sphere 3, Sphere 4, Sphere 5],
 [Sphere 6, Sphere 7, Sphere 8, Sphere 9, Sphere 10, Sphere 11, Sphere 12, Sphere 13]
 ]
 */

自动包装机制对数组初始化也起作用

package arrays;

import java.util.Arrays;

public class AutoboxingArrays {
    public static void main(String[] args) {
        Integer[][] a = { // Autoboxing:
                { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },
                { 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 },
                { 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 },
                { 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 },
        };
        System.out.println(Arrays.deepToString(a));
    }
}

多维数组逐维初始化

package arrays;

import java.util.Arrays;

public class AssemblingMultidimensionalArrays {
    public static void main(String[] args) {
        Integer[][] a;
        a = new Integer[3][];
        for(int i = 0; i < a.length; i++) {
            a[i] = new Integer[3];
            for(int j = 0; j < a[i].length; j++)
                a[i][j] = i * j; // Autoboxing
        }
        System.out.println(Arrays.deepToString(a));
    }
}
/*
[[0, 0, 0], [0, 1, 2], [0, 2, 4]]
 */

Integer 和Double数组,自动包装机制,创建包装器对象

package arrays;

import java.util.Arrays;

public class MultiDimWrapperArray {
    public static void main(String[] args) {
        Integer[][] a1 = { // Autoboxing
                { 1, 2, 3, },
                { 4, 5, 6, },
        };
        Double[][][] a2 = { // Autoboxing
                { { 1.1, 2.2 }, { 3.3, 4.4 } },
                { { 5.5, 6.6 }, { 7.7, 8.8 } },
                { { 9.9, 1.2 }, { 2.3, 3.4 } },
        };
        String[][] a3 = {
                { "The", "Quick", "Sly", "Fox" },
                { "Jumped", "Over" },
                { "The", "Lazy", "Brown", "Dog", "and", "friend" },
        };
        System.out.println("a1: " + Arrays.deepToString(a1));
        System.out.println("a2: " + Arrays.deepToString(a2));
        System.out.println("a3: " + Arrays.deepToString(a3));
    }
}
/*
a1: [[1, 2, 3], [4, 5, 6]]
a2: [[[1.1, 2.2], [3.3, 4.4]], [[5.5, 6.6], [7.7, 8.8]], [[9.9, 1.2], [2.3, 3.4]]]
a3: [[The, Quick, Sly, Fox], [Jumped, Over], [The, Lazy, Brown, Dog, and, friend]]
 */

数组与泛型

不能实例化 具有参数类型 的数组
Peel[] peels = new Peel [10]; // Illegal
擦除 移除 参数类型信息
数组强制 保证类型安全,必须知道持有的确切类型

参数化数组本身的类型

package arrays;

class ClassParameter<T> {//类参数化,<T> 位置
    public T[] f(T[] arg) { return arg; }
}
class MethodParameter {//方法参数化,首选
    public static <T> T[] f(T[] arg) { return arg; }//静态
}

public class ParameterizedArrayType {
    public static void main(String[] args) {
        Integer[] ints = { 1, 2, 3, 4, 5 };
        Double[] doubles = { 1.1, 2.2, 3.3, 4.4, 5.5 };
        Integer[] ints2 =
                new ClassParameter<Integer>().f(ints);//声明的地方不可以使用泛型 但赋值可以
        Double[] doubles2 =
                new ClassParameter<Double>().f(doubles);
        ints2 = MethodParameter.f(ints);
        doubles2 = MethodParameter.f(doubles);
    }
}

尽管不能创建实际的持有泛型的数组对象,

但可以创建非泛型的数组,然后将其转型

package arrays;

import java.util.*;

public class ArrayOfGenerics {
        @SuppressWarnings("unchecked")
        public static void main(String[] args) {
            List<String>[] ls;//创建一个泛型数组的引用
            List[] la = new List[10];//创建一个普通数组
            ls = (List<String>[])la; // "Unchecked" warning
            ls[0] = new ArrayList<String>();
            // Compile-time checking produces an error:编译期类型错误
            //! ls[1] = new ArrayList<Integer>();

            // The problem: List<String> is a subtype of Object
            Object[] objects = ls; // So assignment is OK
            // Compiles and runs without complaint:
            objects[1] = new ArrayList<Integer>();//正常编译


            // However, if your needs are straightforward it is
            // possible to create an array of generics, albeit
            // with an "unchecked" warning:
            List<BerylliumSphere>[] spheres =
                    (List<BerylliumSphere>[])new List[10];
            for(int i = 0; i < spheres.length; i++)
                spheres[i] = new ArrayList<BerylliumSphere>();
        }
}

作业9
package arrays.e9;

import java.util.ArrayList;

class Banana {
    private final int id;

    Banana(int id) {
        this.id = id;
    }

    public String toString() {
        return getClass().getSimpleName() + " " + id;
    }
}

class Peel<T> {
    T fruit;

    Peel(T fruit) {
        this.fruit = fruit;
    }

    void peel() {
        System.out.println("Peeling " + fruit);
    }
}

public class E9 {
    public static void main(String[] args) {
        //Peel<Banana> a = new Peel<Banana>[10];// 编译错误 泛型数组创建
        ArrayList<Peel<Banana>> a = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            a.add(new Peel<>(new Banana(i)));
        }
        for (Peel<Banana> p : a)
            p.peel();
    }
}

6 创建测试数据

介绍各种工具填充数组

Arrays.fill

分类 填充
基本类型 同一个值填充
对象 复制同一个引用
package arrays;

import java.util.Arrays;
import static net.mindview.util.Print.*;

public class FillingArrays {
    public static void main(String[] args) {
        int size = 6;
        //创建长度为6的基本类型 和 String类型数组
        boolean[] a1 = new boolean[size];
        byte[] a2 = new byte[size];
        char[] a3 = new char[size];
        short[] a4 = new short[size];
        int[] a5 = new int[size];
        long[] a6 = new long[size];
        float[] a7 = new float[size];
        double[] a8 = new double[size];
        String[] a9 = new String[size];
        Arrays.fill(a1, true);
        print("a1 = " + Arrays.toString(a1));
        Arrays.fill(a2, (byte)11);
        print("a2 = " + Arrays.toString(a2));
        Arrays.fill(a3,'x');
        print("a3 = " + Arrays.toString(a3));
        Arrays.fill(a4, (short)17);
        print("a4 = " + Arrays.toString(a4));
        Arrays.fill(a5, 19);
        print("a5 = " + Arrays.toString(a5));
        Arrays.fill(a6, 23);
        print("a6 = " + Arrays.toString(a6));
        Arrays.fill(a7, 29);
        print("a7 = " + Arrays.toString(a7));
        Arrays.fill(a8, 47);
        print("a8 = " + Arrays.toString(a8));
        Arrays.fill(a9, "Hello");
        print("a9 = " + Arrays.toString(a9));
        // Manipulating ranges:
        Arrays.fill(a9, 3, 5, "World");//可以指定位置填充,[3,5)
        print("a9 = " + Arrays.toString(a9));
    }
}
/*
a1 = [true, true, true, true, true, true]
a2 = [11, 11, 11, 11, 11, 11]
a3 = [x, x, x, x, x, x]
a4 = [17, 17, 17, 17, 17, 17]
a5 = [19, 19, 19, 19, 19, 19]
a6 = [23, 23, 23, 23, 23, 23]
a7 = [29.0, 29.0, 29.0, 29.0, 29.0, 29.0]
a8 = [47.0, 47.0, 47.0, 47.0, 47.0, 47.0]
a9 = [Hello, Hello, Hello, Hello, Hello, Hello]
a9 = [Hello, Hello, Hello, World, World, Hello]
*/

数据生成器

package arrays;

import net.mindview.util.Generator;

public class CountingGenerator {
    public static class
    Boolean implements Generator<java.lang.Boolean> {
        private boolean value = false;

        public java.lang.Boolean next() {
            value = !value; // Just flips back and forth 仅仅取反
            return value;
        }
    }

    public static class
    Byte implements Generator<java.lang.Byte> {
        private byte value = 0;

        public java.lang.Byte next() {
            return value++;
        }
    }

    static char[] chars = ("abcdefghijklmnopqrstuvwxyz" +
            "ABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray();

    public static class
    Character implements Generator<java.lang.Character> {
        int index = -1;

        public java.lang.Character next() {
            index = (index + 1) % chars.length;//循环读取下个字符
            return chars[index];
        }
    }

    public static class
    String implements Generator<java.lang.String> {
        private int length = 7;
        Generator<java.lang.Character> cg = new Character();//字符生成器

        public String() {//无参构造方法
        }

        public String(int length) {//指定长度构造方法
            this.length = length;
        }

        public java.lang.String next() {
            char[] buf = new char[length];
            for (int i = 0; i < length; i++)
                buf[i] = cg.next();
            return new java.lang.String(buf);
        }
    }

    public static class
    Short implements Generator<java.lang.Short> {
        private short value = 0;

        public java.lang.Short next() {
            return value++;
        }
    }

    public static class
    Integer implements Generator<java.lang.Integer> {
        private int value = 0;

        public java.lang.Integer next() {
            return value++;
        }
    }

    public static class
    Long implements Generator<java.lang.Long> {
        private long value = 0;

        public java.lang.Long next() {
            return value++;
        }
    }

    public static class
    Float implements Generator<java.lang.Float> {
        private float value = 0;

        public java.lang.Float next() {
            float result = value;
            value += 1.0;
            return result;
        }
    }

    public static class
    Double implements Generator<java.lang.Double> {
        private double value = 0.0;

        public java.lang.Double next() {
            double result = value;
            value += 1.0;
            return result;
        }
    }
}

反射

package arrays;


import net.mindview.util.Generator;

public class GeneratorsTest {
    public static int size = 10;

    public static void test(Class<?> surroundingClass) {
        for (Class<?> type : surroundingClass.getClasses()) {
            System.out.print(type.getSimpleName() + ": ");
            try {
                Generator<?> g = (Generator<?>) type.newInstance();//默认构造器
                for (int i = 0; i < size; i++)
                    System.out.printf(g.next() + " ");
                System.out.println();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static void main(String[] args) {
        test(CountingGenerator.class);
    }
}
/*
Double: 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0
Float: 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0
Long: 0 1 2 3 4 5 6 7 8 9
Integer: 0 1 2 3 4 5 6 7 8 9
Short: 0 1 2 3 4 5 6 7 8 9
String: abcdefg hijklmn opqrstu vwxyzAB CDEFGHI JKLMNOP QRSTUVW XYZabcd efghijk lmnopqr
Character: a b c d e f g h i j
Byte: 0 1 2 3 4 5 6 7 8 9
Boolean: true false true false true false true false true false
 */

随机数生成器

package arrays;

import net.mindview.util.Generator;

import java.util.*;

public class RandomGenerator {
    private static Random r = new Random(47);
    public static class
    Boolean implements Generator<java.lang.Boolean> {
        public java.lang.Boolean next() {
            return r.nextBoolean();
        }
    }
    public static class
    Byte implements Generator<java.lang.Byte> {
        public java.lang.Byte next() {
            return (byte)r.nextInt();
        }
    }
    public static class
    Character implements Generator<java.lang.Character> {
        public java.lang.Character next() {
            return CountingGenerator.chars[
                    r.nextInt(CountingGenerator.chars.length)];
        } }
    public static class
    String extends CountingGenerator.String {
        // Plug in the random Character generator:
        { cg = new Character(); } // Instance initializer
        public String() {}
        public String(int length) { super(length); }
    }
    public static class
    Short implements Generator<java.lang.Short> {
        public java.lang.Short next() {
            return (short)r.nextInt();
        }
    }
    public static class
    Integer implements Generator<java.lang.Integer> {
        private int mod = 10000;
        public Integer() {}
        public Integer(int modulo) { mod = modulo; }
        public java.lang.Integer next() {
            return r.nextInt(mod);
        }
    }
    public static class
    Long implements Generator<java.lang.Long> {
        private int mod = 10000;
        public Long() {}
        public Long(int modulo) { mod = modulo; }
        public java.lang.Long next() {
            return new java.lang.Long(r.nextInt(mod));
        }
    }
    public static class
    Float implements Generator<java.lang.Float> {
        public java.lang.Float next() {
            // Trim all but the first two decimal places:
            int trimmed = Math.round(r.nextFloat() * 100);
            return ((float)trimmed) / 100;
        } }
    public static class
    Double implements Generator<java.lang.Double> {
        public java.lang.Double next() {
            long trimmed = Math.round(r.nextDouble() * 100);
            return ((double)trimmed) / 100;
        } }
}

测试RandomGenerator

package arrays;

public class RandomGeneratorsTest {
    public static void main(String[] args) {
        GeneratorsTest.test(RandomGenerator.class);
    }
}

从Generator中创建数组

package arrays;

import net.mindview.util.CollectionData;
import net.mindview.util.Generator;

public class Generated {
    // Fill an existing array:
    public static <T> T[] array(T[] a, Generator<T> gen) {//
        return new CollectionData<T>(gen, a.length).toArray(a);
    }
    // Create a new array: 反射
    @SuppressWarnings("unchecked")
    public static <T> T[] array(Class<T> type,
                                Generator<T> gen, int size) {
        T[] a =
                (T[])java.lang.reflect.Array.newInstance(type, size);
        return new CollectionData<T>(gen, size).toArray(a);
    }
}

ArrayList.toArray(a)

a.length < size 返回 (T[]) Arrays.copyOf(elementData, size, a.getClass());
= 返回a

|返回a 且a[size]=null|

package arrays;

import java.util.Arrays;

public class TestGenerated {
    public static void main(String[] args) {
        Integer[] a = { 9, 8, 7, 6 };
        System.out.println(Arrays.toString(a));
        a = Generated.array(a,new CountingGenerator.Integer());//覆盖 but leaves the original array in place 书上翻译欠妥 保留原来的数组
        System.out.println(Arrays.toString(a));
        Integer[] b = Generated.array(Integer.class,
                new CountingGenerator.Integer(), 15);
        System.out.println(Arrays.toString(b));
    }
}
/*
[9, 8, 7, 6]
[0, 1, 2, 3]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
 */

泛型不能用于基本类型,解决用生成器填充基本类型数组

转换器:接收任意的包装器对象数组,将其转换为相应的基本类型数据

package arrays;

public class ConvertTo {
    public static boolean[] primitive(Boolean[] in) {
        boolean[] result = new boolean[in.length];
        for(int i = 0; i < in.length; i++)
            result[i] = in[i]; // Autounboxing
        return result;
    }
    public static char[] primitive(Character[] in) {
        char[] result = new char[in.length];
        for(int i = 0; i < in.length; i++)
            result[i] = in[i];
        return result;
    }
    public static byte[] primitive(Byte[] in) {
        byte[] result = new byte[in.length];
        for(int i = 0; i < in.length; i++)
            result[i] = in[i];
        return result;
    }
    public static short[] primitive(Short[] in) {
        short[] result = new short[in.length];
        for(int i = 0; i < in.length; i++)
            result[i] = in[i];
        return result;
    }
    public static int[] primitive(Integer[] in) {
        int[] result = new int[in.length];
        for(int i = 0; i < in.length; i++)
            result[i] = in[i];
        return result;
    }
    public static long[] primitive(Long[] in) {
        long[] result = new long[in.length];
        for(int i = 0; i < in.length; i++)
            result[i] = in[i];
        return result;
    }
    public static float[] primitive(Float[] in) {
        float[] result = new float[in.length];
        for(int i = 0; i < in.length; i++)
            result[i] = in[i];
        return result;
    }
    public static double[] primitive(Double[] in) {
        double[] result = new double[in.length];
        for(int i = 0; i < in.length; i++)
            result[i] = in[i];
        return result;
    }
}

package arrays;

import java.util.Arrays;

public class PrimitiveConversionDemonstration {
    public static void main(String[] args) {
        Integer[] a = Generated.array(Integer.class,
                new CountingGenerator.Integer(), 15);
        int[] b = ConvertTo.primitive(a);
        System.out.println(Arrays.toString(b));

        boolean[] c = ConvertTo.primitive(
                Generated.array(Boolean.class,
                        new CountingGenerator.Boolean(), 7));
        System.out.println(Arrays.toString(c));
    }
}
/*
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
[true, false, true, false, true, false, true]
 */

package arrays;

import java.util.Arrays;

import static net.mindview.util.Print.print;

public class TestArrayGeneration {
    public static void main(String[] args) {
        int size = 6;
        boolean[] a1 = ConvertTo.primitive(Generated.array(
                Boolean.class, new RandomGenerator.Boolean(), size));
        print("a1 = " + Arrays.toString(a1));
        byte[] a2 = ConvertTo.primitive(Generated.array(
                Byte.class, new RandomGenerator.Byte(), size));
        print("a2 = " + Arrays.toString(a2));
        char[] a3 = ConvertTo.primitive(Generated.array(
                Character.class,
                new RandomGenerator.Character(), size));
        print("a3 = " + Arrays.toString(a3));
        short[] a4 = ConvertTo.primitive(Generated.array(
                Short.class, new RandomGenerator.Short(), size));
        print("a4 = " + Arrays.toString(a4));
        int[] a5 = ConvertTo.primitive(Generated.array(
                Integer.class, new RandomGenerator.Integer(), size));
        print("a5 = " + Arrays.toString(a5));
        long[] a6 = ConvertTo.primitive(Generated.array(
                Long.class, new RandomGenerator.Long(), size));
        print("a6 = " + Arrays.toString(a6));
        float[] a7 = ConvertTo.primitive(Generated.array(
                Float.class, new RandomGenerator.Float(), size));
        print("a7 = " + Arrays.toString(a7));
        double[] a8 = ConvertTo.primitive(Generated.array(
                Double.class, new RandomGenerator.Double(), size));
        print("a8 = " + Arrays.toString(a8));
    }
}
/*
a1 = [true, false, true, false, false, true]
a2 = [104, -79, -76, 126, 33, -64]
a3 = [Z, n, T, c, Q, r]
a4 = [-13408, 22612, 15401, 15161, -28466, -12603]
a5 = [7704, 7383, 7706, 575, 8410, 6342]
a6 = [7674, 8804, 8950, 7826, 4322, 896]
a7 = [0.01, 0.2, 0.4, 0.79, 0.27, 0.45]
a8 = [0.16, 0.87, 0.7, 0.66, 0.87, 0.59]
 */

作业1 自动包装机制不能应用于数组
package arrays.e11;

public class E11 {
    public static void main(String[] args) {
        int[] pa = { 1, 2, 3, 4, 5 };
//        Integer[] wa = pa;//编译错误:类型不匹配
        Integer[] wb = { 1, 2, 3, 4, 5 };
//        int[] pb = wb;//编译错误:类型不匹配
    }
}
作业12
package arrays.e12;

import arrays.ConvertTo;
import arrays.CountingGenerator;
import arrays.Generated;

import java.util.Arrays;

public class E12 {
    public static void main(String[] args) {
        double[] doubles = ConvertTo.primitive(
                Generated.array(Double.class,new CountingGenerator.Double(),15));
        System.out.println(Arrays.toString(doubles));
    }
}

作业14
package arrays.e14;

import arrays.CountingGenerator;
import arrays.RandomGenerator;
import net.mindview.util.Generator;

import java.lang.reflect.Array;
import java.util.Arrays;

class Fill {
    public static void primitive(Object array, Generator<?> gen) {
        int size = Array.getLength(array);
        Class<?> type1 = array.getClass();// "class [Z"
        Class<?> type = array.getClass().getComponentType();
        //getComponentType :返回代 数组的组件类型的class。如果这个类不代表一个数组类,返回null
        //getClass()方法用来返回对象的类型信息(也就是在内存堆区的那一份唯一的字节码)
        for (int i = 0; i < size; i++)
            if (type == Boolean.TYPE)
                Array.setBoolean(array, i, (Boolean) gen.next());
            else if (type == Byte.TYPE)
                Array.setByte(array, i, (Byte) gen.next());
            else if (type == Short.TYPE)
                Array.setShort(array, i, (Short) gen.next());
            else if (type == Integer.TYPE)
                Array.setInt(array, i, (Integer) gen.next());
            else if (type == Character.TYPE)
                Array.setChar(array, i, (Character) gen.next());
            else if (type == Float.TYPE)
                Array.setFloat(array, i, (Float) gen.next());
            else if (type == Double.TYPE)
                Array.setDouble(array, i, (Double) gen.next());
            else if (type == Long.TYPE)
                Array.setLong(array, i, (Long) gen.next());
    }
}

public class E14 {
    public static void main(String[] args) {
        int size = 6;
        //first create all primitive arrays
        boolean[] a1 = new boolean[size];
        byte[] a2 = new byte[size];
        char[] a3 = new char[size];
        short[] a4 = new short[size];
        int[] a5 = new int[size];
        long[] a6 = new long[size];
        float[] a7 = new float[size];
        double[] a8 = new double[size];
        //now fill them with a matching generator;
        Fill.primitive(a1,new CountingGenerator.Boolean());
        System.out.println("a1 = " + Arrays.toString(a1));
        Fill.primitive(a2,new CountingGenerator.Byte());
        System.out.println("a2 = " + Arrays.toString(a2));
        Fill.primitive(a3,new CountingGenerator.Character());
        System.out.println("a3= " + Arrays.toString(a3));
        Fill.primitive(a4,new CountingGenerator.Short());
        System.out.println("a4 = " + Arrays.toString(a4));
        Fill.primitive(a5,new CountingGenerator.Integer());
        System.out.println("a5 = " + Arrays.toString(a5));
        Fill.primitive(a6,new CountingGenerator.Long());
        System.out.println("a6 = " + Arrays.toString(a6));
        Fill.primitive(a7,new CountingGenerator.Float());
        System.out.println("a7 = " + Arrays.toString(a7));
        Fill.primitive(a8,new CountingGenerator.Double());
        System.out.println("a8 = " + Arrays.toString(a8));
    }
}

7 Arrays实用功能

Arrays有static方法,其中6个基本方法
equals用于比较数组是否相等(deep Equals用于多维数组)
fill为数组填充单一元素
sort对数组排序
binarySearch在已经排序的数据中查找元素
toString产生数组的String表示
hashCode返回数组的散列码

另:Arrays.asList接受任意序列或数组 返回一个List

7.1 复制数组 System.arraycopy( )

package arrays;

import java.util.Arrays;

import static net.mindview.util.Print.print;

public class CopyingArrays {
    public static void main(String[] args) {
        int[] i = new int[7];
        int[] j = new int[10];
        Arrays.fill(i, 47);
        Arrays.fill(j, 99);
        print("i = " + Arrays.toString(i));
        print("j = " + Arrays.toString(j));
        System.arraycopy(i, 0, j, 0, i.length);
        print("j = " + Arrays.toString(j));
        int[] k = new int[5];
        Arrays.fill(k, 103);
        System.arraycopy(i, 0, k, 0, k.length);
        print("k = " + Arrays.toString(k));
        Arrays.fill(k, 103);
        System.arraycopy(k, 0, i, 0, k.length);
        print("i = " + Arrays.toString(i));
        // Objects:
        Integer[] u = new Integer[10];
        Integer[] v = new Integer[5];
//        int[] v = new int[5];// 下面的 System.arraycopy 不会执行自动包装和自动拆包,会ArrayStoreException
        Arrays.fill(u, 47);
        Arrays.fill(v, 99);
        print("u = " + Arrays.toString(u));
        print("v = " + Arrays.toString(v));
        System.arraycopy(v, 0, u, u.length/2, v.length);
        print("u = " + Arrays.toString(u));
    }
}
/*
i = [47, 47, 47, 47, 47, 47, 47]
j = [99, 99, 99, 99, 99, 99, 99, 99, 99, 99]
j = [47, 47, 47, 47, 47, 47, 47, 99, 99, 99]
k = [47, 47, 47, 47, 47]
i = [103, 103, 103, 103, 103, 47, 47]
u = [47, 47, 47, 47, 47, 47, 47, 47, 47, 47]
v = [99, 99, 99, 99, 99]
u = [47, 47, 47, 47, 47, 99, 99, 99, 99, 99]
 */
作业18 浅复制(复制对象的引用,而不是对象本身的拷贝)
package arrays.e18;

import arrays.BerylliumSphere;

import java.lang.reflect.Field;
import java.util.Arrays;

public class E18 {
    static void setID(BerylliumSphere bs,long value){
        try {
            Field fid = BerylliumSphere.class.getDeclaredField("id");//反射修改私有字段
            fid.setAccessible(true);
            fid.setLong(bs,value);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        BerylliumSphere[] a = new BerylliumSphere[4];
        Arrays.fill(a,new BerylliumSphere());
        BerylliumSphere[] b = new BerylliumSphere[4];
        System.out.println("a= " + Arrays.toString(a));
        System.out.println("b= " + Arrays.toString(b));

        System.arraycopy(a,0,b,0,b.length);
        System.out.println("b= " + Arrays.toString(b));

        //Changing a reference in 'a' will not impact 'b'
        a[1] = a[3] = new BerylliumSphere();
        System.out.println("a= " + Arrays.toString(a));
        System.out.println("b= " + Arrays.toString(b));

        // Changing an object's state will impact 'b', as well.
        setID(a[0], -1L);
        System.out.println("a = " + Arrays.toString(a));
        System.out.println("b = " + Arrays.toString(b));
    }
}
/*
a= [Sphere 0, Sphere 0, Sphere 0, Sphere 0]
b= [null, null, null, null]
b= [Sphere 0, Sphere 0, Sphere 0, Sphere 0]
a= [Sphere 0, Sphere 1, Sphere 0, Sphere 1]
b= [Sphere 0, Sphere 0, Sphere 0, Sphere 0]
a = [Sphere -1, Sphere 1, Sphere -1, Sphere 1]
b = [Sphere -1, Sphere -1, Sphere -1, Sphere -1]
 */

7.2 数组的比较

package arrays;

import java.util.Arrays;

import static net.mindview.util.Print.print;

public class ComparingArrays {
    public static void main(String[] args) {
        int[] a1 = new int[10];
        int[] a2 = new int[10];
        Arrays.fill(a1, 47);
        Arrays.fill(a2, 47);
        print(Arrays.equals(a1, a2));
        a2[3] = 11;
        print(Arrays.equals(a1, a2));
        String[] s1 = new String[4];
        Arrays.fill(s1, "Hi");
        String[] s2 = { new String("Hi"), new String("Hi"),
                new String("Hi"), new String("Hi") };
        print(Arrays.equals(s1, s2));
    }
}
/*
true
false
true
 */

所有基本类型和Object 的 equals方法
/**
     * Returns <tt>true</tt> if the two specified arrays of ints are
     * <i>equal</i> to one another.  Two arrays are considered equal if both
     * arrays contain the same number of elements, and all corresponding pairs
     * of elements in the two arrays are equal.  In other words, two arrays
     * are equal if they contain the same elements in the same order.  Also,
     * two array references are considered equal if both are <tt>null</tt>.<p>
     *
     * @param a one array to be tested for equality
     * @param a2 the other array to be tested for equality
     * @return <tt>true</tt> if the two arrays are equal
     */
    public static boolean equals(int[] a, int[] a2) {
        if (a==a2)//如果数组标识符在堆中指向的对象地址一样,返回true,如果都是null,也是true
            return true;
        if (a==null || a2==null)//如果仅有一个null,则返回false
            return false;

        int length = a.length;
        if (a2.length != length)//如果两个数组长度不等,返回false
            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)))//如果o1为null,判断o2若也为null(或 如果o1不为null,判断Object  o1和o2相相等)继续判断下个位置的对象;否则返回不相等
//                return false;
         //其他类型
            if (a[i] != a2[i])
        //处理方式不一样的基本类型  ,需要下次看,Double和Float的比较为什么不一样。
//          if (Double.doubleToLongBits(a[i])!=Double.doubleToLongBits(a2[i]))
//          if (Float.floatToIntBits(a[i])!=Float.floatToIntBits(a2[i]))

                return false;

        return true;
    }
作业19
package arrays.e19;

import java.util.Arrays;

class DataHolder{
    protected int data;
    DataHolder(int data){this.data=data;}
}

class DataHolderWithEquals extends DataHolder{

    DataHolderWithEquals(int data) {
        super(data);
    }
    public boolean equals(Object o){
        // 重载方法,
        // 判断类型一样,且int 值一样
        return o instanceof DataHolderWithEquals && data == ((DataHolderWithEquals)o).data;
    }
}
public class E19 {
    public static void main(String[] args) {
        DataHolder[] a1 = new DataHolder[5];
        DataHolder[] a2 = new DataHolder[5];
        Arrays.fill(a1,new DataHolder(1));
        Arrays.fill(a1,new DataHolder(2));
        System.out.println(Arrays.equals(a1,a2));
        Arrays.fill(a1,new DataHolderWithEquals(1));
        Arrays.fill(a2,new DataHolderWithEquals(1));
        System.out.println(Arrays.equals(a1,a2));
    }
}

作业20 多维数组的deepEquals()
package arrays.e20;

import java.util.Arrays;

public class E20 {
    public static void main(String[] args) {
        int[][] table1 = {
                {1, 2, 3},
                {4, 5},
                {6, 7, 8, 9}
        };
        int[][] table2 = {
                {1, 2, 3},
                {4, 5},
                {6, 7, 8, 9}
        };
        Integer[][] table3 = {
                {1, 2, 3},
                {4, 5},
                {6, 7, 8, 9}
        };

        int[][] table4 = {
                {1, 2, 3},
                {6, 4, 5},
                {7, 8}
        };
        System.out.println(Arrays.deepEquals(table1, table2));
        System.out.println(Arrays.deepEquals(table1, table3));
        System.out.println(Arrays.deepEquals(table1, table4));

        //手动检查table1 和talbe3
        boolean res = true;
        exit_loop://标签,类似goto
        for (int i = 0; i < table1.length; i++)
            for (int j = 0; j < table1[i].length; j++)
                if (table1[i][j] != table3[i][j]) {
                    res = false;
                    break exit_loop; //标签,类似goto
                }
        System.out.println(res);
    }
}
/*
true
false
false
true
 */

7.3 数组元素的比较

编程设计的一个主要目标是“将易变的元素与稳定的元素分开”,在这里,保持不变的代码是一般的排序算法,但是变化的是对象的比较方式。

使用策略设计模式而不是将比较代码放入许多不同的排序源码中。使用策略模式时,变化的代码部分被封装在一个单独的类(策略对象)中。

java有两种方式提供比较功能

数组中的元素实现Comparable接口 即可拥有比较功能

package arrays;

import net.mindview.util.Generator;

import java.util.Arrays;
import java.util.Random;

public class CompType implements Comparable<CompType> {
    int i;
    int j;
    private static int count = 1;
    public CompType(int n1,int n2){
        i = n1;
        j = n2;
    }

    public String toString(){
        String result = "[i = " + i + ", j = " + j + "]";
        if (count++ %3 == 0)
            result += "
";
        return result;
    }
    @Override
    public int compareTo(CompType rv) {//只比较i的值
        return (i < rv.i ? -1:(i == rv.i ? 0 :1));
    }

    private static Random r = new Random(47);
    public static Generator<CompType> generator(){
        return new Generator<CompType>() {
            @Override
            public CompType next() {
                return new CompType(r.nextInt(100),r.nextInt(100));
            }
        };
    }

    public static void main(String[] args) {
        CompType[] a = Generated.array(new CompType[12],generator());
        System.out.println("before sorting");
        System.out.println(Arrays.toString(a));
        // Arrays.sort方法内部会将参数直接转换成Comparable对象进行比较
        // 如果没有实现Comparable接口 则会报类型转换错误
        Arrays.sort(a);
        System.out.println("after sorting");
        System.out.println(Arrays.toString(a));
    }
}
/*
before sorting
[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29]
, [i = 68, j = 0], [i = 22, j = 7], [i = 88, j = 28]
, [i = 51, j = 89], [i = 9, j = 78], [i = 98, j = 61]
, [i = 20, j = 58], [i = 16, j = 40], [i = 11, j = 22]
]
after sorting
[[i = 9, j = 78], [i = 11, j = 22], [i = 16, j = 40]
, [i = 20, j = 58], [i = 22, j = 7], [i = 51, j = 89]
, [i = 58, j = 55], [i = 61, j = 29], [i = 68, j = 0]
, [i = 88, j = 28], [i = 93, j = 61], [i = 98, j = 61]
]
 */

反序排序

package arrays;

import java.util.Arrays;
import java.util.Collections;

public class Reverse {
    public static void main(String[] args) {
        CompType[] a = Generated.array(new CompType[12],CompType.generator());
        System.out.println("before sorting: ");
        System.out.println(Arrays.toString(a));
        Arrays.sort(a, Collections.reverseOrder());
        System.out.println("after sorting: ");
        System.out.println(Arrays.toString(a));
    }
}
/*
before sorting:
[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29]
, [i = 68, j = 0], [i = 22, j = 7], [i = 88, j = 28]
, [i = 51, j = 89], [i = 9, j = 78], [i = 98, j = 61]
, [i = 20, j = 58], [i = 16, j = 40], [i = 11, j = 22]
]
after sorting:
[[i = 98, j = 61], [i = 93, j = 61], [i = 88, j = 28]
, [i = 68, j = 0], [i = 61, j = 29], [i = 58, j = 55]
, [i = 51, j = 89], [i = 22, j = 7], [i = 20, j = 58]
, [i = 16, j = 40], [i = 11, j = 22], [i = 9, j = 78]
]
 */

策略模式:实现Comparator进行不同的排序策略

package arrays;

import java.util.Arrays;
import java.util.Comparator;

class CompTypeComparator implements Comparator<CompType>{

    @Override
    public int compare(CompType o1, CompType o2) {
        return (Integer.compare(o1.j, o2.j));
//        return (o1.j< o2.j ? -1:(o1.j == o2.j? 0:1));
    }
}
public class ComparatorTest {
    public static void main(String[] args) {
        CompType[] a = Generated.array(new CompType[12],CompType.generator());
        System.out.println("before sorting");
        System.out.println(Arrays.toString(a));

        Arrays.sort(a,new CompTypeComparator());
        System.out.println("after sorting");
        System.out.println(Arrays.toString(a));
    }
}
/*
before sorting
[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29]
, [i = 68, j = 0], [i = 22, j = 7], [i = 88, j = 28]
, [i = 51, j = 89], [i = 9, j = 78], [i = 98, j = 61]
, [i = 20, j = 58], [i = 16, j = 40], [i = 11, j = 22]
]
after sorting
[[i = 68, j = 0], [i = 22, j = 7], [i = 11, j = 22]
, [i = 88, j = 28], [i = 61, j = 29], [i = 16, j = 40]
, [i = 58, j = 55], [i = 20, j = 58], [i = 93, j = 61]
, [i = 98, j = 61], [i = 9, j = 78], [i = 51, j = 89]
]
 */

作业21
这个例子很不错!
package arrays.e21;

import arrays.BerylliumSphere;
import arrays.Generated;
import arrays.e15.BSGenerator;

import java.lang.reflect.Field;
import java.util.*;


class ComparableBerylliumSphere extends BerylliumSphere implements Comparable<BerylliumSphere>{
   static long getID(BerylliumSphere bs){
       try {
           Field fid = BerylliumSphere.class.getDeclaredField("id");
           fid.setAccessible(true);
           return fid.getLong(bs);
       } catch (Exception e) {
           e.printStackTrace();
           return 0L;// Bogus value 虚假的值
       }
   }

    @Override
    public int compareTo(BerylliumSphere o) {
        long id = getID(this);
        long oid = getID(o);
        return (Long.compare(id, oid));
    }
}
public class E21 {
    static void setID(BerylliumSphere bs,long value){
        try {
            Field fid = BerylliumSphere.class.getDeclaredField("id");
            fid.setAccessible(true);
            fid.setLong(bs,value);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        Random rand = new Random(47);

        BerylliumSphere[] a = Generated.array(BerylliumSphere.class,new BSGenerator(),5);
        System.out.println("Before shuffle: a = "  + Arrays.toString(a));

        Collections.shuffle(Arrays.asList(a),rand);
        System.out.println("Before sort 1: a = "  + Arrays.toString(a));

        try {
            Arrays.sort(a);
            System.out.println("After sort 1: a = " + Arrays.toString(a));
        }catch (ClassCastException e){
            System.out.println("Array cannot be sorted!");
        }

        System.out.println("***********");
        for (int i = 0;i< a.length;i++)
            a[i] = new ComparableBerylliumSphere();
        System.out.println("Before shuffle: a = "  + Arrays.toString(a));

        Collections.shuffle(Arrays.asList(a),rand);
        System.out.println("Before sort 2: a = "  + Arrays.toString(a));
        Arrays.sort(a);
        System.out.println("After sort  before rev 2: a = "  + Arrays.toString(a));
        Arrays.sort(a,Collections.reverseOrder());
        System.out.println("After rev 2: a = "  + Arrays.toString(a));
    }
}
/*
Before shuffle: a = [Sphere 0, Sphere 1, Sphere 2, Sphere 3, Sphere 4]
Before sort 1: a = [Sphere 2, Sphere 0, Sphere 4, Sphere 1, Sphere 3]
Array cannot be sorted!
***********
Before shuffle: a = [Sphere 5, Sphere 6, Sphere 7, Sphere 8, Sphere 9]
Before sort 2: a = [Sphere 8, Sphere 5, Sphere 9, Sphere 7, Sphere 6]
After sort  before rev 2: a = [Sphere 5, Sphere 6, Sphere 7, Sphere 8, Sphere 9]
After rev 2: a = [Sphere 9, Sphere 8, Sphere 7, Sphere 6, Sphere 5]
 */

7.4 数组排序

如果数组元素是基本数据类型或 实现Comparable接口 或Comparator 的对象类型 可以使用内置排序方法直接排序

针对基本类型 源码 可以看到使用的是二分排序

package arrays;

import java.util.Arrays;
import java.util.Collections;

public class StringSorting {
    public static void main(String[] args) {
        String[] sa = Generated.array(new String[20],new RandomGenerator.String(5));
        System.out.println("Before sort: " + Arrays.toString(sa));
        Arrays.sort(sa);// 大写前面,小写后面  字典编排顺序排序
        System.out.println("After sort: " + Arrays.toString(sa));
        Arrays.sort(sa, Collections.reverseOrder());
        System.out.println("Reverse sort: " + Arrays.toString(sa));
        Arrays.sort(sa,String.CASE_INSENSITIVE_ORDER);//忽略大小写
        System.out.println("Case-insensitive sort: " + Arrays.toString(sa));
    }
}

7.5 在已排序数组中查找元素

public class AlphabeticSearch {
    public static void main(String[] args) {
        String[] sa = Generated.array(new String[30],new RandomGenerator.String(5));
        Arrays.sort(sa,String.CASE_INSENSITIVE_ORDER);
        System.out.println(Arrays.toString(sa));
        int index = Arrays.binarySearch(sa,sa[10],String.CASE_INSENSITIVE_ORDER);
        System.out.println("Index: " + index + " 
" + sa[index]);
    }
}

8 总结

优选容器而不是数组

在容器引入泛型和自动包装机制之后 数组的优势几乎荡然无存,

除非发现性能问题,才会使用数组,而这种情况也是微乎其微的

原文地址:https://www.cnblogs.com/erinchen/p/11978588.html