为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。数据多了用对象,对象多了用集合
数组和集合类同时容器,有何不同?
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。
数组中可以存储基本数据类型,集合只能存储对象。
集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象
集合框架的构成及分类
为什么会出现这么多的容器呢?
因为每一个容器对数据的存储方式都有不同。这个存储方式称之为:数据结构。
如下图,标蓝的是比较常见的集合,接下来就来学习一下这几种集合框架。
Collection的公共方法,已ArrayList为例:
ArrayList al = new ArrayList();
//1.添加元素
al.add("java01");
al.add("java02");
//删除元素
al.remove("java02")
//清空集合
al.clear();
//判断元素
al.contains("java03"); //打印Boolean值
al.isEmpty(); //打印Boolean值
- add方法的参数类型是Object,以便于接受任意类型对象
2 记住:集合和数组存放的都是对象的引用(地址),不是实体对象
ArrayList all = new ArrayList();
al.add("java01");
al.add("java02");
ArrayList al2 = new ArrayList();
al.add("java01");
al.add("java03");
//去交集,al1只会保留和al2中相同的元素
al1.retainAll(al2);// 打印结果:al中的集合变为一个 Java01
al1.removeAll(al2);//打印结果:java2 ,al1会去除和al2相同的结果
//迭代器,用于去除集合中的元素
Iterator it = al.iterator();
while(it.hasNext()){
String string = it.next();
}
Iterator
//迭代器也可以这样写,iterator 为内部变量,用完就会释放掉了,比较优化
for (Iterator<String> iterator = aList.iterator(); iterator.hasNext() ; ) {
String string = iterator.next();
System.out.println(string);
}
Collection
List:元素是有序的,元素可以重复,因为该集合体系有索引
ArrayList:底层的数据结构使用的是数组结构,线程不同步, 特点:查询速度很快,但是增删稍慢
LinkedList:底层使用的是链表的数据结构,特点:查询速度稍慢,但是增删速度很快
Vector:底层是数组数据结构,线程是同步的,和ArrayList功能一样,效率底,被ArrayList替代。
Set:元素是无序的,元素不可以重复
List:特有方法:凡是可以操作角标的方法都是该体系的特有方法
增
add(index,element);
addAll(index,Collection);
删
remove(index)
改
set(index,element);
查
get(index)
subList(from,to);
ListIterator();
ArrayList<String> aList = new ArrayList<>();
aList.add("java1");
aList.add("java2");
aList.add("java3");
/*此迭代器不能进行add操作,有局限性*/
Iterator<String> iterator = aList.iterator();
while (iterator.hasNext()) {
Object object = iterator.next();
if (object.equals("java2")) {
//aList.add("java3");//不可以使用,会发生ConcurrentModificationException并发异常
iterator.remove();//将Java2的引用从集合中删除了,但是objec里面还是存在的
sop(object);//打印java2
}
}
sop(aList);//打印[java1, java3]
List集合特有的迭代器,ListIterator是Iterator的子接口,在迭代时,不可以通过对象的方法操作集合中元素,因为会发生ConcurrentModificationException并发异常。
所以在迭代时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作。
如果想要其他的操作如添加,修改等,就需要使用其子接口ListIterator,该接口只能通过List集合的ListIterator方法获取。
//列表迭代器,在迭代过程中,准备添加或者删除元素
ArrayList<String> aList = new ArrayList<>();
aList.add("java1");
aList.add("java2");
aList.add("java3");
ListIterator<String> listIterator = aList.listIterator();
while (listIterator.hasNext()) {
String string = (String) listIterator.next();
if (string.equals("java2")) {
listIterator.add("java4");
}
}
sop(listIterator.hasPrevious());//有没有前一个元素 打印true
sop(listIterator.hasNext());//有没有后一个元素 打印false
sop(aList);//打印[java1, java2, java4, java3]
Vector例子
//枚举就是Vector特有的去处方式,发现枚举和迭代器很像,其实枚举和迭代器是一样的。
//因为枚举的名字以及方法的名称过长,所以被迭代器取代了。
Vector<String> vector = new Vector<>();
vector.add("java1");
vector.add("java2");
vector.add("java3");
//特有方法
Enumeration<String> enu= vector.elements();
while (enu.hasMoreElements()) {
sop(enu.nextElement());
}
LinkedList
LInked特有方法:
addFirst();
addLast();
getFirst();
getLast();
获取元素,但不删除元素,如果集合中没有元素,会出现NoSuchElementException
removeFirst()
removeLast()
获取元素,但是元素被删除,如果集合中没有元素,会出现NoSuchElementException
在JDK1.6出现了替代方法:
offerFirst()
offerLast()
添加元素
peekFirst()
peekLast()
获取元素,但不删除元素,如果集合中没有元素,会返回null
pollFirst()
pollLast()
获取元素,但是元素被删除,如果集合中没有元素,会返回null
LinkedList<String> linkedList = new LinkedList<>();
linkedList.addFirst("java1");
linkedList.addFirst("java2");
linkedList.addFirst("java3");
sop(linkedList);//打印[java3, java2, java1]
sop(linkedList.getLast());//打印java1
sop(linkedList.getFirst());//打印java3
sop(linkedList.size());//打印3
sop(linkedList.removeLast());//打印java1
练习1
使用LInkedList模拟一个堆栈或者队列数据结构。
堆栈:先进后出
队列:先进先出
class Dulie{
private LinkedList linkedList;
public Dulie(){
linkedList = new LinkedList();
}
public void myAdd(Object object){
linkedList.addFirst(object);
}
public Object myGet(){
return linkedList.removeLast();
}
public boolean isNull(){
return linkedList.isEmpty();
}
}
public class Demo {
public static void sop(Object object){
System.out.println(object);
}
public static void main(String[] args) {
Dulie dulie = new Dulie();
dulie.myAdd("java1");
dulie.myAdd("java2");
dulie.myAdd("java3");
dulie.myAdd("java4");
while (!dulie.isNull()) {
sop(dulie.myGet());
}
}
}
打印结果:
java1
java2
java3
java4
练习2
去除ArrayList集合中的重复元素
public class ListDemo {
public static void sop(Object object){
System.out.println(object);
}
public static void main(String[] args) {
ArrayList aList = new ArrayList<>();
aList.add("java1");
aList.add("java1");
aList.add("java2");
aList.add("java3");
aList.add("java2");
sop(singleElement(aList));
}
public static ArrayList singleElement(ArrayList aList){
//定义一个临时容器
ArrayList arrayList = new ArrayList<>();
//遍历源集合
Iterator iterator = aList.iterator();
while (iterator.hasNext()) {
Object object = iterator.next();
//如果这个元素不在临时容器中,则存起来
if (!arrayList.contains(object)) {
arrayList.add(object);
}
}
return arrayList;
}
}
打印结果:
[java1, java2, java3]
原理:需要一个新的容器来装,在装之前判断是否存在,存在就不装了
练习3
将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
比如:存人对象,同姓名同年龄,视为同一个人,为重复对象
思路:1.定义人对象 2.定义容器,将人存入 3.取出
class Person{
int age;
String name;
public Person(int age,String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
//需要重写Object的equal方法,因为这个equal对比的是地址是否相等
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Person)) {
return false;
}
Person person = (Person)obj;
return this.age == person.age && this.name.equals(person.name);
}
}
public class ListDemo {
public static void sop(Object object){
System.out.println(object);
}
public static void main(String[] args) {
ArrayList aList = new ArrayList<>();
aList.add(new Person(12,"wang"));
aList.add(new Person(11,"lisi"));
aList.add(new Person(12,"wang"));
aList.add(new Person(30,"zhangsan"));
aList = singleElement(aList);
Iterator iterator = aList.iterator();
while (iterator.hasNext()) {
Person p = (Person)iterator.next();
sop(p.age +",,"+ p.name);
}
}
public static ArrayList singleElement(ArrayList aList){
//定义一个临时容器
ArrayList arrayList = new ArrayList<>();
//遍历源集合
Iterator iterator = aList.iterator();
while (iterator.hasNext()) {
Object object = iterator.next();
//如果这个元素不在临时容器中,则存起来
if (!arrayList.contains(object)) {
arrayList.add(object);
}
}
return arrayList;
}
打印结果:
12,,wang
11,,lisi
30,,zhangsan
List集合判断元素是否相同,依据是元素的equals方法
aList.remove(new Person(11,“lisi”) ); //remove也是依据equals