Java 集合框架 - Collection体系部分

时间:2022-10-25 19:36:21

Collection集合框架

一.  概述

1.      数据多了可以存在数组当中,那对象多了就要存在集合中了,数组是固定长度的,但是集合是可变长度的,同一个数组中只能存同一种类型的数据,而集合中只要是对象就可以存储,简单说就是为方便对多个对象的操作,对对象进行存储,集合是存储对象最常见的一种方法

2.      存储对象的集合称为容器,容器又分为很多种,主要是因为存储数据结果不同。

3.      集合中存储的都是对象的地址的引用(地址)。

4.      它提供更具体的子接口(如 SetList)实现。

二.  集合和数组的区别
数组:
同一个数组只能存储同一种数据,但是长度一旦声明定义,就不可以改变,可以存数对象也可以存储基本数据类型,通常一般用于存储基本数据见多。

集合: 只可以存储对象,长度是可变的,类型可以不同。

三.  集合的特点

1.     只用于存储对象,长度可变,也可以存储不同类型的对象。

2.     集合是一个接口,将每一种容器的共性提取,形成一个体系。

四. 数据结构
由于每一种容器对数据的存储方式都不一样,所以出现了不同的容器,此种存储方式称之为数据结构。

五.  集合体系图

Java 集合框架 - Collection体系部分

六. 集合中的共性方法
1. 增加:

boolean add(Object obj); à添加元素
boolean addAll(Collection<? extendsE> 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(Objectelement) 搜索给定参数第一次出现的位置,使用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) 的元素对 e1e2,并且最多包含一个 null 元素。元素是无序的(存入和取出的顺序不一定一致),此实现不是同步的。。

二. 哈希表简介

哈希表是按照哈希值的大小进行排列的,如果两个哈希值不同,则大的值放后面;如果两个哈希值相同,则再用equals方法比较两个元素的对象是否相同,如果不同,则将第二个值顺延,两个值串起来,放在同一个位置上。

取值时是按照哈希值取出来的。

三. Set集合的特点

1.      元素不可重复,更正式地说,set 不包含满足 e1.equals(e2) 的元素对e1e2并且最多包含一个 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.       二叉树的存取方式图

大的元素放右边,小的元素放左边。

Java 集合框架 - Collection体系部分