Set接口

SetCollection子接口;

SetCollection基本上一样,一点除外:

Set无法记住添加的顺序,不允许包含重复的元素。

当试图添加两个相同元素进Set集合,添加操作失败,add()方法返回false

Set判断两个对象是否相等用equals,而不是使用==

也就是说两个对象equals比较返回trueSet集合是不会接受这个两个对象的。

常用子类:

HashSet:散列存放

TreeSet:有序存放

 >hashCode方法对于HashSet的作用

 HashSet类是Set接口最常用的实现类,采用hash算法存储数据,具有良好的存储和查找功能。

散列存储:不记录添加顺序;排列顺序时,顺序有可能发生变化;

线程不安全的,多个线程访问一个HashSet要使用同步代码;

HashSet集合元素值允许是null,但是最多只能有一个;//因为Set集合就不可以装重复的对象!

hash(翻译为哈希,或散列)算法的功能:

保证通过一个对象快速找到另一个对象;

其算法价值体现在速度,可以保证查询快速执行;

当从HashSet中访问元素时,HashSet先计算该元素的hashCode(也就是该对象的hashCode方法返回值),然后直接到该HashCode对应的位置取出该元素;

在这里对象的hashCode就好比是数组里的索引,但是不是索引;

>HashSet元素添加

 当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode,判断已经存储在集合中的对象的hashCode值是否与添加的对象的hashCode值一致:若不一致:直接添加进去;若一致,再进行equals方法比较,equals方法如果返回true,表明对象已经添加进去了,就不会再添加新的对象了,否则添加进去;

如果我们重写了equals方法,也要重写hashCode方法,反之亦然;

HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode方法返回值也相等。

如果需要某个类的对象保存到HashSet集合中,覆写该类的equals()hashCode()方法,应该尽量保证两个对象通过equals比较返回true,他们的hashCode返回也相等。

【重点提示】

很重要的一点:理解!往HashSet集合里面存入数据,要先后调用两个方法:hashCode方法和equals方法!!!

备注:使用eclipse添加这两个方法。

eg:

import java.util.HashSet;
import java.util.Set;

class PersonDemo{
	private String name;

	public PersonDemo(String name) {
		super();
		this.name = name;
	}

	@Override
	public String toString() {
		return "name= " + name ;
	}
	//没有覆写hashcode和equals方法前,显示三次(一样的)。覆写后,只剩下一个了!说明覆写后方法起作用了,重复的输入不进去!
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		PersonDemo other = (PersonDemo) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
}
public class Dem11 {

	public static void main(String[] args) {
        Set<PersonDemo> s = new HashSet<>();
		
		s.add(new PersonDemo("章泽天"));
		s.add(new PersonDemo("章泽天"));
		s.add(new PersonDemo("章泽天"));
		System.out.println(s);
		
	}

}

输出结果

[name= 章泽天]


>类 TreeSet<E>

TreeSetSortedSet接口唯一的实现,与HashSet相比额外的方法有:

Comparator comparator():返回当前Set使用的Comparator,若返回null,表示以自然顺序排序。

Object first() 返回此 set 中当前第一个(最低)元素。

Object last() 返回此 set 中当前最后一个(最高)元素。

SortedSet subSet(Object  fromElement, E toElement) 返回此 set 的部子集,其元素从 fromElement(包括)到 toElement(不包括)。

SortedSet headSet(Object  toElement)返回此 set 的部分子集,其元素严格小于 toElement

SortedSet tailSet(Object  fromElement) 返回此 set 的部分子集,其元素大于等于 fromElement

TreeSet的排序之自然排序

TreeSet会调用元素的compareTo(Object o)方法来比较元素之间的大小关系,然后将集合里的元素按升序排列.此时需要排序元素的类必须实现Compareble接口,并覆写其int compareTo(Object o)方法;

该方法用于比较对象,:obj1,compareTo(obj2),返回0,表示两个对象相等,若返回一个正整数,表示obj1大于obj2,若返回一个负整数,表示obj1小于obj2;

对于TreeSet集合而言,判断两个对象相等的标准是:

compareTo()方法比较返回 0;

//TreeSet可以自动进行排序!最简单的情况

import java.util.Set;
import java.util.TreeSet;

public class Demo13 {
	public static void main(String[] args) {
		
		Set<Integer> s = new TreeSet<Integer>();
		s.add(1);
		s.add(192);
		s.add(123);
		
		s.add(56);
		s.add(13);
		s.add(96);
		System.out.println(s);//[1, 13, 56, 96, 123, 192]
	}
}

稍复杂点的

package july7;
//TreeSet的自然排序,升序

import java.util.Set;
import java.util.TreeSet;

class Student implements Comparable{//必须实现接口
	private Integer age;

	public Student(Integer age) {
		super();
		this.age = age;
	}

	@Override
	public int compareTo(Object o) {//比较的规则,运用泛型可以消除强转!
		if(o instanceof Student){
			Student s = (Student)o;
			return this.age.compareTo(s.age);
		}
		return 0;
	}

	@Override
	public String toString() {
		return age+"" ;
	}
}

public class Demo14 {
	public static void main(String[] args) {
		
		Set<Student> s = new TreeSet();
		s.add(new Student(140));
		s.add(new Student(15));
		s.add(new Student(11));
		s.add(new Student(63));
		s.add(new Student(96));
		System.out.println(s);//[11, 15, 63, 96, 140]
	}
}

TreeSet的排序之定制排序

TreeSet的自然排序是根据元素的大小进行升序排序的,若想自己定制排序,比如降序排序,就可以使用Comparator接口了:

该接口包含int compare(Object o1,Object o2)方法,用于比较两个对象的大小,比较结果和compareTo方法一致;

要实现定制排序,需要在创建TreeSet集合对象时,提供一个一个Comparator对象,该对象里负责集合元素的排序逻辑;

TreeSet(Comparator comparator)

 Eg:

//定制排序的话,必须在创建TreeSet集合对象的时候提供一个Comparator方法

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

class Student1{
	private Integer age;
	
	public Student1(Integer age) {
		super();
		this.age = age;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return age + "";
	}
}

class MyComparator implements Comparator{
	
	@Override
	public int compare(Object o1, Object o2) {
		if(o1 instanceof Student1 & o2 instanceof Student1){
			Student1 s1 = (Student1)o1;
			Student1 s2 = (Student1)o2;
			if(s1.getAge() > s2.getAge()){
				return -1;
			}else if(s1.getAge() < s2.getAge()){
				return 1;
			}
		}
		return 0;
	}
}

public class Demo15 {
	public static void main(String[] args) {
		Set<Student1> s = new TreeSet(new MyComparator());
		/**
		 * 要实现定制排序,需要在创建TreeSet集合对象时,提供一个一个Comparator对象,
		 * 该对象里负责集合元素的排序逻辑;
		 */
		s.add(new Student1(140));
		s.add(new Student1(15));
		s.add(new Student1(11));
		s.add(new Student1(63));
		s.add(new Student1(96));
		
		System.out.println(s);
	}
}




猜你喜欢

转载自blog.csdn.net/wyf2017/article/details/80302390