---------- android培训、java培训、期待与您交流! ----------
集合概述
为什么出现集合类
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多 个对象的操作,就对对象进行存储,
集合就是存储对象最常用的一 种方式。
数组和集合类同是容器,有何不同
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。
数组中可以存储基本数据类型,集合只能存储对象。
集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
Collection接口有两个子接口
List:可存放重复元素,元素存取是有序的。
Set:不可以存放重复元素,元素存取是无序的。
List接口中常用类
Vector:线程安全,但速度慢,已被ArrayList替代。
ArrayList:线程不安全,查询速度快。
LinkedList:链表结构,增删速度快。
取出LIst集合中元素的方式
get(int index):通过脚标获取元素。
iterator():通过迭代方法获取迭代器对象。
public class Temp {
public static void main(String[]args)
{
//JiBen_Method();
Method_2();
}
public static void JiBen_Method()
{
//创建一个集合容器,使用Collection接口的子类, ArrayList
ArrayList al = new ArrayList();
//1,添加集合元素
al.add("Array_01");
al.add("Array_02");
//2,打印原集合
System.out.println("打印原集合:"+al);
//3,打印集合的长度。集合元素。
System.out.println("打印集合长度:"+al.size());
//4,删除元素
al.remove("Array_02");
System.out.println("打印删除后的集合:"+al);
//5,清空集合容器
al.clear();
//6,判断元素。
System.out.println("Array_03是否存在:"+al.contains("Array_03"));
System.out.println("集合是否为空?"+al.isEmpty());
}
public static void Method_2()
{
ArrayList al1 = new ArrayList();
al1.add("Array_01");
al1.add("Array_02");
al1.add("Array_03");
al1.add("Array_04");
ArrayList al2 = new ArrayList();
al2.add("Array_01");
al2.add("Array_02");
al2.add("Array_05");
al2.add("Array_06");
//al1.retainAll(al2);//取交集,al1 只会保留al2中相同的元素
//al1.removeAll(al2);//取交集,al1 只去除与al2中相同的元素
//al1.addAll(al2);//将al2中的元素,全部放到al1容器中去。
//al1.containsAll(al2);
System.out.println("al1:"+al1);
System.out.println("al2:"+al2);
}
}
迭代iterator
迭代是取出集合中元素的一种方式
因为Collection中有iterator方法,所以每一个子类集合对象都具备迭代器
迭代注意事项
1、迭代器在Collcection接口中是通用的,它替 代了Vector类中的Enumeration(枚举)。
2、迭代器的next方法是自动向下取元素,要避 免出现NoSuchElementException。
3、迭代器的next方法返回值类型是Object,所 以要记得类型转换。
/*
* 1, add方法的参数类型是Object. 以便于接收任意类型对象。
* 2,集合中存储的都是对象的引用(地址)
*
* 什么是迭代器呢?
* 其实就是集合的取出元素的方式。
*/
public class Temp {
public static void main(String[]args)
{
Get();
}
public static void Get()
{
ArrayList a1 = new ArrayList();
//添加元素
a1.add("aaaa");//add(Object obj);
a1.add("bbbb");
a1.add("cccc");
a1.add("dddd");
//获取迭代器,用于取出集合中的元素
Iterator it = a1.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
/*
//节省内存的方式For循环
for(Iterator it = a1.iterator();it.hasNext();)
{
sop(it.next());
}
*/
}
}
List集合共性方法
import java.util.*;
/* List集合共性方法
* --------------------------------------------------
* Collection
* |--List: 元素是有序的,元素可以重复,该集合体系有索引。
* |--ArrayList: 底层的数据结构使用的数组结构(特点:查询速度快,但是增删稍慢。线程不同步。因为走角标)
* |--LikedList: 底层使用的是链表数据结构(特点:增删速度很快,查询速度稍慢)
* |--Vector: 底层是数组数据结构。线程同步。被ArrayList替代了。
* |--Set : 元素是无序的,元素不可以重复。
*
* List特有方法:
* 增
* add(index,element);
* addAll(index,Collection);
* 删
* remove(index);
* 改
* set(index,element);
* 查
* get(index);
* subList(from,to);
* ListIterator();
*/
public class Temp {
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[]args)
{
ArrayList a1 = new ArrayList();
//添加元素
a1.add("java01");
a1.add("java02");
a1.add("java03");
System.out.println("原集合:"+a1);
//指定位置添加元素
a1.add(1,"java09");
a1.add(3,"Java007");
sop("添加后集合:"+a1);
//删除元素
a1.remove(1);
System.out.println("删除后集合:"+a1);
//修改元素
a1.set(1, "java007");
//通过角标获取元素
System.out.println("根据角标获取元素"+a1.get(2));
//注意:获取所有元素(size()是获取ArrayList的长度,不是使用length获取)
for(int x = 0;x<a1.size();x++)
{
sop("a1("+x+")="+a1.get(x));
}
//第二种获取所有元素的方式(迭代器)
Iterator it = a1.iterator();//a1.iterator(是获取对象a1的迭代)
while(it.hasNext())
{
sop(it.next());
}
//通过indexOf / subList(Start,End)获取对象的角标位置
System.out.println("通过对象获取对象的角标位置:"+a1.indexOf("java03"));
List sub = a1.subList(1,4);
System.out.println("通过subList获取对象:"+sub);
}
}
ListIterator列表迭代
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
/*
* List集合特有的迭代器,ListIterator是Iterator的子接口。
*
* 在迭代时,不可以通过集合对象的方法操作集合中的元素。
* 因为会发生ConcurrentModificationException异常。
*
* 所以,在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的。
* 只能对元素判断、取出,删除的操作。
*
* ------------------------------------------------------------------------------------
* 迭代器:ListIterator --> List集合特有的迭代器
*
* (特有方法)指定位置add添加、set修改,还能判断前面是否还有元素hasPrevious
* 如果想要其他的操作,如添加,修改,判断前面是否还有元素等,就需要使用其子接口ListIterator。
*
* 原因:ArrayList是数组结构,具有角标,所以可以索取指定角标进行添加修改
* ------------------------------------------------------------------------------------
* 该接口只能通过List集合的ListIterator方法获取。
*/
public class Temp{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[]args)
{
//演示列表迭代器
ArrayList al = new ArrayList();
//添加元素
al.add("Array01");
al.add("Array02");
al.add("Array03");
System.out.println("原集合元素:"+al);
ListIterator li = al.listIterator();
//判断前面是否有元素( hasPrevious() )
System.out.println("hasPrevious:--"+li.hasPrevious());
while(li.hasNext())
{
Object obj = li.next();//此行代码示意:用于接收我们添加的"集合元素"Java007
if(obj.equals("Array02"))
{
//li.add("Java007");//添加
li.set("JAVA02"); //修改
}
}
System.out.println("使用ListIterator列表集合添加后:"+al);
//判断后面是否还有元素、false/true
System.out.println("hasNext:--"+li.hasNext());
//判断前面是否有元素( hasPrevious() )
System.out.println("hasPrevious:--"+li.hasPrevious());
//使用hasPervious循环输出
while(li.hasPrevious())
{
System.out.println("hasPrevious:"+li.previous());//输出方式:逆向输出
}
}
}
LikedList
import java.util.*;
/*
* LikedList特有方法:
*
* addFirst();
* addLast();
* 添加元素
*
* getFirst();
* getLast();
* 获取元素,但不删除元素,如果集合中没有元素,则会出现NoSuchElementException
*
* removeFirst();
* removeLast();
* 获取元素,但是元素被删除,如果集合中没有元素,则会出现NoSuchElementException
*
* 在JDK1.6以后,出现了替代方法
*
* offerFirst();
* offerLast();
*
* peekFirst();
* peekLast();
* 获取元素,但不删除元素,如果集合中没有元素,则返回null.
*
* pollFirst();
* pollLast();
* * 获取元素,但元素被删除,如果集合中没有元素,则返回null
*
*/
public class Temp{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[]args)
{
//演示列表迭代器
ArrayList al = new ArrayList();
//添加元素
al.add("Array01");
al.add("Array02");
al.add("Array03");
System.out.println("原集合元素:"+al);
ListIterator li = al.listIterator();
//判断前面是否有元素( hasPrevious() )
System.out.println("hasPrevious:--"+li.hasPrevious());
while(li.hasNext())
{
Object obj = li.next();//此行代码示意:用于接收我们添加的"集合元素"Java007
if(obj.equals("Array02"))
{
//li.add("Java007");//添加
li.set("JAVA02"); //修改
}
}
System.out.println("使用ListIterator列表集合添加后:"+al);
//判断后面是否还有元素、false/true
System.out.println("hasNext:--"+li.hasNext());
//判断前面是否有元素( hasPrevious() )
System.out.println("hasPrevious:--"+li.hasPrevious());
//使用hasPervious循环输出
while(li.hasPrevious())
{
System.out.println("hasPrevious:"+li.previous());//输出方式:逆向输出
}
}
}
Set集合
Set集合元素唯一性原因
HashSet:通过equals方法和hashCode方法来保证元素的唯一性
TreeSet:通过compareTo或者compare方法中来保证元素的唯一性。元素是以二叉树的形式存放的
HashSet
/**
* |--Set : 元素是无序的(存入和取出的顺序,不一定一致),元素不可以重复。
* |--HashSet: 底层数据结构是哈希表
* HashSet是如何保证元素唯一性呢?
* 是通过元素的两个方法,hashCode和Equals来完成
* 如果元素的HashCode值相同,才会判断equalse是否为true;
* 如果元素的HashCode值不同,不会调用equalse
*
* 结论:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的
* HashCode和equals方法。
*
* |--TreeSet:
*
* Set的功能与Conllection的方法一样。
*
*/
import java.util.*;
public class Temp {
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[]args)
{
HashSet hs = new HashSet();
System.out.println(hs.add("aa"));
System.out.println(hs.add("bb"));
hs.add("java02");
hs.add("java03");
hs.add("java04");
Iterator it = hs.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
TreeSet (Comparable接口)
使用TreeSet集合时,添加对象元素时,
必须实现comparable接口,这样才能进行多个对象的排序。
并且要覆盖comparable接口的compareTo方法,
如果主要条件相同this.age==s.age,就要判断次要条件(returnthis.name.compareTo(s.name);
字符串本身就具备compareTo排序方法。
例如:以年龄大小进行排序,如果年龄相同,就要判断名字是否相同。
/**
* Set: 无序,不可以重复元素。
* |--HashSet:数据结构是哈希表,线程是非同步的。
*
* 保证元素唯一性的原理,判断元素的HashCode是否相同
*
* 如果相同,还会继续判断元素的equals方法,是否为true
* |--TreeSet:可以对Set集合中的元素进行排序
*
*
第一种排序方式:自然排序,实现Comparable接口,重写compareTo方法
向TreeSet集合中存储自定义对象学生
按照学生的年龄进行排序
*/
import java.util.*;
//此接口强制让Student实现比较性
class Student implements Comparable{
//定义Student私有属性
private String name;
private int age;
//构造Student函数,初始化
Student(String name,int age)
{
this.name = name;
this.age = age;
}
//公共访问方法,访问私有属性
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
//复写Comparator中的compare方法,自定义比较器
public int compareTo(Object obj)
{
//判断是否属于Student类型,否则抛异常
if (!(obj instanceof Student))
throw new RuntimeException("NotSuchTypeException");
//将Object类对象强转为Student类
Student s = (Student)obj;
//System.out.println(this.age + "--compare-" + s.age);//测试用,查看比较情况
//按年龄大小比较,相同则比较姓名大小,不同返回两年龄之差
if (this.age == s.age)
{
return this.name.compareTo(s.name);
}
else if (this.age <s.age)
return this.age-s.age;
return this.age-s.age;
}
/*
//如果按照存入顺序输出
public int compareTo()
{
return 1;//改为-1则按倒叙输出
}
*/
}
//测试
public class Temp{
public static void main(String[] args) {
//创建集合,并添加元素
TreeSet ts = new TreeSet();
ts.add(new Student("li01",25));
ts.add(new Student("li02",20));
ts.add(new Student("li01",22));
ts.add(new Student("li05",24));
ts.add(new Student("li08",40));
//打印集合中元素
printE(ts);
}
//定义打印集合中元素的功能
public static void printE(TreeSet ts) {
//迭代器方法获取
Iterator it = ts.iterator();
while (it.hasNext()){
//将返回的元素(Object类)强转为Student类
Student s = (Student)it.next();
System.out.println(s.getName() + "---" + s.getAge());
}
}
}
第二种排序方式:比较器
在集合初始化时就有了比较方式。
当两种排序方式都存在时,以比较器为主。
如何构造比较器:定义一个类,实现Comparator接口,覆盖compare方法。
注:字符串本身具备比较性,但是它的比较方式可能不是所需要的,这时,就只能使用比较器了。
import java.util.*;
//此接口强制让Student实现比较性
class Student implements Comparable
{
//定义Student私有属性
private String name;
private int age;
//构造Student函数,初始化
Student(String name,int age)
{
this.name = name;
this.age = age;
}
//公共访问方法,访问私有属性
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
//复写Comparator中的compare方法,自定义比较器
public int compareTo(Object obj)
{
//判断是否属于Student类型,否则抛异常
if (!(obj instanceof Student))
throw new RuntimeException("NotSuchTypeException");
//按年龄大小比较,相同则比较姓名大小,不同返回两年龄之差
Student s = (Student)obj;
if (this.age > s.age)
return this.age-s.age;
else if (this.age == s.age)
{
return this.name.compareTo(s.name);
}
return this.age-s.age;
}
}
//定义比较器,实现Comparator接口
class MyCompare implements Comparator
{
//重写Comparator中的compare方法,按姓名顺序排序
public int compare(Object o1,Object o2)
{
//判断给定对象是否为Student类,否则抛异常
if (!((o1 instanceof Student) && (o2 instanceof Student)))
throw new RuntimeException("NotSuchTypeException");
//将给定对象强转为Student类
Student s1 = (Student)o1;
Student s2 = (Student)o2;
//比较名字,返回数值,相同则比较年龄
int n = s1.getName().compareTo(s2.getName());
if (n == 0)
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
return n;
}
}
//测试
public class Temp
{
public static void main(String[] args)
{
//TreeSet ts = new TreeSet();
//创建集合,加入接口类参数,并添加元素
TreeSet ts = new TreeSet(new MyCompare());
ts.add(new Student("li01",25));
ts.add(new Student("li02",20));
ts.add(new Student("li01",22));
ts.add(new Student("li05",24));
ts.add(new Student("li08",40));
//打印集合中元素
printE(ts);
}
//定义打印集合中元素的功能
public static void printE(TreeSet ts)
{
//迭代器方法获取
Iterator it = ts.iterator();
while (it.hasNext())
{
//将返回的元素(Object类)强转为Student类
Student s = (Student)it.next();
System.out.println(s.getName() + "---" + s.getAge());
}
}
}