集合
集合和数组的特点:
数组:
数组定义之后的大小是固定的,不能增加数组大小;
数组可以存储基本数据类型和引用数据类型,(例如:int char 等就是基本数据类型;String是引用数据类型);
集合:
集合是可以随时增加数据的,集合的大小是可变的;
集合可以存储引用数据类型,但不能存基本数据类型,只能使用对应的包装类;
ArrayList集合
包含在包 java.util 中
定义:
ArrayList<E> list = new ArrayList<>();
<E>代表泛型,泛型即"参数化类型"。顾名思义,将类型转化为参数,然后在使用的时候传入指定的类型(相当于调用方法时传入的参数),将后面的类型更改都更改成这个指定的类型(相当于调用方法时的形参)。泛型只能接收引用数据类型作为参数。
基本数据类型 | 引用数据类型 |
---|---|
int | Integer |
char | Character |
short | Short |
byte | Byte |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
其他引用类型,比如常用的 String ,数组,BigInteger,包括自定义的类(Student),都可以当作泛型的参数。
集合体系结构
Collection:单列集合
添加元素时,一次只能添加一个;
Map:双列集合
添加数据时,一次添加两个;
List系列集合:添加的元素是有序(存取有序),可重复,有索引。
Set系列集合:添加的元素是无序,不重复(不能存储重复的元素),无索引。
Collection
Collection是所有单列集合的祖宗接口,他的字段和方法可供所有单列集合继承使用。
常用方法
方法名称 | 说明 |
---|---|
public boolean add(E e) | 把给定的对象添加到当前集合中 |
public void clear() | 清空 集合中所有的元素 |
public boolean remove(E e) | 把给定的对象在当前集合中删除 |
public boolean contains(Object obj) | 判断当前集合中是否包含给定的对象 |
public boolean isEmpty() | 判断当前集合是否为空 |
public int size() | 返回集合中元素的个数 |
注意:Collection是一个接口,不能直接通过他实例化对象;使用时必须常见它的实现类的对象。
这里演示的是ArrayList实现类的使用:
定义:
import java.util.ArrayList;
import java.util.Collection;
//导包
.
.
.
//定义:
Collection<String> coll = new ArrayList<>();
1.添加数据 注意:该方法的返回值在List中永远返回true,因为List系列允许元素重复 如果是Set系列集合中,如果要添加的元素不存在,方法返回true,添加成功;如果要添加的元素存在,方法返回false,添加失败 因为Set系列的集合元素不能重复
coll.add("adc");
2.删除
因为Collection中定义的是公共的方法,Set系列中不含索引,所以不能根据索引删除,只能根据元素的对象进行删除
存在会删除成功,返回true,不存在删除不成功会返回false
coll.remove("adc");
3.包含 细节:底层依赖equals方法判断是否存在 所以,如果集合中存储的是自定义对象,也想通过contains判断是否存在该元素,一定要重写equals方法 equals方法是Object类下的方法,不重写的话是依靠地址值进行判断的,如果想要根据元素属性判断是否相等一定要重写 字符串判断相等的时候同理也需要将equals进行重写,但官方已经在String类中重写好了equals方法。
coll.contains("ads");
Collection的遍历方式(List和Set通用)
-
迭代器遍历
-
增强型for循环遍历
-
Lambda表达式遍历
List系列右下标索引可以通过普通 for 循环遍历,但Set系列不能;
迭代器遍历
迭代器是集合专用的遍历方式,其包含在类 Iterator
定义:
import java.util.Iterator;//导包
.
.
.
//假设已经定义好了一个ArrayList集合 名为 list
Iterator<Integer> iterator = list.iterator();//定义
Iterator 中的方法:
iterator.hasNext();
//该方法的源码:
public boolean hasNext() {return cursor != size;}
//cursor 表示当前当前元素的索引,(抽象出来的,其实不一定存在索引),索引最大为size - 1
//所以hasNext() 可以将集合全部遍历完
//理解为判断当前元素是否存在,更容易记忆和使用
iterator.next();
//该方法将返回当前位置的元素,需要用相应的数据类型接收,然后将迭代器后移
iterator.remove();
//该方法会删除当前迭代器指向的元素的 前一个 元素
通常使用while循环可遍历整个集合
while(iterator.hasNext()){
//当迭代器当前元素存在时返回true,进入循环
int ret = iterator.next();
//iterator.next()会返回当前迭代器指向的元素(用ret接收),并将迭代器移动到下一个元素
System.out.println(ret);
}
注意:
-
如果迭代器的 hasNext() 已经返回 false 了,再去调用 next() 获取元素会报错:NoSuchElementException;
-
迭代器遍历完毕,指针不能复位;
-
循环中只能用一次 next() 方法;
-
迭代器遍历时,不能用集合的方法进行增加或删除。要删除可以使用迭代器的 remove() 方法。
增强 for 遍历
增强 for 的底层实现就是通过迭代器,它的出现为了简化迭代器遍历,JDK 5以后出现的。
所有单列集合(Collection)和数组才能使用增强 for 进行遍历。
//遍历集合 (若已知集合ArrayList,名为 list)
for( int X : list){
System.out.println(x);
}
//遍历一维数组 (若已知一维数组int[] arr)
for(int x : arr){
System.out.println(x);
}
//遍历二维数组 (若已知二维数组int[][] arr)
for(int[] x : arr){
for(int val : x){
System.out.println(val);
}
}
//IDEA的快捷方式:list.for + Enter
注意:增强 for 循环不能用来赋值和修改值;
因为 x 是为了遍历创造的临时变量,改变 x 的值不会影响集合或数组的元素。
Lambda表达式遍历
JDK 8开始的新特性
使用匿名内部类进行集合的遍历
coll.forEach(new Consumer<Integer>() {
//forEach方法通过普通for循环遍历集合或数组
//accept将集合或数组的元素赋给形参integer,形参integer用来接收
//同样因为是定义了中间变量,所以对integer的修改无法改变原集合或数组中的元素
@Override
public void accept(Integer integer) {
if (integer % 2 == 0) {
//元素是偶数
System.out.println(integer);
}
}
});
使用Lambda表达式进行集合的遍历
//使用Lambda表达式进行遍历
coll.forEach(integer -> {
if (integer % 2 != 0) {
//元素是奇数
System.out.println(integer);
}
});
Lambda表达式可将在调用函数式接口(只有一个抽象函数)的时候,删去调用的方法(forEach)参数和主体中的方法(accept)的修饰符、返回值和方法名,增添-> 只保留主体的方法的参数和执行语句;
总结:
-
Collection是单列集合的顶层接口,所有的方法被 List 和 Set 系列集合共享;
-
常见成员方法:add clear remove contains isEmpty size
-
三种遍历方式:
-
迭代器:在遍历的时候需要删除元素,只能使用迭代器;
-
增强for、Lambda表达式:仅仅想遍历集合
-
观看黑马程序员B站 java 视频学习 黑马程序员Java零基础视频教程_上部(Java入门,含斯坦福大学练习题+力扣算法题和大厂java面试题)_哔哩哔哩_bilibili