Collection集合框架
一. 概述
1. 数据多了可以存在数组当中,那对象多了就要存在集合中了,数组是固定长度的,但是集合是可变长度的,同一个数组中只能存同一种类型的数据,而集合中只要是对象就可以存储,简单说就是为方便对多个对象的操作,对对象进行存储,集合是存储对象最常见的一种方法。
2. 存储对象的集合称为容器,容器又分为很多种,主要是因为存储数据结果不同。
3. 集合中存储的都是对象的地址的引用(地址)。
4. 它提供更具体的子接口(如 Set 和 List)实现。
二. 集合和数组的区别
数组: 同一个数组只能存储同一种数据,但是长度一旦声明定义,就不可以改变,可以存数对象也可以存储基本数据类型,通常一般用于存储基本数据见多。
集合: 只可以存储对象,长度是可变的,类型可以不同。
三. 集合的特点
1. 只用于存储对象,长度可变,也可以存储不同类型的对象。
2. 集合是一个接口,将每一种容器的共性提取,形成一个体系。
四. 数据结构
由于每一种容器对数据的存储方式都不一样,所以出现了不同的容器,此种存储方式称之为数据结构。
五. 集合体系图
六. 集合中的共性方法
1. 增加:
boolean add(Object obj); à添加元素
boolean
addAll
(
Collection
<? extends
E
> c)
将指定 collection 中的所有元素都添加到此 collection 中
2. 删除:
boolean remove
(Object o)
; à如果存在的话,移除指定元素。
boolean removeAll(Collection<?> c);à移除此集合中包含给定集合中所有元素。
clear(); 删除此元素中的所有元素。
3. 获取:
int size();
booleanretainAll(Collection<?> c); à移除此集合中包含给定集合中之外元素。
4. 判断:
boolean contains(Object
o
); 判断给定元素e是否存在于集合中。
boolean isEmpty(); 判断此集合是否为空。
5. 集合变数组:
toArray()
6. 迭代器:
Iterator
<
E
>
itreator();返回次集合的元素迭代器。
boolean hasNext(); à判断是否还有下一个元素。
Object next();à取出下一个元素。
import java.util.*;
*/
class CollectionDemo
{
public static void main(String[] args)
{
method_get();
}
public static void method_get()
{
ArrayList al = new ArrayList();
//1,添加元素。
al.add("java01");//add(Object obj);
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 method_2()
{
ArrayList al1 = new ArrayList();
al1.add("java01");
al1.add("java02");
al1.add("java03");
al1.add("java04");
ArrayList al2 = new ArrayList();
al2.add("java03");
al2.add("java04");
al2.add("java05");
al2.add("java06");
//al1.retainAll(al2);//去交集,al1中只会保留和al2中相同的元素。
al1.removeAll(al2);
sop("al1:"+al1);
sop("al2:"+al2);
}
public static voidbase_method()
{
//创建一个集合容器。使用Collection接口的子类。ArrayList
ArrayList al = new ArrayList();
//1,添加元素。
al.add("java01");//add(Object obj);
al.add("java02");
al.add("java03");
al.add("java04");
//打印原集合。
sop("原集合:"+al);
//3,删除元素。
//al.remove("java02");
//al.clear();//清空集合。
//4,判断元素。
sop("java03是否存在:"+al.contains("java03"));
sop("集合是否为空?"+al.isEmpty());
//2,获取个数。集合长度。
sop("size:"+al.size());
//打印改变后的集合。
sop(al);
}
public static void sop(Objectobj)
{
System.out.println(obj);
}
}
List集合
一. 概述
List集合继承自Collection接口,List中包含三个子类:ArrayList、LinkedList以及Vector等。
二. ArrayList、LinkedList、Vector的区别
ArrayList:底层采用数据结构是数组。因为该集合存在索引角标,查询速度快,但是增删速度较慢,是线程不同步的。
LinkedList:底层采用的是链表数据结构。增删速度快,但是查询速度稍慢,因为每一个元素都链接到前一元素,要知道这个元素,必须先知道另一个元素,而要知道另一个元素,又必须现知道再另一个元素,线程不同步,当向LinkedList中添加一个对象时,实际上LinkedList内部会生成一个Entry对象,该Entry对象的结构为:
Entry
{
Entryprevious;
Objectelement;
Entrynext;
}
其中的Object类型的元素element就是我们向LinkedList中所添加的元素,然后Entry又构造好了向前与向后的引用previous、next,最后将生成的这个Entry对象加入到了链表当中。换句话说,LinkedList中所维护的是一个个的Entry对象。
Vector:底层采用的是数组结构,JDK1.0出现。增删查询都很慢,被ArrayList替代了,是线程同步。
三. List集合中特有共性集合操作方法
1. 增加:
boolean
add
(int index, E element)
在列表的指定索引插入指定元素(可选操作)。
boolean
addAll
(Collection<? extends E> c)
追加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序(可选操作)。
boolean
addAll
(int index, Collection<?extends E> c)
将指定 collection 中的所有元素都插入到列表中的指定位置(索引) ((可选操作)。
2. 删除:
E remove
(int index)
移除列表中指定索引的元素(可选操作)。返回的是被移除的元素。voidremoveRange
(intfromIndex, int toIndex)
移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素,该方法被protected修饰。
3. 修改:
E set
(int index, E element)
用指定元素替换列表中指定索引的元素(可选操作)
4.查询:
E get
(int index)
返回列表中指定位置的元素。
int indexOf
(Objectelem
ent
)
搜索给定参数第一次出现的位置,使用equals 方法进行相等性测试。
int lastIndexOf
(Object elem)
返回指定的对象在列表中最后一次出现的位置索引。
List<E>subList
(int fromIndex, int toIndex)
返回列表中指定的fromIndex(包括 )和toIndex(不包括)之间的部分视图。
注意:
1. listIterator是List特有的迭代器,是Iterator子接口。
2. 在迭代时,不可通过集合对象的方法操作集合中的元素,因为会发生ConcurrentModficationException(有并发的错误异常)异常。所以,在迭代时,只能用迭代器的方法操作,可Iterator方法是有限的,若想要其他操作如增删改写等,就需要使用子接口,即ListIterator,该接口只能通过List集合的listIerator()方法获取。
2. 在迭代时,循环中的next()调用一次,就要对hasNext判断一次,不可判断一次调用两次。
3. List集合判断元素是否相同,依据的是元素的equals方法,其中,contains中就是调用的equals方法。
4. Iterator和ListIterator是一个接口,而且ListIterator继承了Iterator,是一个迭代器,迭代器是List中特有的取出方法,List集合中的成员都具备一个获取迭代器的方法iterator()和ListIterator(),而Iterator是一个接口,那么又是如何通过iterator()获取迭代器呢?是因为ArrayList和LinkedList的父类实内部封装了一个内部类,这个内部类itr实现了Iterator接口,除了这个类之外,还有另外一个内部类,这个内部类继承了itr且实现了ListIterator,当我们调用iterator()和ListIterator()方法的时候,就会返回一个和集合相关联的迭代器。
1.
import java.util.*;
class ListDemo
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
methodAdd();
//methodListIterator();
}
public static void methodAdd()
{
//创建一个集合容器,使用Collection接口的子类,ArrayList
ArrayList list = new ArrayList();
//1.添加元素--->add(Object obj),多态
list.add("java01");
list.add("java02");
list.add("java03");
list.add("java04");
ArrayList list2 = new ArrayList();
//1.添加元素--->add(Object obj),多态
list2.add("java05");
list2.add("java06");
list2.add("java07");
list2.add("java08");
//打印原集合
sop("原集合:" + list);
sop("------------------");
//1.在某一个位置上添加元素:add(int index,"新元素")
list.add(1,"java001");
sop("增加后的集合:" + list);
sop("---------");
list.addAll(1,list2);
sop("在list中1位置后添加list2:" + list);
sop("------------------");
//2.删除指定位置上的元素:
list.remove(2);
sop("删除后的集合:" + list);
sop("------------------");
//3.改变某一位置上的元素:set(int index,"要改成的元素")
list.set(2,"java007");
sop("改变角标为2的元素后的元素:" + list);
sop("------------------");
//4.获取元素:get()
list.get(1);
sop("获取角标为1上的元素:" + list.get(1));
sop("------------------");
//通过某个元素获取其在集合中的位置--indexOf("查找的元素")
int m = list.indexOf("java007");
sop("获取“java007”所在的位置:" + m);
//获取从某个位置到另一位置上的元素subList()
List l = list.subList(1,3);
sop("获取从位置1到3上的元素:" + l);
sop("------------------");
//4.获取全部元素
//get方法的for循环
sop("get方法:");
for (int i=0;i<list.size();i++)
{
sop("list(" + i + ")" + list.get(i));
}
sop("------------------");
//迭代器方法:Iterator()
for (Iterator it = list.iterator();it.hasNext(); )
{
sop("next:" + it.next());
}
sop("------------------");
}
public static void methodListIterator()
{
//演示列表迭代器:
ArrayList list = new ArrayList();
//1.添加元素--->add(Object obj),多态
list.add("java01");
list.add("java02");
list.add("java03");
list.add("java04");
//打印原集合
sop("原集合:" + list);
sop("------------------");
//在迭代过程中,准备添加或删除元素
for (ListIterator it = list.listIterator();it.hasNext(); )
{
Object obj = it.next();
if (obj.equals("java01"))
it.remove();
else if(obj.equals("java02"))
it.add("增加java200");
else if(obj.equals("java03"))
it.set("修改为java300");
sop("obj:" + obj);
}
sop("list :" + list);
}
import java.util.*;/*去除ArrayList集合中的重复元素。*/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("java02");al.add("java01");al.add("java02");al.add("java01");// al.add("java03");/*在迭代时循环中next调用一次,就要hasNext判断一次。Iterator it = al.iterator();while(it.hasNext()){sop(it.next()+"...."+it.next());}*//**/sop(al);al = singleElement(al);sop(al);}public static ArrayList singleElement(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;}}
import java.util.*;
/*
将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
比如:存人对象。同姓名同年龄,视为同一个人。为重复元素。
思路:
1,对人描述,将数据封装进人对象。
2,定义容器,将人存入。
3,取出。
List集合判断元素是否相同,依据是元素的equals方法。
*/
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;
//System.out.println(this.name+"....."+p.name);
returnthis.name.equals(p.name) && this.age == p.age;
}
/**/
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
class ArrayListTest2
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
ArrayList al = new ArrayList();
al.add(new Demo());
al.add(newPerson("lisi01",30));//al.add(Object obj);//Object obj = newPerson("lisi01",30);
//al.add(new Person("lisi02",32));
al.add(new Person("lisi02",32));
al.add(new Person("lisi04",35));
al.add(new Person("lisi03",33));
//al.add(new Person("lisi04",35));
//al = singleElement(al);
sop("remove 03:"+al.remove(new Person("lisi03",33)));//remove方法底层也是依赖于元素的equals方法。
Iterator it = al.iterator();
while(it.hasNext())
{
Person p = (Person)it.next();
sop(p.getName()+"::"+p.getAge());
}
}
public static ArrayList singleElement(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;
}
}
四. Vector集合
Vector中有种特殊的取出方式,即为枚举
1. 枚举和迭代器十分相似,其实两者是一样的,由于枚举的名称以及方法名都过长,因此,就被迭代器取代了。这里就不过多的介绍了。获取枚举
:
Enumeration<?> elements
();
返回此向量的组件的枚举。
2. 示例代码:
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());
}
}
}
五. LinkedList集合中特有的方法
1. JDK1.6之前的方法
增加: addFirst
(E o)
将给定元素插入此列表的开头。addLast
(E o)
将给定元素追加到此列表的结尾。
获取:EgetFirst
()
返回此列表的第一个元素,但不删除元素,若集合中没有元素,则出现NoSuchElementsException。E getLast
()
返回此列表的最后一个元素,但不删除元素,若集合中没有元素,则出现NoSuchElementsException。
删除:EremoveFirst
()
移除并返回此列表的第一个元素,但是元素被删除,若集合中没有元素,则出现NoSuchElementException。E removeLast
()
移除并返回此列表的最后一个元素,但是元素被删除,若集合中没有元素,则出现NoSuchElementException。
2. JDK1.6出现的替代方法
增加:offerFirst
(E o)
将给定元素插入此列表的开头。offerLast
(E o)
将给定元素追加到此列表的结尾。
获取:peakFirst
()
返回此列表的第一个元素,但不删除元素,若集合中没有元素,则出现null。peakLast
()
返回此列表的最后一个元素,但不删除元素,若集合中没有元素,则出现null。
删除:
pollFirst
()
移除并返回此列表的第一个元素,但是元素被删除,若集合中没有元素,则出现null。
pollLast
()
移除并返回此列表的最后一个元素,但是元素被删除,若集合中没有元素,则出现null。
importjava.util.*;
classLinkedListDemo
{
public static void main(String[] args)
{
LinkedList link = new LinkedList();
link.addLast("java01");
link.addLast("java02");
link.addLast("java03");
link.addLast("java04");
//sop(link);
// sop(link.getFirst());
// sop(link.getFirst());
//sop(link.getLast());
//sop(link.removeFirst());
//sop(link.removeFirst());
//sop("size="+link.size());
while(!link.isEmpty())
{
sop(link.removeLast());
}
}
publicstatic void sop(Object obj)
{
System.out.println(obj);
}
}
/*
使用LinkedList模拟一个堆栈或者队列数据结构。
堆栈:先进后出如同一个杯子。
队列:先进先出 First in First out FIFO 如同一个水管。
*/
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.removeFirst();
}
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());
}
}
}
Set 集合
一. 概述
一个不包含重复元素的 collection。更正式地说,set 不包含满足 e1.equals(e2)
的元素对 e1
和 e2
,并且最多包含一个 null 元素。元素是无序的(存入和取出的顺序不一定一致),此实现不是同步的。。
二. 哈希表简介
哈希表是按照哈希值的大小进行排列的,如果两个哈希值不同,则大的值放后面;如果两个哈希值相同,则再用equals方法比较两个元素的对象是否相同,如果不同,则将第二个值顺延,两个值串起来,放在同一个位置上。
取值时是按照哈希值取出来的。
三. Set集合的特点
1. 元素不可重复,更正式地说,set 不包含满足 e1.equals(e2)
的元素对e1
和e2
,
并且最多包含一个 null元素。
2. 集合中的元素是无序的(存入和取出的顺序是不一定一致的)
3. Set集合的功能和Collection集合的是一样的,并没有什么特别的方法。
四. HashSet
此Set集合底层数据结构是哈希表构成,且元素取出方式只有迭代器方法,其父类AbstractSet<E>内部类实现了Iterator接口,当调用HashSet的Iterator()方法时,是调用其父类的iterator()方法返回一个迭代器。
1. HashSet是如何保证元素的唯一性呢?
是通过元素的两个方法,hashCode()和equals(Object obj)来完成的。
如果元素的hashcode值相同,才会去判断equals是否为true,如果元素的 hashcode值不同,不会调用equals。
注意: 对于判断元素是否存在,添加、以及删除等操作,依赖的方法是元素的hashcode和equals方法。
示例代码1:
class HashSetDemo
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
HashSet hs = new HashSet();
sop(hs.add("java01"));
sop(hs.add("java01"));
hs.add("java02");
hs.add("java03");
hs.add("java03");
hs.add("java04");
Iterator it = hs.iterator();
while(it.hasNext())
{
sop(it.next());
}
}
}
示例代码2:
/*思路:
1、对人描述,将数据封装进对象
2、定义容器,将人存入
3、取出
4、移除
*/
import java.util.*;
class TypeException extends Exception
{
TypeException(String message)
{
super(message);
}
}
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;
}
public int hashCode()
{
return this.name.hashCode()+age*39;
}
public boolean equals(Object obj)
{
try
{
if (!(obj instanceof Person))
throw new TypeException("NoSuchTypeException");
}
catch (TypeException e)
{
System.out.println(e.toString());
}
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}
}
class HashDemo
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void printE(HashSet hs)
{
Iterator it = hs.iterator();
while (it.hasNext())
{
Person p = (Person)it.next();
sop(p.getName() + "--" + p.getAge());
}
}
public static void main(String[] args)
{
HashSet hs = new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
sop("原集合:");
printE(hs);
sop("移除后的集合:");
hs.remove(new Person("a3",13));
printE(hs);
}
}
五. TreeSet集合
此类保证排序后的 set 按照升序排列元素,根据使用的构造方法不同,可能会按照元素的自然顺序 进行排序(参见 Comparable),或按照在创建 set 时所提供的比较器进行排序。此实现不是同步的。
TreeSet继承了AbstractSet,其父类AbstractSet<E>内部类实现了Iterator接口,当调用HashSet的Iterator()方法时,是调用其父类的iterator()方法返回一个迭代器,此Set集合底层数据结构是二叉树构成,且元素取出方式只有迭代器方法。
1. 特点
A.底层采用的数据结构是二叉树(红黑树结构)。
B. 可以对Set集合中的元素进行排序。假如存入的元素本身具有比较性,TreeSet内部会自动将这些元素按照自然升序进行排序存放,假如存入的元素自身不具有比较性,程序在运行时会发生Exceptionin thread "main"java.lang.ClassCastException:com.Test1.Car cannot be cast to java.lang.Comparable。
C.保证数据唯一性的依据:元素的compareTo方法的返回值,是正整数、负整数或零,则两个对象较大、较小或相同。相等时则不会存入。.
2.如何让元素自身具备比较性?
让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。也种方式也成为元素的自然顺序,或者叫做默认顺序
/*
第一种排序方式:自然排序,元素实现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则按倒叙输出
}
*/
}
//测试
class TreeSetTest
{
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);
System.out.println("Hello World!");
}
//定义打印集合中元素的功能
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());
}
}
}
3. TreeSet排序的两种方式
A. 自然排序: 让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法,这种方式也称为元素的自然排序或默认排序方式。
/*
第一种排序方式:自然排序,实现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则按倒叙输出
}
*/
}
//测试
class TreeSetTest
{
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);
System.out.println("Hello World!");
}
//定义打印集合中元素的功能
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());
}
}
}
B. 比较器:当元素自身不具备比较性是,或者具备比较性,却不是所需要的,这时就需要让集合自身具备比较性。在集合初始化时就有了比较方式(即参阅构造函数),其实就是定自己定一个比较器,这个比较器必须实现Comparator接口,并实现其compare(Object o1,Object o2)方法,方法的返回值,是正整数、负整数或零,则两个对象较大、较小或相同,然后将这个比较器作为参数传入TreeSet构造方法中。
注意: 当两种排序方式都存在时,以比较器为主,排序时,当主要条件相同时,按次要条件排序。
字符串本身具备比较性,但是它的比较方式可能不是所需要的,这时,就只能使用比较器了。
package com.Test1;
import java.util.*;
public class TreeSetDemo04
{
public staticvoid main(String[] args)
{
TreeSet ts = newTreeSet(new MyComparator());
ts.add("Ansen");
ts.add("Ansen");
ts.add("Ansenvery good");
ts.add("Ansenvery well");
ts.add("Ansenvery aaaa");
Iterator i =ts.iterator();
while(i.hasNext())
{
System.out.println(i.next());
}
}
}
class MyComparator implements Comparator
{
public intcompare(Object o1 ,Object o2)
{
if(o1 == null ||o2 == null )
{
throw newRuntimeException("传入的Object 类型的对象为null");
}
if(!(o1instanceof String ) || !(o2 instanceof String))
{
throw newRuntimeException("传入的对象为并非String类型");
}
else
{
String s1 =(String)o1;
String s2 = (String)o2;
intnumber = new Integer(s1.length()).compareTo(new Integer(s2.length()));
if(number == 0)
{
returns1.compareTo(s2);
}
else
{
return number;
}
}
}
}
示例2:
//此接口强制让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;
}
}
//测试
class TreeSetComDemo
{
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());
}
}
4. 二叉树的存取方式图
大的元素放右边,小的元素放左边。