Java中的Set

1.Set集合概述

Set是一个接口,与List集合类似,都需要通过实现类来对其进行操作。Set集合的特点如下。

a.不包含重复的元素。

b.没有带索引的方法,不能使用普通for循环遍历。

package Demo1;


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

/**
 * @Description: TODO Set集合的基本应用
 */
public class Test1 {
    public static void main(String[] args) {
        // HashSet 不保证集合的迭代顺序,但是不重复
        Set<String> set = new HashSet<>();

        set.add("黄固");
        set.add("欧阳锋");
        set.add("段智兴");
        set.add("洪七公");

        set.add("欧阳锋");   //重复的元素添加不进去
        //Set集合的读写顺序不一定一致
        System.out.println(set);

    }
}

2.Set集合常见方法说明

方法解释
boolean add(E e)
添加元素,但重复元素不会被添加成功
void clear()
清空集合
boolean contains(Object o)
判断 o 是否在集合中
Iterator<E> iterator()
返回迭代器
boolean remove(Object o)
删除集合中的 o
int size()
返回 set 中元素的个数
boolean isEmpty()
检测 set 是否为空,空返回 true ,否则返回 false
Object[] toArray()
set 中的元素转换为数组返回
boolean containsAll(Collection<?> c)
集合 c 中的元素是否在 set 中全部存在,是返回 true ,否则返回
false
boolean addAll(Collection<? extends E> c)
将集合 c 中的元素添加到 set 中,可以达到去重的效果

 TreeSet的使用案例:

package Demo6;

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class TestSet {
    public static void main(String[] args) {
        Set<String> s = new TreeSet<>();
        // add(key): 如果key不存在,则插入,返回ture
        // 如果key存在,返回false
        boolean isIn = s.add("apple");
        s.add("orange");
        s.add("peach");
        s.add("banana");
        System.out.println(s.size());
        System.out.println(s);


        isIn = s.add("apple");

        // add(key): key如果是空,抛出空指针异常
        //s.add(null);

        // contains(key): 如果key存在,返回true,否则返回false
        System.out.println(s.contains("apple"));
        System.out.println(s.contains("watermelen"));


        // remove(key): key存在,删除成功返回true
        // key不存在,删除失败返回false
        // key为空,抛出空指针异常
        s.remove("apple");
        System.out.println(s);
        s.remove("watermelen");
        System.out.println(s);


        Iterator<String> it = s.iterator();
        while(it.hasNext()){
            System.out.print(it.next() + " ");
        }
        System.out.println();
    }
}

 

 3.Hash值

哈希值:是JDK根据对象的地址或者字符串或者数值计算出来的int类型的数值。 Object对象中就有一个方法可以获取对象的Hash值:public native int hashCode()。

对象的Hash值特点如下:

a.同一个对象多次调用hashCode()方法,得到的返回值是相同的。

b.默认情况下,不同对象的Hash值是不同的,但是可以通过重写hashCode()方法实现不同对象的Hash值相同。

通过hashCode方法查看Hash值:

package Demo1;

/**
 * @Description: TODO  哈希值
 */
public class Test2 {
    public static void main(String[] args) {
        String str = new String("我是一个字符串");
        System.out.println(str.hashCode());
        System.out.println("我是一个字符串".hashCode());
        System.out.println("我是一个字符串".hashCode());
        System.out.println("================================");
        System.out.println("我也是一个字符串".hashCode());
        System.out.println("================================");
        System.out.println(new Object().hashCode());
        System.out.println(new Object().hashCode());
        System.out.println(new Object().hashCode());

    }
}

不同对象也可能具有相同的Hash值: 

package Demo1;

import java.util.HashSet;

public class Test3 {
    public static void main(String[] args) {
        System.out.println("轷龚".hashCode());
        System.out.println("辂鹅".hashCode());
        System.out.println("输鰶".hashCode());
        System.out.println("辎鳑".hashCode());
        System.out.println("辇鶪".hashCode());
        System.out.println("辌鴏".hashCode());

        HashSet<String> str = new HashSet<>();
        str.add("轷龚");
        str.add("辇鶪");

        //Hash值不同的两个对象肯定不是同一个对象
        //但是即使Hash值相同,也不能确定一定是同一个对象
        //不同的对象也可能具有相同的Hash值
    }
}

4.哈希表

通过数组 + 链表的方式实现

构造方法数组16个元素,哈希值 % 16作为头节点位置选择

5.HashSet

HashSet集合是Set接口的实现类,其特点如下。

a.底层数据结构是Hash表。

b.对集合的迭代顺序不做任何保证,也就是说,不能保证存储和读取的顺序一致。

c.没有带索引的方法,也就是说,不能使用普通for循环对其进行遍历。

d.由于是Set集合,所以不存在重复的元素。

HashSet的去重原理是:先对比hashCode,如果相同,则再对比equals内容,这两个方法经常需要在子类中进行重写。 

package Demo2;

import java.util.HashSet;
import java.util.Random;
import java.util.TreeSet;

/**
 * @Description: TODO  双色球Set版
 */
public class Test1 {
    public static void main(String[] args) {
        Random ran = new Random();
        int blueBall = ran.nextInt(16) + 1;
        //HashSet<Integer> redBalls = new HashSet<>();
        TreeSet<Integer> redBalls = new TreeSet<>();  // 有序的Set集合,逻辑顺序
        while(redBalls.size() < 6) {
            redBalls.add(ran.nextInt(33) + 1);
        }
        System.out.println("红球:" + redBalls + " | 蓝球:[" + blueBall + "]");

    }
}

 

