Java编程思想—第16章 数组

  • 对数组的基本看法是,你可以创建并组装它们,通过使用整型索引值访问它们的元素,并且它们的尺寸不能改变
16.1 数组为什么特殊
  1. 数组与其他种类的容器之间的区别有三方面:效率类型保存基本类型的能力
    a. 在Java中,数组是一种效率最高的存储和访问随机对象引用序列的方式
    b. 数组就是一个简单的线性序列,这使得元素访问非常快速
    c. 但是为这种速度所付出的代价是数组对象的大小被固定,并且在其生命周期中不可改变
16.2 数组是第一级对象
  1. 无论使用哪种类型的数组,数组标识符其实只是一个引用,指向在堆中创建的一个真实对象,这个(数组)对象用以保存指向其他对象的引用。
  2. 只读成员length是数组对象的一部分(事实上,这是唯一一个可以访问的字段或方法),表示此数组对象可以存储多少元素
Integer[] a;
Integer[] b = new Integer[5];  //length是数组的大小,而不是实际保存的元素个数
a = new Integer[]{1,2,3,4};
a = {1,2,3,4};
16.3 返回一个数组
  1. 在Java中,你只是直接“返回一个数组”,而无需担心要为数组负责——只要你需要它,它就会一直存在,在你使用完后,垃圾回收器会清理掉它
16.4 多维数组
  1. 创建多位数组很方便。对于基本类型的多维数组,可以通过使用花括号将每个向量分隔开
int[][] a = {{1,2,3}, {4,5,6}}
int[][][] b = new int[2][2][4];
Arrays.deepToString(a);  //可以将多维数组转换成字符串打印
  1. 数组中构成矩阵的每个向量都可以具有任意长度(这被称为粗糙数组)
  2. 自动包装机制对数组初始化器也起作用
  3. Arrays.deepToString()方法对基本类型数组和对象都起作用
16.5 数组与泛型
  1. 通常,数组和泛型不能很好的结合。你不能实例化具有参数化类型的数组
    a. 擦除会移除参数类型信息,而数组必须知道它们所持有的确切类型,以强制保证类型安全
  2. 你可以参数化数组本身的类型
class ClassParameter<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);
    }
}
  1. 使用参数化方法而不使用参数化类的方便之处在于:你不必为需要应用的每种不同的类型都使用一个参数去实例化这个类,并且你可以将其定义为静态
  2. 尽管你不能创建实际的持有泛型的数组对象,但是你 可以创建非泛型的数组,然后将其转型
List<String>[] ls;
List[] la = New List[10];
ls = (List<String>[]) la;
ls[0] = new ArrayList<String>();
16.6 创建测试数据
  • 通常,在试验数组和程序时,能够很方便地生成填充了测试数据的数组,将会很有帮助
  1. Arrays.fill()
    a. 只能用同一个值填充各个位置,而针对对象而言,就是复制同一个引用进行填充
char[] c = new char[3];
Arrays.fill(c, 'a');
Arrays.fill(c,1,3,'b');  //对某个区域进行填充
  1. 数据生成器
    a. 通过Generator的类型来创建任何类型的数据
  2. 从Generator中创建数组
16.7 Arrays实用功能
  1. 复制数组
    a. System.arraycopy(),用它复制数组比用for循环要快很多
    b. 参数:源数组,表示从源数组中的什么位置开始复制的偏移量,目标数组,表示从目标数组的什么位置开始复制的偏移量,以及需要复制的元素个数
    c. System.arraycopy()不会执行自动包装和在自动拆包,两个数组必须具有相同的确切类型
System.arraycopy(i,0,j,0,i.length);
  1. 数组的比较
    a. Arrays类提供了重载后的equals()方法
    b. 数组相等的条件是元素个数必须相等,并且对应位置的元素也相等
    c. 对于基本类型,需要使用基本类型的包装器类的equals()方法,例如,对于int类型使用Integer.equals()作比较
Arrays.equals(a1, a2);
  1. 数组元素的比较
    a. 排序必须根据对象的实际类型执行比较操作
    b. Java有两种方式来提供比较功能
    (1)第一种是java.lang.Comparable接口,使你的类具有“天生”的比较能力
    (2)可以实现Comparator接口,Collections类包含一个reverseOrder()方法,该方法可以产生一个Comparator,它可以反转自然的排序顺序
public class CompType implements Comparable<CompType>{
    int i;
    int j;
    public CompType(int n1, int n2){
        i = n1;
        j = n2;
    }
    
    public int comparaTo(CompType rv){
        return (i < rv.i ? -1 : (i == rv.i ? 0: 1)); //递增顺序
    }
}

  1. 数组排序
    a. 使用内置的排序方法,就可以对任意的基本类型数组排序;也可以对任意的数组对象进行排序,只要该对象实现了Comparable接口或具有相关联的Comparator
Arrays.sort(sa);
Arrays.sort(sa, Collections.reverseOrder());  //反序
Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER);  //忽略大小写的字典排序
  1. 在已排序的数组中查找
    a. 如果数组已经排好序了,就可以使用Arrays.binarySearch()执行快速查找
16.8 总结
  1. 当你使用最近的Java版本编程时,应该“优先容器而不是数组”。只有在以证明性能成为问题(并且切换到数组对性能提高有所帮助)时,你才应该将程序重构为使用数组
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值