集合框架
集合类:就是用于用于存储数据的容器,面向对象语言对事物的大多以对象来体现,多以为了方便对多个对象的操作,就产生了对对象存储的集合。
集合与数组的区别:
1.数组长度是固定的而集合长度可变。
2.集合存储基本数据类型而集合只能存储对象
3.集合存储的数据必须为同一类型,集合可以有多种。
根据存储的方式的不同,抽取出了各种类型的容器,这个存储方式称之为数据结构
Collection接口是这些容器的顶层接口,该接口的方法是各个容器的共性方法。
1.添加:
add(object),添加一个元素
addAll(collection),添加一组元素
2.删除:
remove(object),删除一个元素,集合长度会改变
removeAll(collection),删除一组元素
clear(),将集合中的元素清空
3.判断:
boolean contains(object),是否包含某元素
boolean contains(object),是否包含一组元素
boolean isEmpty(),集合是否为空
4.获取:
int size(),获取集合长度
5.取交集
boolean retainAll(Collection),取交集,原集合只会保留和指定集合相同的元素
6.获取集合中的元素
Iterator iterator().
7.将集合变为数组
toArray().
下面通过程序实现这些方法:
package xiaobing.collection;
import java.util.*;
/*
* add方法得参数类型是Object,以便接受任意对象
* 集合中存储的都是对象的引用
*/
public class CollecttionDemo01 {
public static void main(String[] args)
{
//创建一个容器使用Collection的子类ArrayList
ArrayList al=new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
//打印集合
sop("元集合:"+al);
//获取集合长度
sop(al.size());
//删除元素
al.remove("java02");
sop("删除后集合:"+al);
//判断元素
sop("java03是否存在:"+al.contains("java03"));
sop("集合收费欧为空?"+al.isEmpty());
method();//al1中只会保留与al2中相同的元素
}
//取交集
public static void method()
{
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);
//打印验证结果
sop(al1);
sop(al2);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
迭代器:Iterator.
每一个集合都有自己的数据结构,都有特定的取出自己内部元素的方式。为了便于操作所有的容器,取出元素。将容器内部的取出方式按照一个统一的规则向外提供,这个规则就是Iterator接口。
所以可以用循环取得元素
Iterator it=al.iterato();
for(Iterator it=al.iterato();it.hasNext();){it.next()}
List接口:
List是Collection接口的子接口,具备了Collection的所有方法。List的特有方法都有索引,这就是该集合最大的特点。
List:有序(元素存入集合的顺序和取出的顺序一致),元素都有索引。元素可以重复。
List接口的三个子接口:
ArrayList:底层的数据结构是数组,线程不同步,ArrayList替代了Vector,查询元素的速度非常快。
LinkedList:底层的数据结构是链表,线程不同步,增删元素的速度非常快。
Vector:底层的数据结构就是数组,线程同步的,Vector无论查询和增删都很慢。
list中方法
1,添加:
add(index,element) :在指定的位置插入元素。
addAll(index,collection) :在指定的位置插入一组元素。
2,删除:
remove(index) :删除指定位的元素。 返回被删的元素,可以用来获取元素。
3,获取:
Object get(index) :通过索引获取指定元素。
int indexOf(obj) :获取指定元素第一次出现的索引位,不存在返回-1,所以可以判断一个元素是否存在。
int lastIndexOf(Object o) :反向索引指定元素的位置。
List subList(start,end) :获取子列表。
4,修改:
Object set(index,element) :对指定索引位进行元素的修改。
5,获取所有元素:
ListIterator:list集合特有的迭代器。
List存在角标,所以可以通过循环用get(index)来获取元素。
List集合方法练习:
package xiaobing.collection;
import java.util.*;
public class LinkDemo01 {
public static void main(String[] args)
{
ArrayList al=new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
//删除指定位置的元素
//al.remove(2);
//修改指定位置的元素
//al.set(2,"java07");
sop("元集合是...."+al);
//从指定位置添加元素
al.add(1, "java09");
//通过角标获取元素
sop("get(1)..."+al.get(1));
//获取所有元素,由于有角标用get方法来实现
for(int x=0;x<al.size();x++)
{
System.out.println("al("+x+")="+al.get(x));
}
//用迭代器取出元素
Iterator it=al.iterator();
while(it.hasNext())
{
sop("next="+it.next());
}
//通过indexOf获取元素的位置
sop("index..."+al.indexOf("java02"));
List sub=al.subList(1, 3);
sop("sub..."+sub);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
当我们想再迭代的时候操作元素(增、删、改)时由于容器和迭代器都在操作元素,这样就会产生并发操作异常,为了在操作的时候使用元素,List集合了了特有的迭代器,ListIterator。
package xiaobing.collection;
import java.util.*;
public class LinkDemo02 {
public static void main(String[] args)
{
ArrayList al=new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
//特有迭代
ListIterator li=al.listIterator();
//遍历元素
while(li.hasNext())
{
Object obj=li.next();
if(obj.equals("java02"))
li.add("java009");//遍历过程中操作元素
//li.set("java006");
}
//反向获取
while(li.hasPrevious())
{
sop(li.previous());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
ArrayList集合练习:
package xiaobing.collection;
import java.util.*;
/*
* 需求:去除ArrayList集合中的重复元素
* 思路:遍历集合
* 判断是否重复
* 存入判断后的元素进入新的集合
*/
public class ArrayListTest01 {
public static void main(String[] args)
{
ArrayList al=new ArrayList();
al.add("java01");
al.add("java02");
al.add("java02");
al.add("java03");
al.add("java03");
al.add("java04");
sop("原元集合..."+al);
sop("去除重复后集合。。。。"+method(al));
}
public static ArrayList method(ArrayList al)
{
ArrayList newal=new ArrayList();//定义临时容器
Iterator it=al.iterator();
while(it.hasNext())
{
Object obj=it.next();//获取元素
if(!newal.contains(obj))//判断是否重复
newal.add(obj);//不重复时存入新集合
}
return newal;
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
练习2:
package xiaobing.collection;
import java.util.*;
/*
* 将自定义对象作为元素存入ArrayList集合中,并去除重复元素
* 比如人,同年龄、同姓名视为同一个人,为重复元素
* 思路:
* 1.对人描述
* 2.定义容器进行存储
* 3.取出
* 4.复写equals方法
* List集合判断元素是否相同,判断的是元素的equal方法
*/
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;
return this.name.equals(p.name)&&this.age==p.age;
}
}
public class ArrayListTest02 {
public static void main(String[] args)
{
ArrayList al=new ArrayList();
al.add(new Person("lisi01",30));
al.add(new Person("lisi02",32));
al.add(new Person("lisi02",32));
al.add(new Person("lisi03",33));
al.add(new Person("lisi04",35));
al.add(new Person("lisi02",32));
al=method(al);
Iterator it=al.iterator();
while(it.hasNext())
{
Object obj=it.next();
Person p=(Person)obj;
sop(p.getName()+"....."+p.getAge());
}
}
public static ArrayList method(ArrayList al)
{
ArrayList newal=new ArrayList();
Iterator it=al.iterator();
while(it.hasNext())
{
Object obj=it.next();//获取元素
if(!newal.contains(obj))//判断是否重复
newal.add(obj);//不重复时存入新集合
}
return newal;
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
Set接口
哈希表的原理:
1,对对象元素中的关键字(对象中的特有数据),进行哈希算法的运算,并得出一个具体的算法值,这个值称为哈希值。
2,哈希值就是这个元素的位置。
3,如果哈希值出现冲突,再次判断这个关键字对应的对象是否相同。如果对象相同,就不存储,因为元素重复。如果对象不同,就存储,在原来对象的哈希值基础 +1顺延。
TreeSet:对Set集合中的元素的进行指定顺序的排序。不同步。TreeSet底层的数据结构就是二叉树。
存入自定义对象示例:
package xiaobing.collection;
import java.util.*;
/*
* 网hashset集合存入自定义对象,去除重复元素
*/
class Person1
{
private String name;
private int age;
Person1(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
//复写hashCode判断哈希值
public int hashCode()
{
return name.hashCode()+age;
}
//重写equals方法,定义比较规则
public boolean equals(Object obj)
{
if(!(obj instanceof Person1))
return false;
Person1 p=(Person1) obj;
return this.name.equals(p.name)&&this.age==p.age;
}
}
public class HashSetDemo {
public static void main(String[] args)
{
HashSet hs=new HashSet();
hs.add(new Person1("a1",11));
hs.add(new Person1("a2",12));
hs.add(new Person1("a3",13));
hs.add(new Person1("a2",12));
sop(hs);
Iterator it=hs.iterator();
while(it.hasNext())
{
Person1 p=(Person1) it.next();
sop(p.getName()+"..."+p.getAge());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
第二个子接口:
TreeSet:可以集合中的元素进行自然顺序排序。
那么存储自定义对象该如何排序呢?
代码:
package xiaobing.collection;
import java.util.*;
/*
* 需求:往TreeSet集合存储顶顶一学生,按照年龄排序
* 排序时主要条件相同时,一定要判定次要条件。
*/
class Student implements Comparable//该接口让学生类强制具有比较性
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
//复写compareTo方法,比较年龄
public int compareTo(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s=(Student) obj;
if(this.age>s.age)
return 1;
if(this.age==s.age)
{
//年龄相等的情况再进行姓名排序
return this.name.compareTo(s.name);
}
return -1;
}
}
public class TreeSetDemo {
public static void main(String[] args)
{
TreeSet ts=new TreeSet();
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi01",40));
Iterator it=ts.iterator();
while(it.hasNext())
{
Student stu=(Student) it.next();
sop(stu.getName()+"..."+stu.getAge());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
第二种排序方式:
package xiaobing.collection;
import java.util.*;
/*
* TreeSet的第二种排序方式:
* 当元素自身不具备比较性时,或者具备的比较性不是所需要的
* 这时就系要让集合自身具备比较性
* 在集合初始化时,就有了比较性(构造函数)。
* 定义比较器对象,作为参数传入集合
*/
class Student1 implements Comparable//该接口让学生类强制具有比较性
{
private String name;
private int age;
Student1(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
//复写compareTo方法,比较年龄
public int compareTo(Object obj)
{
if(!(obj instanceof Student1))
throw new RuntimeException("不是学生对象");
Student1 s=(Student1) obj;
if(this.age>s.age)
return 1;
if(this.age==s.age)
{
//年龄相等的情况再进行姓名排序
return this.name.compareTo(s.name);
}
return -1;
}
}
//定义自己的比较器实现Comparator接口
class MyCompare implements Comparator
{
public int compare(Object o1,Object o2)
{
Student1 s1=(Student1) o1;
Student1 s2=(Student1) o2;
int num=s1.getName().compareTo(s2.getName());
if(num==0){
if(s1.getAge()>s2.getAge())
return 1;
if(s1.getAge()==s2.getAge())
return 0;
return -1;
}
return num;
}
}
public class TreeSetDemo02 {
public static void main(String[] args)
{
TreeSet ts=new TreeSet(new MyCompare());
ts.add(new Student1("lisi02",22));
ts.add(new Student1("lisi007",20));
ts.add(new Student1("lisi09",19));
ts.add(new Student1("lisi06",18));
Iterator it=ts.iterator();
while(it.hasNext())
{
Student1 stu=(Student1) it.next();
sop(stu.getName()+"..."+stu.getAge());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}