现在的位置: 首页 > 综合 > 正文

读JSE源码(三)集合之TreeSet

2018年11月07日 ⁄ 综合 ⁄ 共 4305字 ⁄ 字号 评论关闭

1 TreeSet介绍

TreeSet实现了接口SerializableCloneableIterable<E>, Collection<E>, NavigableSet<E>, Set<E>, SortedSet<E>。

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{
    /**
     * The backing map.
     */
    private transient NavigableMap<E,Object> m;

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

它的三个构造函数如下:

(1)

    public TreeSet() {
        this(new TreeMap<E,Object>());
    }

this(new TreeMap<E,Object>());调用的私有构造函数如下

    /**
     * Constructs a set backed by the specified navigable map.
     */
    TreeSet(NavigableMap<E,Object> m) {
        this.m = m;
    }

可以看到TreeSet采用了TreeMap作为其Map保存“键-值”对,所以TreeSet判断元素重复是依靠Comparable接口或Comparator接口实现的。

使用该构造函数时,Set对象要实现Comapreble接口。

(2)这个构造函数会传入一个实现了Comparator接口的比较器对象,所以Set对象不需要实习Comparable接口


    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }

(3)该构造函数传入一个Collection对象,将Collection对象中的元素添加到TreeSet中,Collection中的元素要实现Comparable接口

Constructs a new tree set containing the elements in the specified collection, sorted according to the natural ordering of its elements. All elements inserted into the set must implement the Comparable interface. Furthermore, all such elements must bemutually comparablee1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the set.

    public TreeSet(Collection<? extends E> c) {
        this();
        addAll(c);
    }

(4)该构造函数传入一个SortedSet对象,所以TreeSet中元素的排序与SortedSet中的排序一样

Constructs a new tree set containing the same elements and using the same ordering as the specified sorted set.

    public TreeSet(SortedSet<E> s) {
        this(s.comparator());
        addAll(s);
    }

2 TreeSet使用(增删查改)

package zyang.set;

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;


/** 
 * @author  secret
 * @version 1.0
 * @date    2012-11-30 下午4:26:28 
 * @fuction TreeSet使用(增删查改)
 */

public class TreeSetTest 
{
    //print
	public static void printElements(Collection c)
	{
		Iterator it =c.iterator();
		while(it.hasNext())
		{
			System.out.println(it.next());
		}
	} //printElements(Collection c)
	
     public static void main(String[] args) {
    	//TreeSet的对象要实现Comparble接口或者传入实现了Comparat接口的对象
		Set ts=new TreeSet(new CompareStudentByNum() );
		
		//---1 元素(学生类)-----------------------------------------------
		Student s1=new Student(0, "王五");
		Student s2=new Student(1, "李四");
		Student s3=new Student(2, "万三");
		
		//---1 增加元素-----------------------------------------------
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		
		//---2 删除元素-----------------------------------------------
		ts.remove(s3);
		
		//---3 修改元素(先转换为数组,修改数组,再添加)-----------------------------------------------
		Object[] obj=ts.toArray();
		ts.clear(); //清空Set
		for(int i=0;i<obj.length;i++)
		{
			Student s=(Student)obj[i];
			if(s.getName().equals("李四"))
			{
				s.setName("刘二");
				obj[i]=s;
			} //end if
			ts.add(obj[i]);		 //添加到Set中
		} //end for
		
		//---4 查找元素-----------------------------------------------
		Iterator it=ts.iterator();
		while(it.hasNext())
		{
			Student st=(Student)it.next();
			if(st.getNum()==1)
			{
				System.out.println("学号为1的学生是"+st.getName());
				break;
			}//end if
				
		}// end while
		
	}
}

Student类

package zyang.set;

/** 
 * @author  secret
 * @version 1.0
 * @date    2012-11-30 上午10:01:05 
 * @fuction 学生类
 */

public class Student {
	
	//---property-----------------------------------------------
	//学号
	int num;
	//姓名
	String name;
	
	//---constructor-----------------------------------------------
	public  Student (int num,String name)
	{
		this.num=num;
		this.name=name;
	}
	
	//---set, get method-----------------------------------------------
	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}


	@Override
	public String toString() {
		return "Student [num=" + num + ", name=" + name + "]";
	}
}

自定义实现比较算法

package zyang.set;

import java.util.Arrays;
import java.util.Comparator;

/** 
 * @author  secret
 * @version 1.0
 * @param <T>
 * @date    2012-11-30 上午10:06:23 
 * @fuction 实现Comparator接口的比较算法 
 * 按学号排序 先按学号排序,学号相等时,按姓名排序 o1>o2返回1,o1=o2返回0,o1>o2返回-1 
 */

public class CompareStudentByNum  implements Comparator
{
	public int compare(Object o1, Object o2) {
		Student s1=(Student)o1;
		Student s2=(Student)o2;
		
		//按学号排序
		int result=s1.num > s2.num ? 1 : ( (s1.num==s2.num) ? 0: -1 );
		//学号相等时,按姓名排序
		if(result==0)
		{
			int copmpareName=s1.name.compareTo(s2.name);
			//利用String的compareTo方法进行字符的比较  
			if(copmpareName>0)
				result=1;
			else if (copmpareName==0)
				result=0;
			else
				result=-1;	
		}
		
		return result;
	}
	
	public static void main(String[] args) {
		Student[] s=new Student[2];
		s[0]=new Student(1, "zhangsan");
		s[1]=new Student(0, "lisi");
		
		Arrays.sort(s, new CompareStudentByNum());
		
		for(Student t: s)
		{
			System.out.println(t.toString());
		}
		
	}

}

TreeSet如何保证元素是否重复

TreeSet是依靠TreeMap来实现的,所以是根据实现的Compareble接口或Comparator接口来判断元素是否重复,其排序与TreeMap一样。

抱歉!评论已关闭.