Java基础14:集合类;list集合;迭代器;set集合;

时间:2021-11-28 17:01:58
关键字:集合类;list集合;迭代器;set集合;

一、概述

1、为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就是对对象进行存储,集合就是存储对象最常用的一种方式
2、数组和集合类是容器,有何不同?
数组虽然也可以存储对象,但是长度是固定的
集合长度是可变的
数组中可以存储基本数据类型
集合只能存储对象
3、集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象
4、为什么会出现这么多的容器呢?
因为每一个容器对数据的存储方式都有不同,这个存储方式称之为:数据结构
5、

Java基础14:集合类;list集合;迭代器;set集合;
Collection
|
|------List:元素是有序的,元素可以重复,因为该集合体系有索引
| |
| |--------ArrayList:底层的数据结构使用的是数组结构,查询速度很快,但是增删稍慢,线程不同步,默认10个元素
| |--------LinkedList:底层使用的链表数据结构,查询很慢,增删速度很快
| |--------Vector:底层是数组数据结构,和ArrayList一样,查询,增删,都很慢,Vector是1.0出现,ArrayList是1.2出现,线程同步,但已经不用了
|
|------Set:元素是无序的,元素不可以重复
|
|--------HashSet
|--------TreeSet
二、集合框架(共性方法)
1、add方法的参数类型是Object,以便于接收任意额类型对象。

2、集合中存储的都是对象的引用(地址)

import java.util.*;
class Demo{
public static void main(String[] args){
method_2();
}
public static void method_2(){
ArrayList al1 = new ArrayList();
al1.add("java01");
al1.add("java02");
al1.add("java03");
al1.add("java04");
ArrayList al2 = new ArrayList();
al2.add("java01");
al2.add("java02");
al2.add("java05");
al2.add("java06");
al1.retainAll(al2);//保留交集 al1中只有 java01 java02
al1.remove(al2);//去除交集 al1中只有 java01 java02
sop("al1:"+al1);
sop("al2:"+al2);
}
public static void base_method(){
//创建一个集合容器,使用Collection接口的子类,ArrayList
ArrayList al = new ArrayList();
//1、添加元素。 add(Object obj)
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
//2、获取个数,集合长度 注意:Demo.java 使用了未经检查或不安全的操作。 注意:要了解详细信息,请使用 -Xlint:unchecked 重新编译。
sop("size:"+al.size());
//打印集合
sop(al);
//3、删除元素
al.remove("java02");
sop(al);
//清空
al.clear();
4、判断元素
sop("java03是否存在"+al.contains("java03"));
sop("集合是否为空"+al.isEmpty());
}
public static void sop(Object obj){
System.out.println(obj);
}
}
三、集合框架(迭代器)
1、什么是迭代器?其实就是集合的取出元素的方式
2、就把取出方式定义在集合的内部,这样取出方式就可以直接访问结合内容的元素。那么取出方式就定义成了内部类。
3、而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共共性内容:判断,取出。那么可以将写共性取出。
4、那么这些内部类都符合一个规则。该规则是Iterator。如何获取集合的取出对象呢?通过一个对外提供的方法:iterator();

