《Thinking in Java》学习——16章数组

数组为什么这么特殊

1.数组与其他容器之间的区别有三个方面:效率、类型和保存基本类型的能力。在Java中,数组是一种效率最高的存储和随机访问对象引用序列的方式。数组就是一个简单的线性序列,这使得元素的访问非常快速。但是为这种速度所付出的 代价是数组对象大小被固定,并且在其生命周期中不可改变。
2.随着自动包装机制的出现,容器已经能与数组几乎一样方便地用于基本类型中了。数组仅存的优点就是效率。然而,如果要解决更加一般化的问题,那数组就可能收到过多的限制,因此在这些情况下还是会使用容器。

数组是第一级对象

1.数组的制度成员length是数组对象的一部分,表示此数组对象可以存储多少元素,也就是说,length是数组的大小,而不是实际保存的元素。因此通过length询问数组的大小有一个缺点:你无法知道数组中确切地有多少个元素。
2.新生成一个数组对象时,其中所有的引用被自动初始化为null,所以检查其中引用是否为null,即可知道数组的某个位置是否存有对象。同样的,如果数组中的对象是基本类型,就会被自动初始化为相应的值。

返回一个数组

1.假设要写一个方法,而且希望它返回不止一个值,而是一组值。在Java中只需要直接“返回一个数组”,无需对数组负责——只要需要它,它就会一直存在,当使用完之后,垃圾回收器会清理掉它。

多维数组

1.Java SE5中的Arrays.deepToString()方法,可以将多维数组转换为多个String

public class ThreeDWithNew {
    public static void main(String... args) {
        int[][][] a = new int[2][2][4];
        System.out.println(Arrays.deepToString(a));
    }
}
/* Output:
[[[0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0]]]
*/

2.数组中构成矩阵的每个向量都可以具有任意长度(这被称为粗糙数组)。

数组与泛型

1.通常数组与泛型不能很好地结合。你不能实例化具有参数化类型的数组。擦除会移除参数类型信息,而数组必须知道它们所持有的确切类型,以强制保证类型安全。
2.可以参数化数组本身的类型:

public  <T> T[] f(T[] arg) {
    return arg;
}

3.编译器确实不能让你实例化泛型数组,但是,它允许你创建对这种数组的引用:

List<String>[] ls; //Success
ls = new ArrayList<String>[10]; //Illegal

尽管不能创建实际的持有泛型的数组对象,但是你可以创建非泛型的数组,然后将其转型:

public class ArrayOfGenerics {
    @SupressWarning("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>();
    }
}

问题是数组是协变类型的,因此List<String>[]也是一个Object[],并且你可以利用这一点,将一个ArrayList<Integer>赋值到你的数组中,而不会有任何编译期或运行时错误。

创建测试数据

一.Arrays.fill()

Java标准类库Arrays有一个作用十分有限的fill()方法:只能用同一个值填充哥哥位置,针对对象而言就是肤质同一个引用进行填充:

int[] a = new int[6];
Arrays.fill(a, 11);

String[] s = new String[6];
Arrays.fill(s, 3, 5,  "Hello");

使用Arrays.fill()可以填充整个数组,或者只填充数组的某个区域。但是由于只能用单一的数值来调用Arrays.fill(),因此所产生的结果并非特别有用。

二.数据生成器

1.为了以灵活的方式创建更有意义的数组,我们可以引用Generator的概念。如果某个工具使用了Generator,那么久就可以通过选择Generator的类型来创建任何类型的数据。

Arrays实用功能

一.复制数组

1.Java标准类库提供有static方法System.arraycopy(),用它复制数组比用for循环要快得多。System.arraycopy()针对所有类型做了重载:

int[] i = new int[7];
int[] j = new int[5];
Arrays.fill(j, 100);
System.arraycopy(i, 0, j, 0, j.length);

arraycopy()需要的参数有:源数组,表示从源数组中的什么位置开始复制的偏移量,表示从目标数组的什么位置开始复制的偏移量,以及需要复制的元素个数。注意避免数组越界操作。
2.System.arraycopy()不会执行自动包装和自动拆包。

二.数组的比较

1.Arrays类提供了重载后的equals()方法,用来比较整个数组。数组相等的条件是元素个数必须相等,并且对应位置的元素也相等,这可以通过对每一个元素使用equals()作比较来判断:

int[] a1 = new int[10];
int[] a2 = new int[10];
Arrays.fill(a1, 10);
Arrays.fill(a2, 10);
print(Arrays.equals(a1, a2)); //Output : true
三.数组元素的比较

1.Java有两种方式来提供比较功能,第一种是实现java.lang.Comparable接口,并实现compareTo()方法,使你的类具有天生的比较能力。第二种是创建一个实现了Comparator接口的类,实现compare()方法,有特殊需要时重写equals()方法。

四.数组排序

1.使用内置的排序方法,就可以对任意的基本类型数组进行排序;也可以对人意的对象数组进行排序,只要该对象实现了Comparable接口或具有相关联的Comparator

String[] sa = {"Java", "C++", "Python"};
Arrays.sort(sa);

Java标准类库中的排序算法针对正排序的特殊类型进行了优化——针对基本类型设计的“快速排序”,以及针对对象设计的“稳定归并排序”。所以无须担心排序的性能。

五.在已排序的数组中查找

1.如果数组已经排好序了,就可以使用Arrays.binarySearch()执行快速查找。如果要对味排序的数组使用,那么就会产生不可预料的结果:

int[] a = {1, 2, 3, 4, 5};
Arrays.sort(a);
int position = Arrays.binarySearch(a, 3);

2.如果找到了目标,Arrays.binarySearch()产生的返回值等于或大于0.否则,它产生负返回值,表示若要保持数组的排序状态此目标元素所应该插入的位置。这个负值的计算方式为:
- (插入点) - 1
插入点是指,第一个大雨查找对象的元素在数组中的位置。
3.搜索算法不是专为包含重复元素的数组而设计的,虽然仍可用,但是无法保证找到的是这些副本中的哪一个。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容