【Java高级特性】java学习之旅22-Set集合

HashSet

特征:

  1. 底层实现是HashMap的key
  2. 默认初始化的容量是16,默认的加载因子是0.75
  3. 当存储容量达到原容量的0.75时,扩容为原容量的2倍
  4. 不保证顺序、唯一、可以为null、无索引
  5. 查找较慢、插入删除较快
  6. 线程不同步的,多线程使用不安全,实现同步Set set = Collections.synchronizedSet(new HashSet(…))

常用的方法:

    add(E e)(要增加的元素)
    
    size()//获取集合的长度
    
    remove(Object o)(想要删除的元素)
    
    clear()//清空
    
    isEmpty()//判断是否为空
    
    contains(Object o)(判断包含的元素)
    
    iterator()//irerator遍历器
    

注意事项:

  1. HashSet按照按照什么逻辑排序

不保证顺序,存入的顺序和实际元素排列顺序无关,获取元素的先后顺序由Map中的hash()方法得到的混淆后的hash值决定。

  1. HashSet扩容是否有上限

HashMap限定了最大容量:MAXIMUM_CAPACITY = 1 << 30;

基本的创建以及赋值:

@Test
	public void test1() {
		HashSet<String> set1 = new HashSet<>();
		
		set1.add("王子玉");
		set1.add("吴青山");
		set1.add("钟雪");
		set1.add("任玉文");
		
		System.out.println(set1);
	}

遍历:

//迭代器遍历
Iterator<Integer> it = set2.iterator();
		while (it.hasNext()) {
			Integer i = (Integer) it.next();
			System.out.println(i);
			
		}
		
//foreach遍历
		for (Integer i : set2) {
			System.out.println(i);
		}

排序的依据:

@Test
	public void test3() {
		String key1 = "tom";
		int h1;
		//根据获得的值进行排序
		int i1 = (h1 = key1.hashCode()) ^ (h1 >>> 16);
		System.out.println(i1);
		
		String key2 = "hello";
		int h2;
		int i2 = (h2 = key2.hashCode()) ^ (h2 >>> 16);
		System.out.println(i2);
	}

LinkedHashSet

特征:

  1. 继承了HashSet类,底层实现HashMap,数据结构式链表
  2. 保证顺序、唯一的、可以为null
  3. 查找较慢、插入删除较快
  4. 线程不同步、多线程使用不安全,如果要实现线程同步的set
  5. Set set = Collections.synchroizedSet(new LinkedHashSet());

常用方法:

  • 可以参考HashSet

基本的创建语句和赋值:

public static void main(String[] args) {
		
		LinkedHashSet<String> set = new LinkedHashSet<>();
		
		set.add("吴青山");
		set.add("吴青山");
		set.add("王子玉");
		set.add("任玉文");
		set.add(null);
		
		System.out.println(set);
		
		System.out.println(set.remove("吴青山"));
		System.out.println(set);
		
	}

TreeSet

特征:

  1. 底层实现是TreeMap,数据结构是二叉树
  2. 不保证排序,但是可以自定义排序、唯一、可以为null
  3. 线程不同步、多线程使用不安全,如果要实现同步的set
  4. Sorted set = Collection.synchroizedSortedSet(new TreeSet(…))
  5. TreeSet集合只能存处可排序的对象(如果对象不可排序,会报错。)
  6. 如何实现排序
让元素具有排序的功能
   元素类实现Comparable接口,重写comparTo方法
   1. 在元素被添加进容器时,会调用compareTo方发和已存在的元素进行比较
   2. 如果返回的int值是正数,这个元素排在被比较的元素后面
   3. 如果返回的int值是负数,这个元素排在被比较的元素前面
   4. 如果返回的int值是0,表示无法比较,这个元素无法添加进容器里面
   
让容器具有排序的功能
    1. 创建一个比较器的类,实现Comparator,重写compara方法
    2. 使用有参构造创建TreeSet,参数就是比较器类的对象

创建和赋值:

@Test
	public void test1() {
		TreeSet<String> set = new TreeSet<>();
		
		set.add("王子玉");
		set.add("韩文龙");
		set.add("任玉文");
		
		System.out.println(set);
	}

创建有序的对象:

/**
 * 	学生对象
 */
 //实现Comparable接口
public class Student implements Comparable<Student> {
	
	private String name;
	private int age;
	private char sex;
	
	public Student() {
		super();
	}
	public Student(String name, int age, char sex) {
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
	
	//重写comparaTo方法,如果不重写,会报ClassCastException异常
	@Override
	public int compareTo(Student student) {
		
		if (this.sex != student.sex) {
			return this.sex == '女' ? -1 : 1;
		} else {
			return student.age - this.age;
		}
		
	}
	
}

由于业务场景设定我们需要创建不同的排序规则,所以使用容器实现更加合理

实现容器有序:

/**
 * 	教师类比较器
 */
 //实现Comparator接口
public class TeacherComparator implements Comparator<Teacher> {

//重写比较方法
	@Override
	public int compare(Teacher t1, Teacher t2) {
		return t2.getAge() - t1.getAge();
	}

}
@Test
	public void test3() {
		//创建比较器对象
		TeacherComparator tc = new TeacherComparator();
		//将比较器对象放入TreeSet对象的构造方法中
		TreeSet<Teacher> set = new TreeSet<>(tc);
		
		set.add(new Teacher("郭老师", 20, '女'));
		set.add(new Teacher("吴老师", 40, '男'));
		set.add(new Teacher("方老师", 16, '男'));
		
		System.out.println(set);
		
	}

由于Comparator接口是函数式的接口,所以可以用函数式的编程,不用额外创建一个比较器的类了

//函数式的编程
TreeSet<Girlfriend> set = new TreeSet<>((g1, g2) -> {
	if (g1.getFaceValue() != g2.getFaceValue()) {
		return g2.getFaceValue() - g1.getFaceValue();
	} else if (g1.getAge() != g2.getAge()) {
		return g1.getAge() - g2.getAge();
	} else {
		return 1;
	}
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JeffHan^_^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值