集合类是 Java 数据结构的实现。Java 的集合类是 java.util 包中的重要内容,它允许以各种方式将元素分组,并定义了各种使这些元素更容易操作的方法。Java 集合类是 Java 将一些基本的和使用频率极高的基础类进行封装和增强后再以一个类的形式提供。集合类是可以往里面保存多个对象的类,存放的是对象,不同的集合类有不同的功能和特点,适合不同的场合,用以解决一些实际问题。
一、泛型
Java 泛型的参数只可以代表类,不能代表个别对象。由于 Java 泛型的类型参数的实际类型在编译时会被消除,所以无法在运行时得知其类型参数的类型。Java 编译器在编译泛型时会自动加入类型转换的编码,故运行速度不会因为使用泛型而加快。
1.1 含有泛型的类
// 含有泛型的类
public class Demo<E> {
private E value;
public E getValue() {
return value;
}
public void setValue(E value) {
this.value = value;
}
}
// 测试类
public class Test {
public static void main(String[] args) {
// 确定泛型
Demo<String> s = new Demo<>();
s.setValue("hello");
System.out.println(s.getValue());
}
}
1.2 含有泛型的方法
public class Test {
public static void main(String[] args) {
// 确定泛型
method(100); // 自动装箱 Integer
method("nihao");
method(2.5); // 自动装箱 Double
}
// 含有泛型的方法
public static <E> void method(E e) {
System.out.println(e);
}
}
1.3 含有泛型的接口
// 含有泛型的接口
public interface Demo1<E> {
abstract void method(E e);
}
// 第一种方式,在声明时确定泛型
public class Test implements Demo1<String>{
@Override
public void method(String s) {
System.out.println(s);
}
}
// 第二种方式,在创建对象时确定泛型
public class Demo2<E> implements Demo1<E> {
@Override
public void method(E e) {
System.out.println(e);
}
}
public class Test{
public static void main(String[] args) {
Demo2<String> d = new Demo2<>();
}
}
1.4 泛型通配符
<?>:泛型可以是任意类型
<? extends E>:泛型是能是E的子类或自己
<? super E>:泛型只能是E的父类或自己
1.5 注意事项
在使用时必须要确定泛型的类型。
在 Java7 以前Demo<String> s = new Demo<String>()
两边尖括号的类型必须都写,不能省略。从 Java7 开始,Java 允许在构造器后不需要带完整的泛型信息,只要给出一对尖括号<>
即可,Java 可以推断尖括号里应该是什么泛型信息。即可以改写为: Demo<String> s = new Demo<>()
E - Element (在集合中使用,因为集合中存放的是元素)、T - Type(Java 类)、K - Key(键)、 V - Value(值)、 N - Number(数值类型)、? - 表示不确定的java类型
二、集合
java.util 包中的集合类就像一个装有多个对象的容器,提到容器就不难想到数组,数组与集合的不同之处在于:数组的长度是固定的,集合的长度是可变的;数组既可以存放基本类型的数据,又可以存放对象,集合只能存放对象。集合类包括 List 集合、Set 集合和 Map 集合,其中 List 与 Set 继承了 Collection 接口,且 List 接口、Set 接口和 Map 接口还提供了不同的实现类。
2.1 集合继承体系
2.2 Collection
Set 接口和 List 接口都继承于 Collection 接口。Collection 接口虽然不能直接被使用,但提供了操作集合以及集合中元素的方法,且 Set 接口和 List 接口都可以调用 Collection 接口中的方法。
2.2.1 常用方法
方法名 | 说明 |
boolean add(E e) | 向集合添加元素 e,若指定集合元素改变了则返回 true |
boolean addAll(Collection<? extends E> c) | 把集合 C 中的元素全部添加到集合中,若指定集合元素改变返回 true |
void clear() | 清空所有集合元素 |
boolean contains(Object o) | 判断指定集合是否包含对象 o |
boolean containsAll(Collection<?> c) | 判断指定集合是否包含集合 c 的所有元素 |
boolean isEmpty() | 判断指定集合的元素 size 是否为 0 |
boolean remove(Object o) | 删除集合中的元素对象 o,若集合有多个 o 元素,则只删除第一个元素 |
boolean removeAll(Collection<?> c) | 删除指定集合包含集合 c 的元素 |
boolean retainAll(Collection<?> c) | 从指定集合中保留包含集合 c 的元素,其他元素则删除 |
int size() | 集合的元素个数 |
T[ ] toArray(T[ ] a) | 将集合转换为T类型的数组 |
2.2.2 示例
public class DemoCollection {
public static void main(String[] args) {
//多态,创建集合
Collection<String> coll = new ArrayList<>();
//添加字符串进集合
coll.add("华为");
coll.add("联想");
coll.add("神舟");
coll.add("小米");
coll.add("中兴");
System.out.println(coll); //[华为, 联想, 神舟, 小米, 中兴]
//判断是否包含 "华为"
System.out.println(coll.contains("华为")); //true
//移除 "联想"
System.out.println(coll.remove("联想")); //true
//清空集合
coll.clear();
//判断集合是否为空
System.out.println(coll.isEmpty()); //true
}
}
2.2 迭代器
Iterator 接口也是 Java 集合框架的成员,但它与 Collection 集合、Map 集合不一样:Collection 集合、Map 集合主要用于盛装其他对象,而 Iterator 则主要用于遍历(即迭代访问) Collection 集合中的元素,Iterator 对象也被称为迭代器。Iterator 接口隐藏了各种 Collection 实现类的底层细节,向应用程序提供了遍历 Collection 集合元素的统一编程接口。
2.2.1 常用方法
方法名 | 说明 |
boolean hasNext() | 如果被迭代的集合元素还没有被遍历完,则返回 true |
Object next() | 返回集合里的下一个元素 |
void remove() | 删除集合里上一次next方法返回的元素 |
void forEachRemaining(Consumer action) | Java 8 为 Iterator 新增的默认方法,该方法可使用 Lambda 表达式来遍历集合元素 |
2.2.2 示例
public class DemoCollection {
public static void main(String[] args) {
//多态,创建集合
Collection<String> coll = new ArrayList<>();
//添加字符串进集合
coll.add("华为");
coll.add("联想");
coll.add("神舟");
coll.add("小米");
coll.add("中兴");
System.out.println(coll); //[华为, 联想, 神舟, 小米, 中兴]
//创建迭代器
Iterator<String> iterator = coll.iterator();
//判断集合中是否有下一个元素
while (iterator.hasNext()) {
//取出下一个元素,next后移一位
String next = iterator.next();
System.out.println(next );
}
}
}
2.2.3 注意事项
当使用 Iterator 迭代访问 Collection 集合元素时,Collection 集合里的元素不能被改变,否则将会引发 java.util.Concurrent ModificationException 异常(有方法解决但不推荐使用)。
2.3 增强for
增强 for 循环(也称 for each 循环)是 JDK1.5 以后出来的一个高级 for 循环,专门用来遍历数组和集合,所有单列表集合都可以使用增强 for 循环。其内部原理是一个 Iteration 迭代器,在遍历的过程中,不能对集合中的元素进行增删操作。
2.3.1 语法
for(元素的数据类型 变量 : Collection集合/数组){
···
}
2.3.2 示例
public class DemoCollection {
public static void main(String[] args) {
//多态,创建集合
Collection<String> coll = new ArrayList<>();
//添加字符串进集合
coll.add("华为");
coll.add("联想");
coll.add("神舟");
coll.add("小米");
coll.add("中兴");
System.out.println(coll); //[华为, 联想, 神舟, 小米, 中兴]
//增强for循环
for (String s : coll) {
System.out.println(s);
}
}
}