java--基础--9.5--集合--set

文章详细介绍了Java集合框架中的Set接口,包括HashSet、LinkedHashSet和TreeSet的特性和底层实现。HashSet基于哈希表实现,保证元素唯一性;LinkedHashSet在哈希表基础上增加链表,保持插入顺序;TreeSet使用二叉树结构,支持排序,元素可自定义排序或使用Comparator.
摘要由CSDN通过智能技术生成

java–基础–9.5–集合–set


1、Collection 接口

Collection 接口
	|--List 接口,继承Collection 
		|--ArrayList                           --- implement  List 
		|--Vector                              --- implement  List 
		|--LinkedList                          --- implement  List 
	|--Set 接口,继承Collection 
		|--HashSet                             --- implement  Set 
		   |--linkedHashSet 继承HashSet 
		|--TreeSet                             --- implement  Set 


2、set集合

  • 无序
  • 唯一

2.1、子类

  • HashSet
  • LinkedHashSet
  • TreeSet

3、HashSet

  • 底层数据结构是哈希表(是一个元素为链表的数组)
  • 哈希表底层依赖两个方法:hashCode()和equals(),该方法与添加的对象有关,所以添加的对象需要重写hashCode()和equals()

3.1、构造方法

在这里插入图片描述

3.2、add方法的底层实现,可以说明为什么set的值是唯一,不重复的

//key 是add添加的对象
public V put(K key, V value) { //key=e=hello,world
	
		//看哈希表是否为空,如果空,就开辟空间
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        
        //判断对象是否为null
        if (key == null)
            return putForNullKey(value);
        
        int hash = hash(key); //和对象的hashCode()方法相关
        
        //在哈希表中查找hash值
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        	//table[i] 获取哈希表中的对象
            Object k;
            //比较add添加的对象与哈希表的对象
            //如果哈希值相同,且(两者地址值相同或者内容相同),就不添加元素,否则就添加元素
            //比较地址值或者走equals()
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;//跳出方法,不走下面的代码
            }
        }

        modCount++;
        addEntry(hash, key, value, i); //把元素添加
        return null;
    }

4、LinkedHashSet:

底层数据结构由哈希表和链表组成。
哈希表保证元素的唯一性链表保证元素有素。(存储和取出是一致)

在这里插入图片描述

5、、TreeSet

  • 能够对元素按照某种规则进行排序。
  • 排序和唯一
  • 底层数据结构是二叉树

5.1、构造方法

在这里插入图片描述

5.2、自然排序

让元素所属的类实现Comparable接口,基本类型都有实现该接口,自定义类需要自己实现该接口。

5.2.1、基本类型的自然排序

// 创建集合对象
// 自然顺序进行排序
TreeSet<Integer> ts = new TreeSet<Integer>();
ts.add(5);
ts.add(4);
ts.add(2);
ts.add(3);
ts.add(1);
// 遍历
for (Integer i : ts) {
	System.out.println(i);
}
 
输出:
1
2
3
4
5

5.2.2、自定义类的自然排序

自定义类
package cn;

/*
 * 如果一个类的元素要想能够进行自然排序,就必须实现自然排序接口
 */
public class Student implements Comparable<Student> {
	private String name;
	private int age;

	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = 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;
	}

	@Override
	public int compareTo(Student s) {
		//按照年龄排序
		int num1= this.getAge()-s.getAge();
		如果年龄相同,按名字排序
		int num2=num1==0?(this.getName().compareTo(s.getName())):num1;
		return num2;
	}
}

自定义类的自然排序测试
	// 创建集合对象
		TreeSet<Student> ts2 = new TreeSet<Student>();
		// 创建元素
		Student s1 = new Student("abc", 27);
		Student s2 = new Student("abc", 29);
		Student s3 = new Student("bcd", 23);
		Student s4 = new Student("efd", 27);
		Student s5 = new Student("cfd", 22);
		Student s6 = new Student("cdf", 40);
		Student s7 = new Student("bed", 22);
		// 添加元素
		ts2.add(s1);
		ts2.add(s2);
		ts2.add(s3);
		ts2.add(s4);
		ts2.add(s5);
		ts2.add(s6);
		ts2.add(s7);
		// 遍历
		for (Student s : ts2) {
			System.out.println(s.getName() + "---" + s.getAge());
		}
输出:
bed---22
cfd---22
bcd---23
abc---27
efd---27
abc---29
cdf---40

5.3、底层2叉数分析:

这里写图片描述

5.3.1、比较器排序

让TreeSet< T t>接收Comparator的实现类对象
举例:

new TreeSet< T t>(Comparator的实现类对象)
new TreeSet< T t>(new Comparator<T>(){  重写compare方法,定义规则})

案例
// 比较器进行排序
System.out.println("------------比较器进行排序--------------------");
TreeSet<Student> tComparator = new TreeSet<Student>(new Comparator<Student>() {
	@Override
	public int compare(Student s1, Student s2) {
		
		// 姓名排序
		int num = s1.getName().compareTo(s2.getName());
		// 年龄排序
		int num2=num==0 ? s1.getAge() - s2.getAge():num;
		return num2;
	}
});

// 添加元素
tComparator.add(s1);
tComparator.add(s2);
tComparator.add(s3);
tComparator.add(s4);
tComparator.add(s5);
tComparator.add(s6);
tComparator.add(s7);
// 遍历
for (Student s : tComparator) {
	System.out.println(s.getName() + "---" + s.getAge());
}
输出:
------------比较器进行排序1--------------------
abc---27
abc---29
bcd---23
bed---22
cdf---40
cfd---22
efd---27

5.3.2、底层2叉数分析:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值