JAVA面向对象基础-容器

发布时间:2024年01月09日

一、泛型

? ? ??我们可以在类的声明处增加泛型列表,如:<T,E,V>。

? ? ??此处,字符可以是任何标识符,一般采用这3个字母。

【示例9-1】泛型类的声明

1

2

3

4

5

6

7

8

9

10

class?MyCollection<E>?{//?E:表示泛型;

????Object[]?objs?=?new?Object[5];

????public?E?get(int?index)?{//?E:表示泛型;

????????return?(E)?objs[index];

????}

????public?void?set(E?e,?int?index)?{//?E:表示泛型;

????????objs[index]?=?e;

????}

}

? ? ??泛型E像一个占位符一样表示“未知的某个数据类型”,我们在真正调用的时候传入这个“数据类型”。

【示例9-2】泛型类的应用

1

2

3

4

5

6

7

8

9

10

public?class?TestGenerics?{

????public?static?void?main(String[]?args)?{

????????//?这里的”String”就是实际传入的数据类型;

????????MyCollection<String>?mc?=?new?MyCollection<String>();

????????mc.set("aaa",?0);

????????mc.set("bbb",?1);

????????String?str?=?mc.get(1);?//加了泛型,直接返回String类型,不用强制转换;

????????System.out.println(str);

????}

}

二、Collection接口

? Collection 表示一组对象,它是集中、收集的意思。Collection接口的两个子接口是List、Set接口。

表9-1 Collection接口中定义的方法

? ? ??由于List、Set是Collection的子接口,意味着所有List、Set的实现类都有上面的方法。我们下一节中,通过ArrayList实现类来测试上面的方法。

三、List特点和常用方法

List是有序、可重复的容器。

? ? ??有序:List中每个元素都有索引标记。可以根据元素的索引标记(在List中的位置)访问元素,从而精确控制这些元素。

? ? ??可重复:List允许加入重复的元素。更确切地讲,List通常允许满足 e1.equals(e2) 的元素重复加入容器。

? ? ??除了Collection接口中的方法,List多了一些跟顺序(索引)有关的方法,参见下表:

表9-2List接口中定义的方法

? ? ??List接口常用的实现类有3个:ArrayList、LinkedList和Vector。

【示例9-4】List的常用方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

public?class?TestList?{

????/**

?????*?测试add/remove/size/isEmpty/contains/clear/toArrays等方法

?????*/

????public?static?void?test01()?{

????????List<String>?list?=?new?ArrayList<String>();

????????System.out.println(list.isEmpty());?//?true,容器里面没有元素

????????list.add("高淇");

????????System.out.println(list.isEmpty());?//?false,容器里面有元素

????????list.add("高小七");

????????list.add("高小八");

????????System.out.println(list);

????????System.out.println("list的大小:"?+?list.size());

????????System.out.println("是否包含指定元素:"?+?list.contains("高小七"));

????????list.remove("高淇");

????????System.out.println(list);

????????Object[]?objs?=?list.toArray();

????????System.out.println("转化成Object数组:"?+?Arrays.toString(objs));

????????list.clear();

????????System.out.println("清空所有元素:"?+?list);

????}

????public?static?void?main(String[]?args)?{

????????test01();

????}

}

? ? ??执行结果如图9-3所示:

【示例9-5】两个List之间的元素处理

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

public?class?TestList?{

????public?static?void?main(String[]?args)?{

????????test02();

????}

????/**

?????*?测试两个容器之间元素处理

?????*/

????public?static?void?test02()?{

????????List<String>?list?=?new?ArrayList<String>();

????????list.add("高淇");

????????list.add("高小七");

????????list.add("高小八");

????????List<String>?list2?=?new?ArrayList<String>();

????????list2.add("高淇");

????????list2.add("张三");

????????list2.add("李四");

????????System.out.println(list.containsAll(list2));?//false?list是否包含list2中所有元素

????????System.out.println(list);

????????list.addAll(list2);?//将list2中所有元素都添加到list中

????????System.out.println(list);

????????list.removeAll(list2);?//从list中删除同时在list和list2中存在的元素

????????System.out.println(list);

????????list.retainAll(list2);?//取list和list2的交集

????????System.out.println(list);

????}

}

? ? ? 执行结果如图9-4所示:

图9-4 示例9-5运行效果图

【示例9-6】List中操作索引的常用方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

public?class?TestList?{

????public?static?void?main(String[]?args)?{

????????test03();

????}

????/**

?????*?测试List中关于索引操作的方法

?????*/

????public?static?void?test03()?{

????????List<String>?list?=?new?ArrayList<String>();

????????list.add("A");

????????list.add("B");

????????list.add("C");

????????list.add("D");

????????System.out.println(list);?//?[A,?B,?C,?D]

????????list.add(2,?"高");

????????System.out.println(list);?//?[A,?B,?高,?C,?D]

????????list.remove(2);

????????System.out.println(list);?//?[A,?B,?C,?D]

????????list.set(2,?"c");

????????System.out.println(list);?//?[A,?B,?c,?D]

????????System.out.println(list.get(1));?//?返回:B

????????list.add("B");

????????System.out.println(list);?//?[A,?B,?c,?D,?B]

????????System.out.println(list.indexOf("B"));?//?1?从头到尾找到第一个"B"

????????System.out.println(list.lastIndexOf("B"));?//?4?从尾到头找到第一个"B"

????}

}