package Demo3;

import java.util.Objects;

public class Student {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

package Demo3;

import java.util.HashSet;

/**
 * @Description: TODO Set 集合存储学生类对象如何去重
 */
public class Test {
    public static void main(String[] args) {
        HashSet<Student> stuSet = new HashSet<>();

        stuSet.add(new Student("Andy",19));
        stuSet.add(new Student("Lucy",18));
        stuSet.add(new Student("Jack",17));
        stuSet.add(new Student("Andy",19));

        for (Student stu : stuSet) {
            System.out.println(stu);
        }
    }
}

6.LinkedHashSet 

LinkedHashSet集合是Hash表和链表实现的Set接口,其特点如下。

a.具有可预测的迭代顺序。

b.通过链表保证元素有序,也就是说,元素的存储和读取顺序是一致的。

c.通过Hash表保证元素的唯一性,也就是说,没有重复的元素。

package Demo4;

import java.util.LinkedHashSet;

/**
 * @Description: TODO LinkedHashSet 的特点 - 读写有序
 */
public class Test1 {
    public static void main(String[] args) {
        LinkedHashSet<String> set = new LinkedHashSet<>();

        set.add("黄固");
        set.add("欧阳锋");
        set.add("段智兴");
        set.add("洪七公");
        set.add("王重阳");

        System.out.println(set);
        for (String str : set) {
            System.out.println(str);
        }
    }
}

 

7.TreeSet 

TreeSet集合是Set接口中的一个实现类,其特点如下。

a.元素有序,这里的“序”不是指存储和读取的顺序,而是指按照一定的规则进行排序,具体排序方式取决于实例化对象时的构造方法。

        TreeSet():根据元素的自然顺序进行排序。

        TreeSet(Comparator comparator):根据指定的比较器进行排序。

b.没有带索引的方法,不能使用普通for循环进行遍历。

c.由于是Set集合,所以不存在重复的元素。

package Demo5;

import java.util.TreeSet;

/**
 * @Description:  TODO TreeSet的基本用法
 */
public class Test1 {
    public static void main(String[] args) {
        TreeSet<Integer> ts = new TreeSet<>();

        ts.add(5);
        ts.add(2);
        ts.add(1);
        ts.add(3);
        ts.add(6);
        ts.add(4);
        ts.add(8);
        ts.add(7);

        System.out.println(ts);
    }
}

使用自定义排序规则(接口实现):

package Demo5;

/**
 * @Description:  TODO  学生类
 */
public class Student implements Comparable<Student>{
    private String name;
    private int age;

    public Student(String name, int age) {
        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 String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }


    @Override
    public int compareTo(Student o) {
        //return 0;       //0表示相等,后面传递进来的o对象就存储不进去
        //return 9527;    //大于0,表示o对象比当前的对象大,放到后面
        //return -1314;     //小于0,表示o对象比当前的对象小,放到前面
        //根据年龄进行排序,如果年龄相同,就根据姓名字符串进行排序
        int res = this.getAge() - o.getAge();
        return 0 == res ? this.getName().compareTo(o.getName()) : res;

    }
}

package Demo5;

import java.util.TreeSet;

/**
 * @Description: TODO  Student类对象存储到TreeSet集合当中
 */
public class Test2 {
    public static void main(String[] args) {
        TreeSet<Student> stuSet = new TreeSet<>();

        stuSet.add(new Student("Andy",29));
        stuSet.add(new Student("Jack",39));
        stuSet.add(new Student("Lily",19));
        stuSet.add(new Student("Tom",49));
        stuSet.add(new Student("Lucy",19));

        for (Student stu : stuSet) {
            System.out.println(stu);
        }


    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaSet是一种集合类型,它不允许重复元素,并且没有固定的顺序。常见的Set实现类有HashSet、LinkedHashSet和TreeSet。下面是Set的用法示例: 1. 创建Set对象 可以使用以下语法创建Set对象: ```java Set<T> set = new HashSet<>(); // 创建HashSet对象 Set<T> set = new LinkedHashSet<>(); // 创建LinkedHashSet对象 Set<T> set = new TreeSet<>(); // 创建TreeSet对象 ``` 其,T表示元素的类型。 2. 添加元素 可以使用add()方法向Set添加元素: ```java set.add(element); // 将元素添加到Set,如果Set已经存在该元素,add()方法不会执行任何操作 ``` 3. 删除元素 可以使用remove()方法从Set删除元素: ```java set.remove(element); // 从Set删除指定元素,如果Set不存在该元素,remove()方法不会执行任何操作 ``` 4. 判断元素是否存在 可以使用contains()方法判断Set是否存在指定元素: ```java set.contains(element); // 如果Set存在该元素,返回true;否则返回false ``` 5. 遍历元素 可以使用foreach循环或者迭代器遍历Set的元素: ```java for (T element : set) { // 对元素进行操作 } Iterator<T> iterator = set.iterator(); while (iterator.hasNext()) { T element = iterator.next(); // 对元素进行操作 } ``` 6. 获取元素个数 可以使用size()方法获取Set元素的个数: ```java set.size(); // 返回Set元素的个数 ``` 7. 清空Set 可以使用clear()方法清空Set的所有元素: ```java set.clear(); // 清空Set的所有元素 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值