(java)Set (哈希表)+(HashSet SortedSet)

HashSet的底层实际上是一个HashMap,而HashMap的数据结构为哈希表/散列表
所以先讲解什么是哈希表/散列表?

哈希表是:数组和单向链表的结合

哈希表本质是一个数组,只不过这数组中每个元素又是单向链表

在这里插入图片描述

Set集合:HashSet
1.HashSet底层实际上是一个HasMap,HashMap底层采用了哈希表数据结构。
2.哈希表又叫散列表,哈希表是一个数组,这个数组中每一个元素是一个单向链表。每个单向链表都有一个独一无的hash值,代表数组的下标。在某个单向链表中的每一个节点上的hash值是相等的。hash值实际上是key调用hashCode方法,再通过“hash function”转换成的值、

3.如何向哈希表中添加元素:
	先调用被存储的key的hashCode方法,经过某个算法得出hash值,如果在这个哈希表中不存在这个hash值,则直接加入元素。如果该hash值已经存在,继续调用key之间的equals方法,如果equals方法返回false,则将该元素添加。如果equals方法返回true,则放弃添加该元素

4.HashSet其实是HashMap中的key部分。HashSet有什么特点,和HashMap中的key应该具有向同的特点

5.(HashSet的底层实际上是HashMap)HashMap和HashSet 始化容量为16,加载因子为0.75。加载因子(当数组内元素达到总容量的75%时开始扩容)
import java.util.*;
public class HashSetTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Set n1 = new HashSet();	
		
		n1.add(1);
		n1.add(1);
		
		n1.add(new Object());
		n1.add(100);
		n1.add(100);
		n1.add(85);
		Iterator it = n1.iterator();
		
		while(it.hasNext()) 
		{
			System.out.println(it.next());
			//输出结果为1 100 85 java.lang.Object@34c45dca   
			//可以看到Set集合的特点,无序不可重复
		}
		
		
	}

}
关于往Set集合中存储的元素,该元素的hasCode和equals方法
HashMap中有一个put方法,put(key,value)  key是无序不可重复的,一下程序的employee相当于是key。
注意:在没有重写emplyee内部的hashcode方法之前,如果新建了两个员工对象,两个对象内部存储的姓名以及编号即使相同,也都会添加到Set集合内部(因为两个不同的对象在没有重写hashcode方法之前,得到的hash值是不同的,所以会存储进去)
再注意:当hashcode得出的值相同时,就通过equals比较内容,内部不同再添加。
以上可得需要比对两个指标,来判断是否能加入,hashcode返回的值不同,加在数组的不同位置,hashcode返回的值相同,但是equals比对后不同的,加载同一hashcode位置上单向链表下,两者都不同,则不添加
得出结论:需要重写employee内部的hashcode方法
import java.util.*;
public class HashSetTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		//创建集合
		Set s = new HashSet();	
		
		//创建几个员工实例
		Employee e1 = new Employee( "1001","jack");
		Employee e2 = new Employee("1002","jack");
		Employee e3 = new Employee("2001","bob");
		Employee e4 = new Employee("3001","tom");
		
		//添加元素
		s.add(e1);
		s.add(e2);
		s.add(e3);
		s.add(e4);
		
		//查看元素个数
		System.out.println(s.size());
		
		System.out.println("1001".hashCode());
		System.out.println("1100".hashCode());
		

	}

}




//根据业务逻辑得知:该公司员工编号是:1000 - 9999
//写一个员工类
class Employee{
	String no;
	String name;
	
	Employee(String no,String name){
		this.no = no;
		this.name = name;
	}
	public boolean equals(Object e) {
	if(this == e) {
		return true;
	}else if(((Employee)e).name.equals(name)&&((Employee)e).no.equals(no))
	{	
		return true;
	}
		return false;
	}
	//重写hashcode方法,这里有疑问,就是没有能够实现重写hashcode后使得1000-1999分在数组的同一位置下
	public int hashCode() {
		
		return no.hashCode();
	}
}

java.util.Set;
java.util.SortedSet;)
java.util.TreeSet;

SortedSet:1.是个接口,TreeSet实现了这个接口

特点:无序不可重复,但是存进去的元素可以按照元素大小顺序自动排列(从小到大)