? ? ??执行结果如图9-5所示:

三、Map接口-HashMap和HashTable

Map就是用来存储“键(key)-值(value) 对”的

Map类中存储的“键值对”通过键来标识,所以“键对象”不能重复(根据equals方法),否则新的会覆盖旧的

Map 接口的实现类有HashMap、TreeMap、HashTable、Properties等

HashMap底层实现采用了哈希表,这是一种非常重要的数据结构。希表的本质就是“数组+链表”

Entry[] table 就是HashMap的核心数组结构,我们也称之为“位桶数组”。一个Entry对象存储了:

  • key:键对象,value:值对象
  • next:下一个节点
  • hash: 键对象的hash值

Entry[]数组的结构:

存储数据过程put(key,value)

? 当添加一个元素(key-value)时,首先计算key的hash值,以此确定插入数组中的位置,但是可能存在同一hash值的元素已经被放在数组同一位置了,这时就添加到同一hash值的元素的后面,他们在数组的同一位置,就形成了链表,同一个链表上的Hash值是相同的,所以说数组存放的是链表。

HashMap

?HashMap采用哈希算法实现,是Map接口最常用的实现类。 由于底层采用了哈希表存储数据,我们要求键不能重复,如果发生重复,新的键值对会替换旧的键值对。 HashMap在查找、删除、修改方面都有非常高的效率。

【示例9-7】Map接口中的常用方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

public?class?TestMap?{

????public?static?void?main(String[]?args)?{

????????Map<Integer,?String>?m1?=?new?HashMap<Integer,?String>();

????????Map<Integer,?String>?m2?=?new?HashMap<Integer,?String>();

????????m1.put(1,?"one");

????????m1.put(2,?"two");

????????m1.put(3,?"three");

????????m2.put(1,?"一");

????????m2.put(2,?"二");

????????System.out.println(m1.size());

????????System.out.println(m1.containsKey(1));

????????System.out.println(m2.containsValue("two"));

????????m1.put(3,?"third");?//键重复了,则会替换旧的键值对

????????Map<Integer,?String>?m3?=?new?HashMap<Integer,?String>();

????????m3.putAll(m1);

????????m3.putAll(m2);

????????System.out.println("m1:"?+?m1);

????????System.out.println("m2:"?+?m2);

????????System.out.println("m3:"?+?m3);

????}

}

? ? ??执行结果如图9-11所示:

HashTable

? ? ? HashTable类和HashMap用法几乎一样,底层实现几乎一样,只不过HashTable的方法添加了synchronized关键字确保线程同步检查,效率较低。

HashMap与HashTable的区别

? ? ??1. HashMap: 线程不安全,效率高。允许key或value为null。

? ? ??2. HashTable: 线程安全,效率低。不允许key或value为null。

四、Set接口-HashSet基本使用

大家在做下面练习时,重点体会“Set是无序、不可重复”的核心要点。

【示例9-9】HashSet的使用

1

2

3

4

5

6

7

8

9

10

11

12

13

14

public?class?Test?{

????public?static?void?main(String[]?args)?{

????????Set<String>?s?=?new?HashSet<String>();

????????s.add("hello");

????????s.add("world");

????????System.out.println(s);

????????s.add("hello");?//相同的元素不会被加入

????????System.out.println(s);

????????s.add(null);

????????System.out.println(s);

????????s.add(null);

????????System.out.println(s);

????}

}

? ? ??执行结果如图9-24所示:

五、Collections工具类

类 java.util.Collections 提供了对Set、List、Map进行排序、填充、查找元素的辅助方法。

? ? ??1. void sort(List) //对List容器内的元素排序,排序的规则是按照升序进行排序。

? ? ??2. void shuffle(List) //对List容器内的元素进行随机排列。

? ? ??3. void reverse(List) //对List容器内的元素进行逆续排列 。

? ? ??4. void fill(List, Object) //用一个特定的对象重写整个List容器。

? ? ??5. int binarySearch(List, Object)//对于顺序的List容器,采用折半查找的方法查找特定对象。

【示例9-23】Collections工具类的常用方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

public?class?Test?{

????public?static?void?main(String[]?args)?{

????????List<String>?aList?=?new?ArrayList<String>();

????????for?(int?i?=?0;?i?<?5;?i++){

????????????aList.add("a"?+?i);

????????}

????????System.out.println(aList);

????????Collections.shuffle(aList);?//?随机排列

????????System.out.println(aList);

????????Collections.reverse(aList);?//?逆续

????????System.out.println(aList);

????????Collections.sort(aList);?//?排序

????????System.out.println(aList);

????????System.out.println(Collections.binarySearch(aList,?"a2"));?

????????Collections.fill(aList,?"hello");

????????System.out.println(aList);

????}

}

? ? ??执行结果如图9-31所示:

文章来源:https://blog.csdn.net/Aurora_m/article/details/135472987
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。