JAVA面向对象基础-容器

一、泛型

我们可以在类的声明处增加泛型列表,如:<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-2 List接口中定义的方法

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所示:

相关推荐
一百天成为python专家18 分钟前
python库之jieba 库
开发语言·人工智能·python·深度学习·机器学习·pycharm·python3.11
Go Dgg40 分钟前
【Go + Gin 实现「双 Token」管理员登录】
开发语言·golang·gin
27669582921 小时前
tiktok 弹幕 逆向分析
java·python·tiktok·tiktok弹幕·tiktok弹幕逆向分析·a-bogus·x-gnarly
十五年专注C++开发1 小时前
hiredis: 一个轻量级、高性能的 C 语言 Redis 客户端库
开发语言·数据库·c++·redis·缓存
WJ.Polar1 小时前
Python数据容器-集合set
开发语言·python
晓13131 小时前
JavaScript加强篇——第七章 浏览器对象与存储要点
开发语言·javascript·ecmascript
用户40315986396631 小时前
多窗口事件分发系统
java·算法
用户40315986396631 小时前
ARP 缓存与报文转发模拟
java·算法
小林ixn1 小时前
大一新手小白跟黑马学习的第一个图形化项目:拼图小游戏(java)
java
nbsaas-boot2 小时前
Go语言生态成熟度分析:为何Go还无法像Java那样实现注解式框架?
java·开发语言·golang