数组的特殊之处

数组被创建之后,可以通过整型索引值访问他们的元素,数组的尺寸不能被更改
数组和其他容器的区别在于:效率,类型,和保存基本类型的能力。
数组一种效率最高的存储和随机访问对象引用序列的方式。
容器和数组的比较:

  1. class BerylliumSphere{
  2. private static long counter;
  3. private final long id = counter++;
  4. @Override
  5. public String toString() {
  6. return "Sphere" + id;
  7. }
  8. }
  9. public class ContainerComparison {
  10. public static void main(String[] args) {
  11. BerylliumSphere[] spheres = new BerylliumSphere[10];
  12. for (int i = 0; i < 5; i++) {
  13. spheres[i] = new BerylliumSphere();
  14. }
  15. System.out.println(Arrays.toString(spheres));
  16. System.out.println(spheres[4]);
  17. List<BerylliumSphere> sphereList = new ArrayList<>();
  18. for (int i = 0; i < 5; i++) {
  19. sphereList.add(new BerylliumSphere());
  20. }
  21. System.out.println(sphereList);
  22. System.out.println(sphereList.get(4));
  23. int[] integers = {0, 1, 2, 3, 4, 5};
  24. System.out.println(Arrays.toString(integers));
  25. System.out.println(integers[4]);
  26. List<Integer> intList = new ArrayList<>(Arrays.asList(0,1,2,3,4,5));
  27. intList.add(97);
  28. System.out.println(intList);
  29. System.out.println(intList.get(4));
  30. }
  31. }

数组的优点就是效率

数组是第一级对象

数组的标识符只是一个引用,指向在堆中创建的一个真实的对象,数组对象保存指向其他对象的引用
length是数组对象的一部分,唯一一个可以访问的字段或方法,他表示的数组的大小而不是实际保存元素的个数
对象数组保存的是引用,基本类型的数组保存的是值

  1. public class ArrayOptions {
  2. public static void main(String[] args) {
  3. BerylliumSphere[] a;
  4. BerylliumSphere[] b = new BerylliumSphere[5];
  5. System.out.println("b: " + Arrays.toString(b));
  6. BerylliumSphere[] c = new BerylliumSphere[4];
  7. for (int i = 0; i < c.length; i++) {
  8. if (c[i] == null)
  9. c[i] = new BerylliumSphere();
  10. }
  11. BerylliumSphere[] d = {new BerylliumSphere(), new BerylliumSphere(), new BerylliumSphere()};
  12. a = new BerylliumSphere[]{new BerylliumSphere(), new BerylliumSphere()};
  13. System.out.println("a.length: " + a.length);
  14. System.out.println("b.length: " + b.length);
  15. System.out.println("c.length: " + c.length);
  16. System.out.println("d.length: " + d.length);
  17. a = d;
  18. System.out.println("a.length: " + a.length);
  19. int[] e;
  20. int[] f = new int[5];
  21. System.out.println("f: " + Arrays.toString(f));
  22. int[] g = new int[4];
  23. for (int i = 0; i < g.length; i++) {
  24. g[i] = i * i;
  25. }
  26. int[] h = {47, 85, 99};
  27. System.out.println("f.length: " + f.length);
  28. System.out.println("g.length: " + g.length);
  29. System.out.println("h.length: " + h.length);
  30. e = h;
  31. System.out.println("e.length: " + e.length);
  32. e = new int[]{1, 2};
  33. System.out.println("e.length: " + e.length);
  34. }
  35. }

返回一个数组

  1. public class IceCream {
  2. private static Random rand = new Random(47);
  3. static final String[] FLAVORS = {"Chocolat", "Strawberry", "Fudge", "MiniChip"};
  4. public static String[] flavorsSet (int n) throws IllegalAccessException {
  5. if (n > FLAVORS.length){
  6. throw new IllegalAccessException("it's too big");
  7. }
  8. String[] res = new String[n];
  9. boolean[] picked = new boolean[FLAVORS.length];
  10. for (int i = 0; i < n; i++) {
  11. int t;
  12. do {
  13. t = rand.nextInt(FLAVORS.length);
  14. } while (picked[t]);
  15. res[i] = FLAVORS[t];
  16. picked[t] = true;
  17. }
  18. return res;
  19. }
  20. public static void main(String[] args) throws IllegalAccessException {
  21. for (int i = 0; i < 7; i++) {
  22. System.out.println(Arrays.toString(flavorsSet(3)));
  23. }
  24. }
  25. }

数组和泛型

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

  1. public class ArrayOfGeneric {
  2. public static void main(String[] arg){
  3. List<String>[] ls;
  4. List[] la = new List[10];
  5. ls = (List<String>[]) la;
  6. Object[] objects = ls;
  7. objects[1] = new ArrayList<Integer>();
  8. List<BerylliumSphere>[] spheres = (List<BerylliumSphere>[]) new List[10];
  9. for (int i = 0; i < spheres.length; i++) {
  10. spheres[i] = new ArrayList<BerylliumSphere>();
  11. }
  12. }
  13. }

泛型在类或者方法的边界很有效,在类或者方法的内部,因为有擦除,所以泛型变得不适用

数组的实用功能

复制数组

System.arraycopy:

  1. public class CopyingArrays {
  2. public static void main(String[] args) {
  3. int[] i = new int[7];
  4. int[] j = new int[10];
  5. Arrays.fill(i,47);
  6. Arrays.fill(j,99);
  7. System.out.println("i: " + Arrays.toString(i));
  8. System.out.println("j: " + Arrays.toString(j));
  9. System.arraycopy(i,0,j,0,i.length);
  10. System.out.println("j: " + Arrays.toString(j));
  11. int[] k = new int[5];
  12. Arrays.fill(k,103);
  13. System.out.println("k: " + Arrays.toString(k));
  14. //复制哪个数组,从哪里开始复制,粘贴到哪个数组,从哪里开始粘贴,粘贴的长度
  15. System.arraycopy(i,0,k,0,k.length);
  16. System.out.println("k: " + Arrays.toString(k));
  17. Arrays.fill(k,103);
  18. System.arraycopy(k,0,i,0,k.length);
  19. System.out.println("i: " + Arrays.toString(i));
  20. }
  21. }

数组的比较

equals:数组相等的条件是:元素个数必须相等,对应位置的元素也相等

  1. public class ComparingArrays {
  2. public static void main(String[] args) {
  3. int[] a1 = new int[10];
  4. int[] a2 = new int[10];
  5. Arrays.fill(a1, 47);
  6. Arrays.fill(a2, 47);
  7. System.out.println(Arrays.equals(a1, a2));
  8. //实用的是Arrays.equals而不是a1.equals(a2),因为后者是Object的方法
  9. a2[3] = 11;
  10. System.out.println(Arrays.equals(a1,a2));
  11. String[] s1 = new String[4];
  12. Arrays.fill(s1,"Hi");
  13. String[] s2 = {new String("Hi"), new String("Hi"), new String("Hi"), new String("Hi")};
  14. System.out.println(Arrays.equals(s1, s2));
  15. }
  16. }

数组元素的比较

第一种实现Comparable接口,是自己的类拥有ComparaTo()的方法,如果当前对象小于参数,会返回0,如果大于参数会返回一个正值
第二种是Collections工具类中的reversrOrder()方法