TJI读书笔记15-持有对象

Posted 吾码2016

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TJI读书笔记15-持有对象相关的知识,希望对你有一定的参考价值。

 

 

总览

It’s a fairly simple program that only has a fixed quantity of objects with known lifetimes.
埃大爷开篇说了那么一句话.

通常情况下,程序总在运行时才知道根据某些条件创建新的对象,在此之前不知道对象的数量,甚至不知道对象的类型. 这样对程序设计来说就会有个问题,如何在任意时间任意位置去创建任意数量的对象. 当然,数组是一种很好的解决方案,但是数组具有固定的大小,适应问题的灵活度不是很高. 很多时候会显得不够灵活.

java.util类库中提供了一套相当完备的容器类来解决这个问题. 如下图.

.1474462428722

java的容器类是用来保存对象的.可以划分为两种概念:

  • Collection:是一个元素序列,这些元素序列都服从一定的规则. 比如,list是按照插入顺序保存的元素. set是没有重复的元素集合,queue是按照队列规则保存的元素序列.
  • Map:map又叫做关联数组,字典. 是一种”键值对”

类型安全和泛型

java1.5之前,容器类在编译期是没有类型检查一说的. 也就是说,存入容器中的对象都会向上转型成Object类型,再次取出的时候,需要做强转. 那这样就会带来类型安全的问题. 像下面这段代码,如果在add apple的时候混入了orange,那就悲剧了.

1.import java.util.ArrayList;
2.
3.class Apple{
4. private static long counter;
5. private final long id = counter++;
6. public void id() {
7. System.out.println(id);
8. }
9.}
10.
11.class Orange{}
12.
13.public class ApplesAndOrangesWithoutGenerics {
14. @SuppressWarnings("unchecked")
15. public static void main(String[] args) {
16. ArrayList apples = new ArrayList();
17. for(int i = 0;i<3;i++){
18. apples.add(new Apple());
19. }
20.
21. for(int i =0;i<apples.size();i++){
22. ((Apple)apples.get(i)).id();
23. }
24. }
25.}

在java1.5之后,提供了泛型支持. 在定义容器的时候,可以声明成ArrayList<Apple> 也就是说,在编译过程中会做类型检查. 在从容器中取出时也可以保证是原来的类型. 泛型会在后面的章节详细介绍. 但是这里需要说一句,向上转型也可以作用于泛型.(这是埃大爷的原话,太学术范儿了,说白了就是,这个类型检查只检查是不是属于该类及其子类)

1.import java.util.ArrayList;
2.
3.
4.class Apple{
5. private static long counter;
6. private final long id = counter++;
7. public void id() {
8. System.out.println(id);
9. }
10.}
11.
12.class Orange{}
13.
14.class Fushi extends Apple{}
15.
16.public class ApplesAndOrangesWithoutGenerics {
17.
18. public static void main(String[] args) {
19.
20. ArrayList<Apple> apples = new ArrayList<>();
21. apples.add(new Apple());
22. apples.add(new Fushi());
23. apples.add(new Apple());
24.
25. for(int i =0;i<apples.size();i++){
26. apples.get(i).id();
27. System.out.println(apples.get(i).getClass());
28. }
29. }
30.}/*output:
31.0
32.class ch11_holdyourObject.Apple
33.1
34.class ch11_holdyourObject.Fushi
35.2
36.class ch11_holdyourObject.Apple
37.*/

Collection接口

Collection概括了一个序列的概念. 是一种存放对象的方式.

1.import java.util.ArrayList;
2.import java.util.Collection;
3.
4.public class SimpleCollection {
5. public static void main(String[] args) {
6. Collection<Integer> c = new ArrayList<>();
7. for(int i =0;i<10;i++){
8. c.add(i);
9. }
10. for(Integer i:c){
11. System.out.println(i);
12. }
13.
14. }
15.}

很简单的例子,没啥好说的. 但是有一点,这里注意ArrayList的声明方式. 更多的是,我们会采用这么一种方式来声明. 创建一个具体的容器类对象,然后转型成对应的接口.在之后的代码里都使用这个接口. 当然把ArrayList转成Collection有点不合适…
这种做法在后期如果需要做代码优化的时候就会很方便. 比如,发现ArrayList实际表现性能不如LinkedList的时候. 基本只需要修改一行代码就可以了.

添加元素

Collection 添加单个元素很简单,直接add()方法就可以了. 如果想添加一组元素的时候,可以使用Collection自己的addAll方法. 但是更多时候,我们使用的是其工具类Collections.addAll()方法.

1.import java.util.ArrayList;
2.import java.util.Arrays;
3.import java.util.Collection;
4.import java.util.Collections;
5.
6.public class AddingGroup {
7. public static void main(String[] args) {
8. Collection<Integer> collection = new ArrayList<>();
9.// collection = Arrays.asList(1,2,3,4,5);
10.
11. Integer[] arrInt = {9,8,7,6};
12. collection.addAll(Arrays.asList(arrInt));
13. Collections.addAll(collection, 11,12,13);
14.
15. System.out.println(collection);
16. }
17.}