import java.util.*;
class Demo{
public static void main(String[] args){
method_get();
}
public static void method_get(){
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
//Iterator it = al.iterator();//获取迭代器,用于取出集合中的元素,
// while(it.hasNext()){
// sop(it.next());
// }
//都这么写
for(Iterator it = al.iterator();it.hasNext();){
sop(it.next());
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
四、集合框架(List集合共性方法)
1、Collection
|
|----List:元素是有序的,元素可以重复,因为该集合体系有索引
|----Set:元素是无序的,元素不可以重复

2、List:特有方法,凡是可以操作角标的方法都是该体系特有的方法
(1)、增:
add(index,element)
(2)、删:
remove(index)
(3)、改:
set(index,element)
(4)、查:
get(index)
subList()
listIterator()
五、集合框架(ListIterator)
1、list集合特有的迭代器,ListIterator是Iterator的子接口。
2、在迭代时候,不可以通过集合对象的方法操作集合中的元素,因为会发生 ConcurrenModificationException异常。
3、所以在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作
4、如果想要其他的操作,如添加、修改等,就需要使用其子接口,ListIterator。
5、该接口只能通过List集合的listIterator方法获取
6、hasPrevious() ,前面是否有元素
六、集合框架(List集合具体对象的特点)

import java.util.*;
class Demo{
public static void main(String[] args){
method_get();
}
public static void method_get(){
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
sop("原集合是:"+al);
al.add(1,"java09");
sop("后:"+al);
//删除
al.remove(2);
//修改元素
al.set(2,"java07");
//通过角标获取元素
sop(al.get(1));
//获取所有元素
for(int x=0;x<al.size();x++){
sop("al("+x+") = "+al.get(x));
}
for(Iterator it = al.iterator();it.hasNext();){
sop(it.next());
}
//通过 indexOf获取对象的位置
sop(al.indexOf("java04"));
sop(al);
sop(al.subList(1,3));
ListIterator li = al.listIterator();

}
public static void sop(Object obj){
System.out.println(obj);
}
}
七、集合框架(Vector中的枚举)
1、枚举就是Vector特有的取出方式
2、发现枚举和迭代器很像。
3、其实枚举和迭代是一样的,
4、因为枚举的名称以及方法的名称都过长,所以被迭代器取代了,枚举就郁郁而终了

import java.util.*;
class Demo{
public static void main(String[] args){
method_get();
}
public static void method_get(){
Vector v = new Vector();
v.add("java01");
v.add("java02");
v.add("java03");
v.add("java04");
Enumeration en = v.elements();
while(en.hasMoreElements()){
sop(en.nextElement());
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
八、集合框架(LinkedList)
1、LinkedList:特有方法
(1)、addFirst():
(2)、addLast():
(3)、getFirst():
(4)、getLast():
(5)、removeFirst():删除并返回元素 ,如果集合中没有有元素,会出现 NoSuchElementExceptionextends RuntimeException 表明枚举中没有更多的元素


peekFirst() 
          获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
(5)、removeLast()
2、1.6中出现了替代方法
boolean offer(E e) 
          将指定元素添加到此列表的末尾(最后一个元素)。 
boolean offerFirst(E e) 
          在此列表的开头插入指定的元素。 
E peekFirst() 
          获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。 
E peekLast() 
          获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。
E pollFirst() 
 获取并移除此列表的第一个元素;如果此列表为空,则返回 null。 
E pollLast() 
 获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。 
九、集合框架(LinkedList练习)
/*
使用LinkedFirst模拟一个堆栈或者队列数据结构
堆栈:先进后出 如同一个罐子
队列:先进先出 如同一个水管
*/
import java.util.*;
class Duilie{
private LinkedList link;
Duilie(){
link = new LinkedList();
}
public void myAdd(Object obj){
link.addFirst(obj);
}
public Object myGet(){
return link.removeLast();
}
public boolean isNull(){
return link.isEmpty();
}
}
class Demo{
public static void main(String args[]){
Duilie dl = new Duilie();
dl.myAdd("java01");
dl.myAdd("java02");
dl.myAdd("java03");
dl.myAdd("java04");
while(!dl.isNull()){
System.out.println(dl.myGet());
}
}
}
十、集合框架(ArrayList练习)

/*
使用LinkedFirst模拟一个堆栈或者队列数据结构
堆栈:先进后出 如同一个罐子
队列:先进先出 如同一个水管
*/
import java.util.*;


class Demo{
public static void main(String args[]){
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java02");
al.add("java04");
al = singleElement(al);
System.out.println(al.toString());
}
public static ArrayList singleElement(ArrayList al){
//定义一个临时容器
ArrayList newAl = new ArrayList();
Iterator it = al.iterator();
//没调用一次next就要hasNext判断下
while(it.hasNext()){
Object obj = it.next();
if(!newAl.contains(obj)){
newAl.add(obj);
}
}
return newAl;
}
}
十一、集合框架(ArrayList练习2)
/*
将自定义对象作为元素存到ArrayList集合中,并去除创富元素
比如,存人对象,视为同一个人,为重复元素
思路:
1、对人描述,将数据封装进人对象
2、定义容器,将人进行存入
3、取出


List集合判断是否包含其实是根据这个对象判断是否和内部的对象, equals,可以复写这个equals,写自己的判断


当List remove 删除时候,也是i先equals判断有没有,如果所以要注意
*/
import java.util.*;


public class Demo{
public static void main(String args[]){
ArrayList al = new ArrayList();
al.add(new Person("list01",31));
al.add(new Person("list02",32));
al.add(new Person("list02",32));
al.add(new Person("list03",33));
al.add(new Person("list04",34));
al.add(new Person("list04",34));
al.add(new Person("list05",35));
al = singleElement(al);
for(Iterator it = al.iterator();it.hasNext();){
Person p = (Person)it.next();
sop(p.getName()+":"+p.getAge());
}
}
public static void sop(Object obj){
System.out.println(obj.toString());
}
public static ArrayList singleElement(ArrayList al){
//定义一个临时容器
ArrayList newAl = new ArrayList();
Iterator it = al.iterator();
//没调用一次next就要hasNext判断下
while(it.hasNext()){
Object obj = it.next();
if(!newAl.contains(obj)){
newAl.add(obj);
}
}
return newAl;
}
}
class Person{
private String name;
private int age;
Person(String name,int age){
this.name = name;
this.age = age;
}
public boolean equals(Object obj){
if(!(obj instanceof Person)){
return false;
}
Person p = (Person)obj;
return this.name.equals(p.name)&&this.age==p.age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
}
十二、集合框架(HashSet)
/*
Set:元素是无序(存入和取出的顺序不一定一致)的,元素不可以重复
|---HashSet:底层数据结构是哈希表
HashSet是如何保证元素的唯一性的呢?
是通过元素的两个方法,hashCode和equals来完成。
如果元素的hashCode值相同,才会判断equals是否为true
如果元素的hashCode值不同,不会调用equals

注意:对于判断元素是否存在,以及删除的操作,以来的方法是元素的 hashCode和equals方法
先 hashCode 再 equals
而,arrayList 仅仅是equals
|---TreeSet:

Set集合的功能和Collection是一致的
*/
import java.util.*;


public class Demo{
public static void main(String args[]){
HashSet hs = new HashSet();
hs.add("java01");
hs.add("java02");
hs.add("java03");
sop(hs.add("java04"));
sop(hs.add("java04"));
for(Iterator it = hs.iterator();it.hasNext();){
sop(it.next());
}
}
public static void sop(Object obj){
System.out.println(obj.toString());
}
}
十三、集合框架(HashSet存储自定义对象)

/*
往hashSet集合中存入自定义对象
姓名和年龄相同为同一人,重复元素
*/
import java.util.*;


public class Demo{
public static void main(String args[]){
HashSet hs = new HashSet();
hs.add(new Person("al",11));
hs.add(new Person("a2",12));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
hs.add(new Person("a4",14));
for(Iterator it = hs.iterator();it.hasNext();){
Person p = (Person)it.next();
sop(p.getName()+"::"+p.getAge());
}
}
public static void sop(Object obj){
System.out.println(obj.toString());
}
}
class Person{
private String name;
private int age;
Person(String name,int age){
this.name = name;
this.age = age;
}
public boolean equals(Object obj){
Person p = (Person)obj;
sop(this.name+" -> "+p.name);
if(!(obj instanceof Person)){
return false;
}
return this.name.equals(p.name)&&this.age==p.age;
}
public int hashCode(){
sop(this.name);
//两个对象不一样,但是name.hashCode()+this.age;一样,所以最好是name.hashCode()+this.age*;一个数字;比如name.hashCode()+this.age*37
return this.name.hashCode()+this.age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public static void sop(Object obj){
System.out.println(obj.toString());
}
}
十四、集合框架(HashSet判断和删除的依据)

/*
往hashSet集合中存入自定义对象
姓名和年龄相同为同一人,重复元素
*/
import java.util.*;


public class Demo{
public static void main(String args[]){
HashSet hs = new HashSet();
hs.add(new Person("al",11));
hs.add(new Person("a2",12));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
hs.add(new Person("a4",14));
sop(hs.contains(new Person("a2",12)));
hs.remove(new Person("a3",13));
for(Iterator it = hs.iterator();it.hasNext();){
Person p = (Person)it.next();
sop(p.getName()+"::"+p.getAge());
}
}
public static void sop(Object obj){
System.out.println(obj.toString());
}
}
class Person{
private String name;
private int age;
Person(String name,int age){
this.name = name;
this.age = age;
}
public boolean equals(Object obj){
Person p = (Person)obj;
sop(this.name+" -> "+p.name);
if(!(obj instanceof Person)){
return false;
}
return this.name.equals(p.name)&&this.age==p.age;
}
public int hashCode(){
sop(this.name);
//两个对象不一样,但是name.hashCode()+this.age;一样,所以最好是name.hashCode()+this.age*;一个数字;比如name.hashCode()+this.age*37
return this.name.hashCode()+this.age*37;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public static void sop(Object obj){
System.out.println(obj.toString());
}
}