Java编程思想: 数组

数组的特殊性

数组区别于类容器在于: 效率,类型和保存基本类型的能力.

效率: 数组是线性序列,存储空间大小被固定, 则存储读取效率很高.

类型和保存类型的能力: 数组存储具体的类型, 则它在编译期间就会进行检查类型是否正确.

数组是第一级对象

无论使用哪种类型的数组, 数组标识符其实只是一个引用, 指向在堆中创建的一个真实对象, 这个数组对象用以保存指向其他对象的引用.

以下是数组的一些基本操作:

import java.util.*;

class BerylliumSphere {
  private static long counter;
  private final long id = counter++;
  public String toString() { return "Sphere " + id; }
}
public class ArrayOptions {
  public static void print(Object o) {
    System.out.println(o);
  }
  public static void main(String[] args) {
    BerylliumSphere[] a;
    BerylliumSphere[] b = new BerylliumSphere[5];
    print("b: " + Arrays.toString(b));

    BerylliumSphere[] c = new BerylliumSphere[4];
    for (int i = 0; i < c.length; i++) {
      if (c[i] == null) {
        c[i] = new BerylliumSphere();
      }
    }
    BerylliumSphere[] d = {
      new BerylliumSphere(),
        new BerylliumSphere(),
        new BerylliumSphere()
    };
    a = new BerylliumSphere[] {
      new BerylliumSphere(), new BerylliumSphere()
    };

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


    int[] e;
    int[] f = new int[5];
    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};

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

我们可以返回一个数组, 即将数组当做一个对象即可. 对于C/C++来说, 是无法做到的, 它们只能返回一个指针.

针对多维数组来说, 我们需要Arrays.deepToString()来进行显示:

import java.util.*;

public class ThreeDWithNew {
  public static void main(String[] args) {
    int[][][] a = new int[2][2][4];
    // [[[0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0]]]
    System.out.println(Arrays.deepToString(a));
    // [[[I@628b4796, [[I@2608fb65]
    System.out.println(Arrays.toString(a));
  }
}

 

数组与泛型

我们无法实例化具有参数化类型的数组:

Peel<Banana>[] peel = new Peel<>[10];

这里, 由于擦除的存在, Banana会擦除为Object类型. 但我们可以对Peel进行泛型处理:

import java.util.Arrays;

public class Test {
  public static <T> T[] f(T[] arg) {
    return arg;
  }
  public static void main(String[] args) {
    Integer[] ints = {1, 2, 3};
    Integer[] ints2 = Test.<Integer>f(ints);
    System.out.println(Arrays.toString(ints2));
  }
}

 

创建测试数据

1. 使用Arrays.fill()

import java.util.*;

public class Test {
  public static void main(String[] args) {
    int[] ints = new int[10];
    Arrays.fill(ints, 1);
    // [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
    System.out.println(Arrays.toString(ints));
  }
}

2. 将数据生成器和数组结合起来

import java.util.*;

interface Generator<T> {
  T next();
}
class CountingGenerator {
  public static class Boolean implements Generator<java.lang.Boolean> {
    private boolean value = false;
    public java.lang.Boolean next() {
      value = !value;
      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 Charater 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 Charater();
    public String() {}
    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() {
      return value++;
    }
  }
  public static class Double implements Generator<java.lang.Double> {
    private double value = 0;
    public java.lang.Double next() {
      return value++;
    }
  }
}
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.print(g.next() + " ");
        }
        System.out.println();
      } catch(Exception e) {
        throw new RuntimeException(e);
      }
    }
  }
  public static void main(String[] args) {
    test(CountingGenerator.class);
  }
}

3. 从Generator中创建数组

使用任意的Generator来产生Object子类型的数组:

import java.util.*;

class CollectionData<T> extends ArrayList<T> {
  public CollectionData(Generator<T> gen, int quantity) {
    for (int i = 0; i < quantity; i++) {
      add(gen.next());
    }
  }
  public static <T> CollectionData<T> list(Generator<T> gen, int quantity) {
    return new CollectionData<>(gen, quantity);
  }
}

class Generated {
  public static <T> T[] array(T[] a, Generator<T> gen) {
    return new CollectionData<T>(gen, a.length).toArray(a);
  }
  @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);
  }
}
public class TestGenerated {
  public static void main(String[] args) {
    Integer[] a = {9, 8, 7, 6};
    // [9, 8, 7, 6]
    System.out.println(Arrays.toString(a));
    a = Generated.array(a, new CountingGenerator.Integer());
    // [0, 1, 2, 3]
    System.out.println(Arrays.toString(a));

    Integer[] b = Generated.array(Integer.class, new CountingGenerator.Integer(), 15);
    // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
    System.out.println(Arrays.toString(b));
  }
}

 

Arrays实用功能

1. 复制数组

使用System.arraycopy来进行数组的复制.

import java.util.*;

public class CopyingArrays {
  public static void print(Object o) {
    System.out.println(o);
  }
  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, 10);
    System.arraycopy(i, 0, k, 0, k.length);
    Arrays.fill(k, 103);
    System.arraycopy(k, 0, i, 0, k.length);
    print("i = " + Arrays.toString(i));

    Integer[] u = new Integer[10];
    Integer[] v = new Integer[5];
    Arrays.fill(u, new Integer(47));
    Arrays.fill(v, new Integer(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));
  }
}

2. 数组的比较

使用equals来比较.

import java.util.*;

public class Test {
  public static void main(String[] args) {
    int[] a = new int[10];
    int[] b = new int[10];
    int[] c = new int[5];
    System.out.println(Arrays.equals(a, b));
    System.out.println(Arrays.equals(a, c));
  }
}

3. 数组元素的比较

实现Comparable接口即可.

import java.util.*;

class CompType implements Comparable<CompType> {
  public int i;
  CompType(int i) {
    this.i = i;
  }
  public int compareTo(CompType rv) {
    return (i < rv.i ? -1 : (i == rv.i ? 0: 1));
  }
}

public class Test {
  public static void main(String[] args) {
    CompType[] a = {
      new CompType(2),
      new CompType(4),
      new CompType(3),
      new CompType(1),
      new CompType(5)
    };
    Arrays.sort(a);
    for (int i = 0; i < a.length; i++) {
      System.out.print(a[i].i + " ");
    }
  }
}

 

转载于:https://my.oschina.net/voler/blog/724068

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值