09.集合框架(二)【Set】【HashSet】【TreeSet】

 

一.Set集合(接口)

1.概述

Set集合中元素不可以重复,无序。

Set集合中的方法和Collection一致。

Set集合只有一种取出方式:Iterator迭代器。

        2.Set字体系

        Set

                  |--HashSet:内部结构是哈希表,不同步,稳定,元素是唯一的。

        |--TreeSet:数据结构是二叉树,不同步,元素也是唯一的。

二.HashSet类

1.概述

HashSetSet集合接口的实现类。底层的数据结构是哈希表,操作此类时稳定。但

   线程不同步

哈希表里每一位元素都是唯一的,存储元素时,都会先调用哈希算法,根据元素自身的特点,存储到特定位置,查找时根据对应的角标查找就行。

       所以,哈希表查询快。

       弊端:元素不能重复。

   2.哈希表如何确定两个元素是否相同?

       如何确定元素是否相同,有两步判断:

   第一步:判断元素的哈希值,用hashCode()方法。如果哈希值地址上没有元素,那么就可以存储,如果哈希值地址上有元素,则进行第二步判断。

第二步:判断两个元素的内容,用equals()方法。如果内容不同,则可以顺延存储。如果

       内容相同,则不能存储。

例子:创建HashSet集合,存储自定义对象。

       具体为:往HashSet集合中存储个人信息(包括姓名,年龄)。

注意:1.自定义对象Person时,对象所属类继承的是Object,而Object类中的

       equals()方法比较的是地址的值是否相等,所以要重写equals()

        2.用迭代器迭代时应Object类型转为Person类。

Person类的实现

<span style="font-size:18px">public class Person implements Comparable {
	
	private String name;
	private int age;
	
	public Person() {
		super();	
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	@Override
	public int hashCode() {
		
		return name.hashCode()+age;
	}</span>
<span style="font-size:18px">	@Override
	public boolean equals(Object obj) {
		
		if(this == obj)//健壮性判断
			return true;
//		if(obj instanceof Person)
//			throw new ClassCastException("类型错误");
		Person p = (Person)obj;
		
		return this.name.equals(p.name) && this.age==p.age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String toString(){
		return name+":"+age;
	}
	
	@Override
	public int compareTo(Object o) {		
		Person p = (Person)o;
		
		//优化
		int temp = this.age-p.age;
		return temp==0?this.name.compareTo(p.name):temp;
		
		/*
		if(this.age>p.age)
			return 1;
		if(this.age<p.age)
			return -1;
		else{
			
			return this.name.compareTo(p.name);
		}
		*/	
	}
}
</span>

HashSetTest代码实现

<span style="font-size:18px">import java.util.HashSet;
import java.util.Iterator;

import cn.itcast.p.bean.Person;

public class HashSetTest {
	public static void main(String[] args) {
		HashSet hs = new HashSet();
		
		/*
		 * HashSet集合数据结构是哈希表,所以存储元素的时候,
		 * 使用元素的hashCode方法来确定位置,如果位置相同,再通过元素的equals方法来确定内容是否相同,
		 */
		hs.add(new Person("lisi",21));
		hs.add(new Person("zhangsan",28));
		hs.add(new Person("wangwu",27));
		hs.add(new Person("laoer",24));
		hs.add(new Person("zhangsan",28));
		
		/*
		 * Person 继承的是Object类,Object里的equals方法判断的是地址是否相同,
		 * 所以,存储元素时,不能保证元素的唯一性。
		 * 那么只能通过在Person里覆写hashCode方法和equals方法来判断。
		 */
		
		for(Iterator it = hs.iterator();it.hasNext();){
			Person p =(Person)it.next();
			System.out.println(p.getName()+"..."+p.getAge());
		}
	}

}
</span>


 

 

三.TreeSet类

TreeSet可以对Set集合中的元素进行指定排序,是不同步的。

1. TreeSet判断元素唯一性的方式:

根据比较方法的返回结果。返回0,则说明两元素相同。

2. TreeSet对元素进行排序的方式:

方式一:让元素具备比较功能。

元素需要实现comparable接口,覆盖compareTo()方法。如果不要按照对象中具备的自然顺序进行排序,如果对象中不具备自然

        顺序,那么就使用方式二。

方式二:让集合自身具备比较功能。

        定义一个类实现Comparator接口,覆盖compare方法,将该类对象作为参数

        传递给TreeSet集合的构造函数。

例子:对TreeSet中的字符串对象的长度进行排序。

自定义类实现Comparator接口

     

import java.util.Comparator;

public class ComparatorByLength implements Comparator{

	@Override
	public int compare(Object o1, Object o2) {
		
		String s1 = (String)o1;
		String s2 = (String)o2;
		
		int temp = s1.length()-s2.length();
		
		return temp==0?s1.compareTo(s2):temp;
	}

}


  

  将该对象作为餐宿传递给TreeSet的构造函数

  

import java.util.Iterator;
import java.util.TreeSet;

import cn.itcast.p5.comparator.ComparatorByLength;

/**
 * 对字符串进行长度排序
 */
public class TreeSetTest {

	public static void main(String[] args) {

		TreeSet ts = new TreeSet(new ComparatorByLength());
		
		ts.add("aaaaa");
		ts.add("zz");
		ts.add("nbaq");
		ts.add("cba");
		ts.add("abc");
		
		Iterator it = ts.iterator();
		
		while(it.hasNext()){
			System.out.println(it.next());
		}
		
	}

}


 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值