这里有一个地方需要注意,如果直接将Arrays.asList()的返回值直接传递给list,这个时候虽然表面上看是个list,但是其底层表示的是数组. 因此不能调整尺寸. 这个时候如果使用add或者delete的时候,会报UnSupported Operation的错误.

List

List接口承诺将元素维护在特定的序列之中.而常见的LIst的实现有两种:

  • ArrayList:通过名字就可以看出来,ArrayList是一种底层靠数组实现的list,随机访问性能良好,但是插入和移除的时候,开销较大
  • LinkedList:通过链表实现,插入和删除时代价较低.但是相比ArrayList随机访问性能较差.

这次真的是一码解千愁了,埃大爷的这逻辑真的不得不让人佩服. 我把结果直接注释到了代码的下面. 我们来看一下:

1.import java.util.ArrayList;
2.import java.util.Arrays;
3.import java.util.Collections;
4.import java.util.List;
5.import java.util.Random;
6.
7.import typeinfo.pets.Cymric;
8.import typeinfo.pets.Hamster;
9.import typeinfo.pets.Mouse;
10.import typeinfo.pets.Pet;
11.import typeinfo.pets.Pets;
12.
13.public class ListFeature {
14. public static void main(String[] args) {
15. Random rand = new Random(47);
16. List<Pet> pets = Pets.arrayList(7);
17. System.out.println("1: " + pets);
18. //1: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug]
19.
20. Hamster h = new Hamster();
21. pets.add(h); // Automatically resizes
22. System.out.println("2: " + pets);
23. //2: [Rat, Manx, Cymric, Mutt, Pug, Cymric, Pug, Hamster]
24.
25. System.out.println("3: " + pets.contains(h));
26. //3: true
27.
28. pets.remove(h); // Remove by object
29. Pet p = pets.get(2);
30. System.out.println("4: " + p + " " + pets.indexOf(p));
31. //4: Cymric 2
32.
33. Pet cymric = new Cymric();
34. System.out.println("5: " + pets.indexOf(cymric));
35. //5: -1
36.
37. System.out.println("6: " + pets.remove(cymric));
38. //6: false
39.
40. // Must be the exact object:
41. System.out.println("7: " + pets.remove(p));
42. //7: true
43.
44. System.out.println("8: " + pets);
45. //8: [Rat, Manx, Mutt, Pug, Cymric, Pug]
46.
47.
48. pets.add(3, new Mouse()); // Insert at an index
49. System.out.println("9: " + pets);
50. //9: [Rat, Manx, Mutt, Mouse, Pug, Cymric, Pug]
51.
52. List<Pet> sub = pets.subList(1, 4);
53. System.out.println("subList: " + sub);
54. //subList: [Manx, Mutt, Mouse]
55.
56. System.out.println("10: " + pets.containsAll(sub));
57. //10: true
58.
59. Collections.sort(sub); // In-place sort
60. System.out.println("sorted subList: " + sub);
61. //sorted subList: [Manx, Mouse, Mutt]
62.
63. // Order is not important in containsAll():
64. System.out.println("11: " + pets.containsAll(sub));
65. //11: true
66.
67.
68. Collections.shuffle(sub, rand); // Mix it up
69. System.out.println("shuffled subList: " + sub);
70. //shuffled subList: [Mouse, Manx, Mutt]
71.
72. System.out.println("12: " + pets.containsAll(sub));
73. //12: true
74.
75. List<Pet> copy = new ArrayList<Pet>(pets);
76. sub = Arrays.asList(pets.get(1), pets.get(4));
77. System.out.println("sub: " + sub);
78. //sub: [Mouse, Pug]
79.
80. copy.retainAll(sub);
81. System.out.println("13: " + copy);
82. //13: [Mouse, Pug]
83.
84. copy = new ArrayList<Pet>(pets); // Get a fresh copy
85. copy.remove(2); // Remove by index
86. System.out.println("14: " + copy);
87. //14: [Rat, Mouse, Mutt, Pug, Cymric, Pug]
88.
89.
90. copy.removeAll(sub); // Only removes exact objects
91. System.out.println("15: " + copy);
92. //15: [Rat, Mutt, Cymric, Pug]
93.
94. copy.set(1, new Mouse()); // Replace an element
95. System.out.println("16: " + copy);
96. //16: [Rat, Mouse, Cymric, Pug]
97.
98. copy.addAll(2, sub); // Insert a list in the middle
TJI读书笔记11-多态

TJI读书笔记10-复用类

TJI读书笔记09-访问控制权限

TJI读书笔记12-接口

TJI读书笔记16-异常处理

TJI读书笔记07-初始化