学习任务:

视频学习

Set集合介绍

测试HashSet集合

ArrayList是一个单列集合,HashMap和TreeMap都是双列集合,TreeMap是一个天然有序集合,适合排序场景但不适合大数量搜索场景,HashMap适合大数量搜索的场景,有没有一种数据结构是单列集合同时还具有TreeMap和Hashmap的优势呢?

Set集合是一种单列集合,它是Collection集合的子接口,Set接口无特有方法,它的使用方式和Collection集合基本一致。

它的特点是:

1、元素无序(不保证存储和取出的顺序一致)

2、元素唯一

3、元素无索引,不能使用for循环进行遍历

Set集合常用的实现类有HashSet、TreeSet,HashSet的底层是哈希表,TreeSet的底层是红黑树,所以,HashSet是单列集合同时具有了HashMap的优势,TreeSet也是单列集合同时具有了TreeMap的优势。

HashSet集合底层使用的是哈希表(请参考哈希表原理章节),它和HashMap的区别是Set是单列集合,Map是双列集合。

HashSet和ArrayList的区别:

1、HashSet是无序的而ArrayList是有序的。

2、HashSet可以保证元素唯一,ArrayList则无法保证元素的唯一性。

下边编写测试代码,将课程信息添加到HashSet中,测试它的添加、删除、遍历三个特性。

首先需要编写课程对象的hashCode和equals方法,因为哈希表是通过hashCode找到表中桶的位置,通过equals比较元素。

课程对象由课程id和课程名称决定唯一性,在重写hashCode和equals时要注意包括课程id和课程名称这两个因素,代码如下:

package com.pbteach.javase.oop.set.test1;

/**
 * 	课程类
 * @author 攀博课堂(www.pbteach.com)
 *
 */
public class PbCourse {
	
	//课程标识
	private long id;
	//课程名称
	private String courseName;
	//课程价格
	private int price;
	
	public PbCourse() {
		
	}
	public PbCourse(long id, String courseName, int price) {
		this.id = id;
		this.courseName = courseName;
		this.price = price;
	}
	//getter方法和setter方法
	//...
	
	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;
		PbCourse pbCourse = (PbCourse) o;
		return id == pbCourse.id &&
				Objects.equals(courseName, pbCourse.courseName);
	}

	@Override
	public int hashCode() {
		return Objects.hash(id, courseName);
	}
	@Override
	public String toString() {
		return "PbCourse [id=" + id + ", courseName=" + courseName + ", price=" + price + "]";
	}
}

测试代码如下:

package com.pbteach.javase.oop.set.test1;

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


/**
 * HashSet测试
 * @author 攀博课堂(www.pbteach.com)
 *
 */
public class HashSetTest1 {
	
	public static void main(String[] args) {
		Set<PbCourse> set = new HashSet<>();
		System.out.println("============添加元素=============");
		set.add(new PbCourse(100L, "攀博课堂-Java面向对象教程", 33));
		set.add(new PbCourse(101L, "攀博课堂-Spring全家桶教程", 44));
		set.add(new PbCourse(102L, "攀博课堂-SpringCloud微服务教程", 55));
		set.add(new PbCourse(103L, "攀博课堂-在线教育分布式项目教程", 66));
		set.add(new PbCourse(100L, "攀博课堂-Java面向对象教程", 11));
		//遍历链表
		foreash(set);
		System.out.println("============删除元素=============");
		//删除元素,索引号>0并且<size为合法
		set.remove(new PbCourse(103L, "攀博课堂-在线教育分布式项目教程", 66));
		//遍历链表
		foreash(set);
	}
	
	//遍历链表
	public static void foreash(Set<PbCourse> set) {
		set.forEach(System.out::println);
	}

}

通过测试发现:

1)添加元素

由于课程的id和课程的名称决定了唯一性,所以下边两门课程是同一门课程

set.add(new PbCourse(100L, "攀博课堂-Java面向对象教程", 33));
set.add(new PbCourse(100L, "攀博课堂-Java面向对象教程", 11));

当添加new PbCourse(100L, "攀博课堂-Java面向对象教程", 11)由于已经存在了此课程所以第二条记录无法存入Set集合。

2)删除元素

set.remove(new PbCourse(103L, "攀博课堂-在线教育分布式项目教程", 66));

根据元素的哈希值定位哈希表中的某个桶的位置,找到该元素,删除该元素。

输出:

============添加元素=============
PbCourse [id=101, courseName=攀博课堂-Spring全家桶教程, price=44]
PbCourse [id=103, courseName=攀博课堂-在线教育分布式项目教程, price=66]
PbCourse [id=100, courseName=攀博课堂-Java面向对象教程, price=33]
PbCourse [id=102, courseName=攀博课堂-SpringCloud微服务教程, price=55]
============删除元素=============
PbCourse [id=101, courseName=攀博课堂-Spring全家桶教程, price=44]
PbCourse [id=100, courseName=攀博课堂-Java面向对象教程, price=33]
PbCourse [id=102, courseName=攀博课堂-SpringCloud微服务教程, price=55]
提问-攀博课堂
我要提问 不会就问,有效沟通
关注公众号,加入微信群交流提问。 攀博课堂官方公众号
问答列表,查看本知识点所有问题