文章目录
- Set接口
- 实现类之一:HashSet
- H a s h S e t 具 有 以 下 特 点 : \textcolor{Red}{HashSet具有以下特点:} HashSet具有以下特点:
- H a s h S e t 集 合 判 断 两 个 元 素 相 等 的 标 准 : \textcolor{Red}{HashSet集合判断两个元素相等的标准:} HashSet集合判断两个元素相等的标准:两个对象通过 hashCode()方法比较相等,并且两个对象的equals()方法返回值也相等。
- 对于存放在Set容器中的对象, 对 应 的 类 一 定 要 重 写 e q u a l s ( ) 和 h a s h C o d e ( O b j e c t o b j ) 方 法 , 以 实 现 对 象 相 等 规 则 。 即 : “ 相 等 的 对 象 必 须 具 有 相 等 的 散 列 码 ” 。 \textcolor{Red}{对应的类一定要重写equals()和hashCode(Objectobj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。} 对应的类一定要重写equals()和hashCode(Objectobj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。
Set接口
存储无序、不可重复的数据
以Hashset为例说明
- 无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定
- 不可重复性:保证添加的元素按照equals()判断时,不饿能返回true.即:相同元素只能添加一个。
- 向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置),判断此位置上是否以及有元素。如果此位置上没有元素,则元素a添加成功。如果此位置上有其他元素b(或以链表形式存在多个元素),则比较元素a与元素b的hash值:如果hash值不相同,则元素a添加成功。如果hash值相同,进而调用元素a的equals()方法;equals()返回true,元素a添加失败。否则,元素a添加成功。
TreeSet是 SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。
TreeSet底层(数组+链表)使用 红 黑 树 \textcolor{Red}{红黑树} 红黑树结构存储数据
- 新增的方法如下:(了解)
- C o m p a r a t o r \textcolor{Red}{Comparator} Comparator c o m p a r a t o r ( ) \textcolor{Red}{comparator()} comparator()
- O b j e c t \textcolor{Red}{Object} Object f i r s t ( ) \textcolor{Red}{first()} first()
- O b j e c t \textcolor{Red}{Object} Object l a s t ( ) \textcolor{Red}{last()} last()
- O b j e c t \textcolor{Red}{Object} Object l o w e r ( O b j e c t \textcolor{Red}{lower(Object} lower(Object e ) \textcolor{Red}{e)} e)
- O b j e c t \textcolor{Red}{Object} Object h i g h e r ( O b j e c t \textcolor{Red}{higher(Object} higher(Object e ) \textcolor{Red}{e)} e)
- S o r t e d S e t \textcolor{Red}{SortedSet} SortedSet s u b S e t ( f r o m E l e m e n t , t o E l e m e n t ) \textcolor{Red}{subSet(fromElement, toElement)} subSet(fromElement,toElement)
- S o r t e d S e t \textcolor{Red}{SortedSet} SortedSet h e a d S e t ( t o E l e m e n t ) \textcolor{Red}{headSet(toElement)} headSet(toElement)
- S o r t e d S e t \textcolor{Red}{SortedSet} SortedSet t a i l S e t ( f r o m E l e m e n t ) \textcolor{Red}{tailSet(fromElement)} tailSet(fromElement)
- TreeSet两种排序方法: 自 然 排 序 \textcolor{Red}{自然排序} 自然排序和 定 制 排 序 \textcolor{Red}{定制排序} 定制排序。默认情况下,TreeSet采用自然排序。
实现类之一:HashSet
HashSet是 Set接口的典型实现,大多数时候使用Set集合时都使用这个实现类。
HashSet按 Hash 算法来存储集合中的元素,因此具有很好的存取、查找、删除性能。
H a s h S e t 具 有 以 下 特 点 : \textcolor{Red}{HashSet具有以下特点:} HashSet具有以下特点:
- 不能保证元素的排列顺序
- HashSet不是线程安全的
- 集合元素可以是 n u l l \textcolor{Red}{null} null
H a s h S e t 集 合 判 断 两 个 元 素 相 等 的 标 准 : \textcolor{Red}{HashSet集合判断两个元素相等的标准:} HashSet集合判断两个元素相等的标准:两个对象通过 hashCode()方法比较相等,并且两个对象的equals()方法返回值也相等。
对于存放在Set容器中的对象, 对 应 的 类 一 定 要 重 写 e q u a l s ( ) 和 h a s h C o d e ( O b j e c t o b j ) 方 法 , 以 实 现 对 象 相 等 规 则 。 即 : “ 相 等 的 对 象 必 须 具 有 相 等 的 散 列 码 ” 。 \textcolor{Red}{对应的类一定要重写equals()和hashCode(Objectobj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。} 对应的类一定要重写equals()和hashCode(Objectobj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。
import org.junit.Test;
import java.util.*;
/**
* @创建人 HeXin
* @所属包 SetTest
* @所属项目 JavaSenior
* @创建时间 2022/12/2 19:51
* @描述
*/
public class SetTest {
/**
*@BelongsProject: JavaSenior
*@BelongsPackage: SetTest
*@Author: HeXin
*@CreateTime: 2022/12/2 19:51
*@Description:
*@Version: 1.0
*
*/
@Test
public void test() {
Set set = new HashSet();
set.add(123);
set.add(456);
set.add(new String("WLM"));
set.add(new String("LIKE"));
set.add("WLM");
set.add(new People("WLM",19));
set.add(new People("WLM",20));
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
//LinkedHashSet的使用
//LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据前一个数据和后一个数据
//优点:对于频繁的遍历操作,LinkedHashSet效率高于HashSet
@Test
public void test1() {
Set set = new LinkedHashSet();
set.add(123);
set.add(456);
set.add(new String("WLM"));
set.add(new String("LIKE"));
set.add("WLM");
set.add(new People("WLM",19));
set.add(new People("WLM",20));
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
//1.向TreeSet中添加的数据,要求是像同类的对象。
//两种排序方式:自然排序 和 定制排序
//自然排序中,比较两个对象是否相同的标准为: compareTo( )返回0.不再是equals().
//定制排序中,比较两个对象是否相同的标准为: compare()返回0.不再是equals().
@Test
public void test2() {
//失败:不能添加不同类对象
// TreeSet set = new TreeSet();
// set.add(123);
// set.add(456);
// set.add(new String("WLM"));
// set.add(new String("LIKE"));
// set.add("WLM");
// set.add(new People("WLM",19));
// set.add(new People("WLM",20));
//举例一:
// TreeSet set = new TreeSet();
// set.add(new String("WLM"));
// set.add(new String("LIKE"));
// set.add("CXY");
// set.add("YJJ");
//举例二:
TreeSet set = new TreeSet();
set.add(new People("WLM",19));
set.add(new People("WLM",18));
set.add(new People("ZJN",18));
set.add(new People("YJJ",20));
set.add(new People("WRT",22));
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
@Test
public void test3() {
Comparator comparator = new Comparator() {
//按照年龄从小到大排序
@Override
public int compare(Object o1, Object o2) {
//Java17新特性
// if (o1 instanceof People p1 && o2 instanceof People p2) {
// return p1.getAge() - p2.getAge();
// } else {
// throw new UnsupportedOperationException("输入的数据类型不匹配");
// }
if(o1 instanceof People&&o2 instanceof People){
People p1 = (People)o1;
People p2 = (People)o2;
return Integer.compare(p1.getAge(),p2.getAge());
}else{
throw new RuntimeException("输入的数据类型不匹配!");
}
}
};
TreeSet set = new TreeSet(comparator);
set.add(new People("WLM",19));
set.add(new People("WLM",18));
set.add(new People("ZJN",18));
set.add(new People("YJJ",20));
set.add(new People("WRT",22));
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
class People implements Comparable{
private String name;
private int age;
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
People people = (People) o;
if (age != people.age) return false;
return Objects.equals(name, people.name);
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
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;
}
public People() {
}
public People(String name, int age) {
this.name = name;
this.age = age;
}
//按名字从小到大排列,年龄从小到大排列
@Override
public int compareTo(Object o) {
if(o instanceof People){
People people = (People) o;
int result = this.name.compareTo(people.name);
if(result != 0){
return result;
}else{
return Integer.compare(this.age, people.age);
}
}else{
throw new RuntimeException("输入的类型不匹配!");
}
}
}
注:此文章为本人学习过程中的随手笔记,样式较为简陋,若有雷同,请见谅!