黑马程序员-Set-HashSet-TreeSet-Comparator-Comparable

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
l Set

特点:

1. 无序(存储和查询的顺序不同,因为是按照对象的地址值存储进去的)。

2. 不可重复。

 

通过查看APISet的功能与Collection是一样的。

 

常用子类

1. HashSet

2. TreeSet

 

l HashSet

HashSet如何保证元素的唯一性?

原理:将对象存储在HashTable中,HashTable是通过该对象自己的HashCode得出地址的。当两个对象的地址相同时,还要判断其内容是否相同(使用equals())方法。

 

需求:

将自己定义的Person对象存储到HashSet中,重写HashCode()equals()方法。

 

代码:

package com.lxh.collection;

public class Person {
	private String name;
	private int age;
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
	
	public String get() {
		return name + "::" + age;
	}
	
	public int hashCode() {
		// return name.hashCode() + age*39;
		return 90;
	}
	
	public boolean equals(Object obj){
		if(!(obj instanceof Person))
			return false;
		Person p = (Person)obj;
		System.out.println(this.name + "...equals..." + p.name );
		return this.age == p.age && this.name.equals(p.name);
	}

}
package com.lxh.collection;
import java.util.*;
public class package com.lxh.collection;
import java.util.*;
public class HashSetDemo {

	public static void main(String[] args) {
		
		HashSet hs = new HashSet();
		hs.add(new Person("aaa",10));
		hs.add(new Person("bbb",12));
		hs.add(new Person("ccc",14));
		hs.add(new Person("aaa",10));
		
		Iterator it = hs.iterator();
		
		while(it.hasNext()) {
			Person p = (Person)it.next();
			System.out.println(p.get());
		}
		
	}

}

 {

	public static void main(String[] args) {
		
		HashSet hs = new HashSet();
		hs.add(new Person("aaa",10));
		hs.add(new Person("bbb",12));
		hs.add(new Person("ccc",14));
		hs.add(new Person("aaa",10));
		
		Iterator it = hs.iterator();
		
		while(it.hasNext()) {
			Person p = (Person)it.next();
			System.out.println(p.get());
		}
		
	}

}

输出结果:

bbb...equals...aaa

ccc...equals...bbb

ccc...equals...aaa

aaa...equals...ccc

aaa...equals...bbb

aaa...equals...aaa

ccc::14

bbb::12

aaa::10

l TreeSet

两个或两个以上的对象想要加入TreeSet中时,需要实现Comparable<T>接口,此对象可以对元素按照自然排序进行排序。

Comparable<T>接口

此接口强行对实现它的对象进行整体排序,这种排序被称为自然排序,类的compareTo()方法被称之为自然排序方法。

TreeSet如何保证元素的唯一性?

记录的对象实现Comparable<T>接口,通过compareTo()方法进行比较。

 

常用方法:

int compareTo(T o)

如果该对象<,=或>,则返回负数,零和正数,通常使用 -11

重写的CompareTo(Object obj)方法,对应一级比较内容相同时,可以比较二级字段。

package com.lxh.collection;

public class Person implements Comparable {
	private String name;
	private int age;
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
	
	public String get() {
		return name + "::" + age;
	}
	
	public int compareTo(Object obj) {
		if(!(obj instanceof Person))
			throw new RuntimeException("不是Person对象");
		
		/**
		 * 直接返回1,是正向排序
		 * 直接返回-1,是逆向排序
		 * 直接返回0,只返回第一个对象
		 * */
//		return 1;
		
		Person p = (Person)obj;
		if(age < p.age)
			return -1;
		if(age == p.age) {
			return this.name.compareTo(p.name); 
		}
		return 1;
	}
	

}
package com.lxh.collection;
import java.util.*;
public class TreeSetDemo {

	public static void main(String[] args) {
		TreeSet ts = new TreeSet();
		
		ts.add(new Person("001",23));
		ts.add(new Person("002",22));
		ts.add(new Person("003",24));
		ts.add(new Person("004",23));
		
		Iterator it = ts.iterator();
		
		while(it.hasNext()) {
			Person p = (Person)it.next();
			System.out.println(p.get());
		}
	}

}

当不能修改实现了Comparable接口的对象的compareTo()方法时,或者compareTo()方法不能够买足需求,可以考虑让集合自身具备比较的性能。通过TreeSet的构造方法来实现:

TreeSet(Comparator<? super E> comparator) 
构造一个新的空 TreeSet,它根据指定比较器进行排序。

 

l Comparator<T>接口

强行对某个对象collection进行整体排序的比较函数。

 

方法:

compare(Object o1 , Object o2)

如果该第一个对象<,=或>第二个对象,则返回负数,零和正数,通常使用 -11

 

需求:

使用比较器让TreeSet对象自身具有比较功能。

思路

使用构造方法TreeSet(Comparator<? super E> comparator),使集合可以去比较添加进来的对象。

创造构造器类,其实现Comparator接口。重写compare(Object o1, Object o2)方法

package com.lxh.collection;
import java.util.*;
public class TreeSetDemo2 {

	public static void main(String[] args) {
		TreeSet ts = new TreeSet(new Compare());
		
		ts.add(new Person("001",23));
		ts.add(new Person("002",22));
		ts.add(new Person("004",24));
		ts.add(new Person("003",23));
		ts.add(new Person("003",29));
		
		Iterator it = ts.iterator();
		
		while(it.hasNext()) {
			Person p = (Person)it.next();
			System.out.println(p.get());
		}
	}

}

/**
 * 比较器
 * */
class Compare implements Comparator {
	Person p1 = null;
	Person p2 = null;
	public int compare(Object o1, Object o2) {
		Person p1 = (Person)o1;
		Person p2 = (Person)o2;
		
		int num = p1.getName().compareTo(p2.getName());
		if(num == 0) {
			/*
			if(p1.getAge() < p2.getAge())
				return -1;
			if(p2.getAge() > p2.getAge())
				return 1;
			return 0;
			*/
			// 使用Integer类封装int类型的正数。
			return (new Integer(p1.getAge()).compareTo(new Integer(p2.getAge())));
		}
		return num;
			
		
	}
	
}
public class Person /*implements Comparable*/ {
	private String name;
	private int age;
	public Person(String name,int age) {
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}
	
	public int getAge() {
		return age;
	}
	
	public String get() {
		return name + "::" + age;
	}
}

练习:

按照字符串的长度进行比较排序。

package com.lxh.collection;
import java.util.*;
public class TreeSetCompareString {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		TreeSet ts = new TreeSet(new StringComparator());
		ts.add("sdfsd");
		ts.add("s");
		ts.add("fasefwefas");
		ts.add("sdfsa");
		ts.add("sdfsa");
		
		Iterator it = ts.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}

}

class StringComparator implements Comparator {
	String s1 = null;
	String s2 = null;
	public int compare(Object o1,Object o2) {
		s1 = (String)o1;
		s2 = (String)o2;
		
//		if(s1.length() < s2.length())
//			return -1;
//		if(s1.length() == s2.length())
//			return s1.compareTo(s2);
//		return 1;
		
		int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
		if(num == 0) 
			return s1.compareTo(s2);
		return num;
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值