mport java.util.*;
public class SortrdSetTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Set s = new TreeSet();
		s.add(117);
		s.add(12);
		s.add(10);
		s.add(12);
		s.add(100);
		s.add(15);
		s.add(9);
		
		Iterator it = s.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
			//输出结果为9 10 12 15 100 117
			//可以看到他的特点无序不重复,并能够按照从小到大排列
		}
		//日期也会按照从小到大的顺序排列
		//同时注意下日期的使用,回顾之前的知识
		//日期Date
		String st1 = "2008-08-08";
		String st2 = "2009-09-09";
		String st3 = "2005-05-05";
		String st4 = "2013-04-08";
		
		SimpleDateFormat f1 = new SimpleDateFormat("yyyy-MM-dd");
		
		Date t1 = f1.parse(st1);
		Date t2 = f1.parse(st2);
		Date t3 = f1.parse(st3);
		Date t4 = f1.parse(st4);
		
		Set time = new TreeSet();
		
		time.add(t1);
		time.add(t2);
		time.add(t3);
		time.add(t4);
		
		Iterator it2 = time.iterator();
		while(it2.hasNext()) {
			System.out.println(f1.format(it2.next()));
		}
		
	}

}

SortedSet是如何实现排序的,(总结,是通过comparable的返回值进行排序的,程序员只需要重写comparable方法,然后SortedSet会通过comparable的返回值来进行排序,升序和倒序由自己返回值来决定,具体示例看程序)
(问题:具体底层拿到返回值后如何排序,是通过二叉树实现,后面再深入研究)
如果不在自己新创建的类里实现comparable这个接口,是无法在SortedSet集合里面进行比较的
故要自己创建的类里实现comparable接口,一个接口要实现,就要实现里面所有的方法

import java.util.*;
public class SortedTest2 {

	public static void main(String[] args) {
		SortedSet n1 = new TreeSet();
		User u1 = new User(10);
		User u2 = new User(12);
		User u3 = new User(9);
		User u4 = new User(15);
		User u5 = new User(10);
		User u6 = new User(21);
		
		n1.add(u1);
		n1.add(u2);
		n1.add(u3);
		n1.add(u4);
		n1.add(u5);		
		n1.add(u6);
		
		Iterator it = n1.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		

	}
	
}
class User{
	
	int age;
	
	User(int age){
		this.age = age;
	}
	//重写toStrin方法
	public String toString() {
		return "use is age:"+this.age+"";
	}
	//以年龄为标准来进行排序,以下程序是以升序排除了,按照返回值比自身age小返回一个负数
	public int compareTo(Object o) {
	//这行代码是模仿,Integer类型写的,以年龄为排序的标准
	 return (this.age<((User)o).age)? -1:(this.age==((User)o).age)? 0:1;
 }
}

通过创建比较器,来完成比较
还有匿名内部类的使用下·

//让SortedSet集合排序的另外一种方式,构造比较器comparator
import java.util.*;
public class SortedTest3 {

	public static void main(String[] args) {


		//创建TreeSet,在创建的时候就把比较器传进去
		SortedSet s1 = new TreeSet(new SortedComparator());

		//还可以通过匿名内部类的方法,匿名内部类很久没用过了,顺便回忆
		//写了匿名内部类,不能重复使用,只能使用在创建的S1对象内部
		SortedSet s1 = new TreeSet(new Comparator() {
			public int compare(Object o1, Object o2) {

				return (((User) o1).age < ((User) o2).age) ? -1 : (((User) o1).age == ((User) o2).age) ? 0 : 1;

			}
		});
		User u1 = new User(10);
		User u2 = new User(7);
		User u3 = new User(16);
		User u4 = new User(5);
		
		s1.add(u1);
		s1.add(u2);
		s1.add(u3);
		s1.add(u4);
		
		Iterator it = s1.iterator();
		
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		
		
	}

}
class User {
	int age;
	
	User(int age){
		this.age = age;
	}
}
class SortedComparator implements Comparator{


	
	public int compare(Object o1, Object o2) {
		
		return (((User)o1).age<((User)o2).age)?-1:(((User)o1).age==((User)o2).age)?0:1;
		
	}
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值