集合框架Collection
Collection
|--List
|--ArrayList
|--LinkedList
|--Vector
|--Set
|--HashSet
|--TreeSet
/*
为什么会有这么多容器?
因为每一个容器对数据的存储方式都有不同
这个存储方式称为-数据结构
*/
数组是固定长度,集合是可变长度
数组中只能存储同一类型对象,集合没有限制
以ArrayList为例
常用操作
import java.util.*;
class CollectionDemo{
public static void sop(Object obj){
System.out.println(obj);
}
//add方法参数类型是Object,以便于接收任意类对象
//集合中存储的都是对象的引用/地址
public static void main(String[] args){
}
public static void base_method(){
//创建集合容器
ArrayList al=new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
//获取个数,集合长度
sop("size="+al.size());
//删除元素
al.remove("java02");
//al.clear();//清空集合
sop(al);
//判断元素
sop("java03是否存在:"+al.contains("java03"));
sop("集合是否为空:"+al.isEmpty());
}
}
取交集、去除相同元素
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只会保留交集,没有则为空
al1.removeAll(al2);//去掉相同的元素
sop("al1:"+al1);
sop("al2:"+al2);
}
获取元素-迭代器:集合的取出元素的方式
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()){ //如有剩余元素(可迭代)则为true
sop(it.next());
}
for(Iterator it=al.iterator();al.hasNext();){//for循环
sop(it.next());
}
}
**集合内部已经将取出方式定义为内部类,便于直接访问集合内容的元素
没一个容器的数据结构不同,取出的动作细节也不一样
但是都有判断和取出,可以将这些共性抽取,符合Iterator规则,形成了Iterator接口
获取集合的取出对象都通过iterator()方法
List与Set接口
Collection
|--List:元素是有序的,元素可以重复,因为该集合体系有索引
|--Set:元素是无序的,元素不可以重复,没有索引
List接口特有方法
凡是可以操作角标的方法都是该体系特有的方法
增
add(index,element);
addAll(index,Collection);
删
remove(index);
改
set(index,element);
查
get(index);
subList(from,to);
listIterator();
练习
import java.util.*;
class ListDemo{
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args){
ArrayList al=new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
sop("原集合:"+al);
//在指定位置添加元素
al.add(1,"java09");
//删除指定位置元素
al.remove(2);
//修改元素
al.set(2,"java007");
//通过角标获取元素
sop(al.get(1));
sop(al);
//获取所有元素
for(int x=0;x<al.size();x++){
sop(al.get(x));
}
for(Iterator it=al.iterator();it.hasNext();){
sop(it.next());
}
//通过indexOf获取对象位置
sop("index="+al.indexOf("java007"));
List sub=al.subList(0,2);
sop("sub="+sub);
}
}
ListIterator列表迭代器
List集合特有的迭代器,ListIterator是Iterator的子接口
在迭代时,不可以通过集合对象的方法操作集合中的元素,会发生并发异常
因此在使用迭代器时,只能通过迭代器操作元素
Iterator方法有限,需要使用其子接口ListIterator
该接口只能通过List集合的ListIterator方法获取
Ver 1.0 当迭代到某个元素时对该元素进行操作
public static void main(String[] args){
//演示ListIterator
ArrayList al=new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
sop(al);
//在迭代过程中准备添加或者删除元素
for(Iterator it=al.iterator();it.hasNext();){
Object obj=it.next();
/* if(obj.equals("java02")){ //报出异常,迭代器在操作时,用到集合的操作方式
al.add("java008"); //导致并发访问,不能对同一组元素进行多种操作
}*/
if(obj.equals("java02")){
it.remove(); //将元素从集合中移除
}
sop(obj); //但元素依旧在内存中存在,仍然被Object引用,因此仍会被打印
}
sop(al); //已被移除集合,不会被打印
}
Ver 2.0 Iterator只有判断、取出、移除功能,没有添加功能
其子类ListIterator功能更多
public static void main(String[] args){
//演示ListIterator
ArrayList al=new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
sop(al);
for(ListIterator li=al.listIterator();li.hasNext();){
Object obj=li.next();
if(obj.equals("java02")){
// li.add("java009");
li.set("java006");
}
}
ListIterator中特有功能:逆向遍历hasPrevious()
ListIterator li=al.listIterator();
sop("hasNext()"+li.hasNext());
sop("hasPrevious()"+li.hasPrevious());//逆向遍历
List集合具体对象特点
ArrayList:底层的数据结构是数组结构,线程不同步,能够自动延长
特点在于查询速度快
LinkedList:底层使用的是链表数据结构
特点在于便于添加和删除
Vector:底层是数组数据结构,与ArrayList功能相同,线程同步
被ArrayList替代
Vector演示
import java.util.*;
class VectorDemo{
public static void main(String[] args){
Vector v=new Vector();
v.add("java01");
v.add("java02");
v.add("java03");
v.add("java04");
Enumeration en=v.elements();
while(en.hasMoreElements()){
System.out.println(en.nextElement());
}
}
}
枚举是Vector的特有取出方式,其实枚举和迭代相同
枚举的名称以及方法的名称过长,因此被迭代取代
LinkedList
LinkedList特有方法:add/get/removeFirst/Last()
remove也能获取元素,但是会从集合中删除该元素
import java.util.*;
class LinkedListDemo{
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args){
LinkedList link=new LinkedList();
link.addFirst("java01");
link.addFirst("java02");
link.addLast("java03");
link.addFirst("java04");
// sop(link.getLast());
// sop(link.getFirst());
// sop(link.removeFirst());remove也能获取元素,但是元素被删除
while(!link.isEmpty()){
sop(link.removeFirst());//取出所有元素
}
sop(link.size());
}
}
如果集合中没有元素,会出现NoSuchElementException
在JDK6.0中出现了替代方法
offerFirst/Last();
peekFirst/Last();
pollFirst/Last();
//以上方法,如果集合中没有该元素会返回null
LinkedList练习
/*
使用LinkedList模拟一个堆栈或者队列数据结构
堆栈:先进后出(水杯)
队列:先进先出(水管)
*/
import java.util.*;
class DuiLie{
private LinkedList link;
DuiLie(){
link=new LinkedList();
}
public void myAdd(Object obj){
link.add(obj);
}
public Object myGet(){
return link.remove();
}
public boolean isNull(){
return link.isEmpty();
}
}
class LinkedListTest{
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
练习1.去除ArrayList中的重复元素
/*
去除ArrayList中的重复元素
**在迭代循环中,next调用一次,就要判断一次
*/
import java.util.*;
class ArrayListTest{
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args){
ArrayList al=new ArrayList();
al.add("java01");
al.add("java01");
al.add("java01");
al.add("java02");
al.add("java02");
al.add("java03");
al.add("java03");
al.add("java01");
sop(al);
sop(singleElement(al));
}
public static ArrayList singleElement(ArrayList al){
//定义一个临时容器
ArrayList newAl=new ArrayList();
//迭代查找
for(Iterator it=al.iterator();it.hasNext();){
Object obj=it.next();
//将非重复的数值放入临时容器
if(!newAl.contains(obj)){
newAl.add(obj);
}
}
return newAl;
}
}
练习2.将自定义对象作为元素存储到ArrayList集合中,并去除重复元素
/*
将自定义对象作为元素存储到ArrayList集合中,并去除重复元素
比如,以人为对象,同姓名同年龄视为同一人
思路:
1.对人描述,进行封装
2.定义容器,将数据存入
3.取出
*/
import java.util.*;
class Person{
private String name;
private int age;
Person(String name,int age){
this.name=name;
this.age=age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
//原方法采用地址值判断,因此需要覆写equals方法
public boolean equals(Object obj){
if(!(obj instanceof Person)){
return false;
}
Person p=(Person)obj; //将Person类降级
return this.name.equals(p.name)&&this.age==p.age;
}
}
class ArrayListTest2{
public static void sop(Object obj){
System.out.println(obj);
}
public static ArrayList singleElement(ArrayList al){
ArrayList newAl=new ArrayList();
for(Iterator it=al.iterator();it.hasNext();){
Object obj=it.next();
if(!newAl.contains(obj)){ //判断是否包含元素采用contains,其底层原理为equals方法
newAl.add(obj);
}
}
return newAl;
}
public static void main(String[] args){
ArrayList al=new ArrayList();//ArrayList判断对象是否相同,采用equals()
al.add(new Person("lisi01",10));
al.add(new Person("lisi02",20));
al.add(new Person("lisi02",20));
al.add(new Person("lisi03",30));
al.add(new Person("lisi04",40));
al.add(new Person("lisi04",40));
al=singleElement(al);
for(Iterator it=al.iterator();it.hasNext();){
Person p=(Person)it.next();
sop(p.getAge()+"__"+p.getName());
}
}
}
**List集合判断元素是否相同,依据的是元素的equals方法