Java集合框架 List集合、Set集合、Map集合 学习泛型与包装类的装箱拆箱
集合框架:
图中接口说明:
- Collection :用来存储管理一组对象 objects ,这些对象一般被成为元素 elements
- Set : 元素不能重复,背后隐含着查找/搜索的语义
- SortedSet : 一组有序的不能重复的元素
- List : 线性结构
- Queue : 队列
- Deque : 双端队列
- Map : 键值对 Key-Value-Pair ,背后隐含着查找/搜索的语义
- SortedMap : 一组有序的键值对
Collection:单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是List和Set。其中,List的特点是元素有序、元素可重复。Set的特点是元素无序,而且不可重复。List接口的主要实现类有ArrayList和LinkedList。Set接口的主要实现类有HashSet和TreeSet。
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
collection.add("aaa");
System.out.println(collection.contains("aaa"));
System.out.println(collection.equals("aaa"));
System.out.println(collection.isEmpty());
collection.remove("aaa");
System.out.println(collection.isEmpty());
}
Map:双列集合类的根接口,用于存储具有键(Key)、值(Value)映射关系的元素,每个元素都包含一对键值,在使用Map集合时可以通过指定的Key找到对应的Value,例如根据一个学生的学号就可以找到对应的学生。Map接口的主要实现类有HashMap和TreeMap。
public static void main(String[] args) {
//
Map<String, String> map = new HashMap<>();
System.out.println(map.isEmpty());
System.out.println(map.size());
map.put("Zero", "000");
map.put("One", "111");
map.put("Two", "222");
System.out.println(map.containsKey("Zero"));
System.out.println(map.containsValue("222"));
System.out.println(map.get("Two"));
System.out.println(map.size());
map.put("Three", "333");
System.out.println(map.size());
System.out.println(map.get("Fore"));
System.out.println(map.getOrDefault("Fore", "444"));
for (Map.Entry<String , String> entry : map.entrySet()
) {
System.out.println(entry);
}
System.out.println(map.keySet());
System.out.println(map.values());
map.remove("Zero");
for (Map.Entry<String , String> entry : map.entrySet()
) {
System.out.println(entry);
}
System.out.println(map.remove("One", "111"));
for (Map.Entry<String , String> entry : map.entrySet()
) {
System.out.println(entry);
}
map.replace("Two", "二二二");
map.replace("Three", "333", "三三三");
for (Map.Entry<String , String> entry : map.entrySet()
) {
System.out.println(entry);
}
map.replace("Three", "222", "333");
for (Map.Entry<String , String> entry : map.entrySet()
) {
System.out.println(entry);
}
}
Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合
List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且还增加了一些根据元素索引来操作集合的特有方法,如下表所示。
在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口Iterator。Iterator接口也是Java集合中的一员,但它与Collection、Map接口有所不同,Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也被称为迭代器。
虽然Iterator可以用来遍历集合中的元素,但写法上比较繁琐,为了简化书写,从JDK5.0开始,提供了foreach循环。foreach循环是一种更加简洁的for循环,也称增强for循环。foreach循环用于遍历数组或集合中的元素,其具体语法格式如下:
for (Map.Entry<String , String> entry : map.entrySet()
) {
System.out.println(entry);
}
为了便于Map接口的学习,首先来了解一下Map接口中定义的一些常用方法,如下表所示。
JDK5.0新特性—泛型
集合可以存储任何类型的对象,但是当把一个对象存入集合后,集合会“忘记”这个对象的类型,将该对象从集合中取出时,这个对象的编译类型就变成了Object类型。换句话说,在程序中无法确定一个集合中的元素到底是什么类型的。那么在取出元素时,如果进行强制类型转换就很容易出错。
注意:
- 泛型是作用在编译期间的一种机制,即运行期间没有泛型的概念。
- 泛型代码在运行期间,利用 Object 达到的效果。
// 1. 尖括号 <> 是泛型的标志
// 2. E 是类型变量(Type Variable),变量名一般要大写
// 3. E 在定义时是形参,代表的意思是 MyArrayList 最终传入的类型,但现在还不知道
public class MyArrayList<E> {
private E[] array;
//特殊注意
private E[] arrays = (E[]) new Obijct[100];
private int size;
...
}
// 定义了一个元素是 Book 引用的
MyArrayList MyArrayList<Book> books = new MyArrayList<Book>();
books.add(new Book());
// 会产生编译错误,Person 类型无法转换为 Book 类型
books.add(new Person());
// 不需要做类型转换
Book book = book.get(0);
// 不需要做类型转换
// 会产生编译错误,Book 类型无法转换为 Person 类型
Person person = book.get(0);
//Book 只能想象成 E 的类型,但实际上 E 的类型还是 Object。
包装类的使用,装箱(boxing)拆箱(unboxing):
int i = 10;
// 装箱操作,新建一个 Integer 类型对象,将 i 的值放入对象的某个属性中
Integer ii = Integer.valueOf(i);
Integer ij = new Integer(i);
// 拆箱操作,将 Integer 对象中的值取出,放到一个基本数据类型中
int j = ii.intValue();
int i = 10;
//自动装箱
Integer ii = i;
Integer ij = (Integer)i;
//自动拆箱
int j = i;
int k = (int)i;
简而言之:
装箱:基本类型=》包装类
拆箱:包装类=》基本类型