Collection集合之Set集合


前言

牢记认Collection图谱

牢记集合图谱


一、Set集合是什么

Set集合是一种用于存储无序、不重复元素的集合。

二、Set集合特点

  1. 唯一性:Set集合中的元素都是唯一的,不允许出现重复。
  2. 无序性:Set集合不保证元素的顺序,即无法对元素进行排序。Set集合中元素的插入、删除和查找操作的时间复杂度都是O(1),
  3. Set集合不允许插入null元素。
  4. Set 中的元素是基于哈希表实现的,因此 Set 具有快速的查找和插入速度。

三、常见的实现类

1. HashSet集合

HashSet基于HashMap实现,底层采用HashMap来保存元素,注意:HashSet没有get()方法。(后面会介绍HashMap的使用及结构)

1.1 HashSet常用方法

1.1.1添加元素:可以使用add()方法向HashSet中添加元素
HashSet<String> hashSet = new HashSet<String>();
hashSet.add("apple");
hashSet.add("banana");
hashSet.add("orange");
1.1.2 移除元素:可以使用remove()方法获取HashSet中的元素
public class AppMain {

    public static void main(String[] args) {
        HashSet<String> hashSet = new HashSet<>();
        hashSet.add("apple");
        hashSet.add("banana");
        hashSet.add("orange");
        boolean banana = hashSet.remove("banana");
        System.out.printf("删除banana是否成功: %s%n删除之后hashSet的值为%s", banana, hashSet);
    }
}

删除banana是否成功: true
删除之后hashSet的值为[orange, apple]

1.1.3是否包含某个元素:使用contains()方法
public class AppMain {

    public static void main(String[] args) {
        HashSet<String> hashSet = new HashSet<>();
        hashSet.add("apple");
        hashSet.add("banana");
        hashSet.add("orange");
        boolean banana = hashSet.contains("banana");
        System.out.printf("hashSet是否包含banana:%s%n", banana);
    }
}

hashSet是否包含banana:true

1.1.4 遍历集合,两种方式:使用迭代器(Iterator)或for-each循环遍历
public class AppMain {

    public static void main(String[] args) {
        HashSet<String> hashSet = new HashSet<>();
        hashSet.add("apple");
        hashSet.add("banana");
        hashSet.add("orange");
        Iterator<String> iterator = hashSet.iterator();
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.printf("当前值为:%s%n", element);
        }
    }
}

当前值为:banana
当前值为:orange
当前值为:apple

public class AppMain {

    public static void main(String[] args) {
        HashSet<String> hashSet = new HashSet<>();
        hashSet.add("apple");
        hashSet.add("banana");
        hashSet.add("orange");
        for (String element : hashSet) {
            System.out.printf("当前值为:%s%n", element);
        }
    }
}

当前值为:banana
当前值为:orange
当前值为:apple

2.LinkedHashSet集合

  1. 它是HashSet的子类,继承了HashSet的无序性、不保证迭代顺序、不允许存储重复元素的特点。
  2. LinkedHashSet在内部通过链表维护了元素的插入顺序,可以保证取出的顺序和存入的顺序一致。

LinkedHashSet的使用方法和HashSet一直,这里提一点的是,当我们将LinkedHashSet或者HashSet转为stream流以后,我们就有了很多操作空间,下面只是单独举几例:

2.1 LinkedHashSet之Stream流操作

2.1.1 获取第一个值
public class AppMain {

    public static void main(String[] args) {
        LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();
        linkedHashSet.add("apple");
        linkedHashSet.add("banana");
        linkedHashSet.add("orange");
        Optional<String> first = linkedHashSet.stream().findFirst();
        System.out.println(first.get());
    }
}

apple

2.2.2 Stream流的过滤操作
public class AppMain {

    public static void main(String[] args) {
        LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();
        linkedHashSet.add("apple");
        linkedHashSet.add("banana");
        linkedHashSet.add("orange");
        linkedHashSet.add("");
        List<String> collect = linkedHashSet.stream().filter(item -> item.contains("an")).collect(Collectors.toList());
        System.out.println(collect);
    }
}

[banana, orange]

这些转为流操作的是java8的特性,有时间可以学习下,java8的stream流在我们常用开发中,虽然能简化很多代码,但是复杂的语句造成可读性变差,所以一般简便的用法值得使用,复杂的语句还是尽量少使用,以免增加后期维护成本

这里可以看看小码哥呀的文章:Java8新特性:Stream流

3 TreeSet

TreeSet 是一个基于红黑树(一种自平衡二叉查找树)实现的 Set 集合,它保证了集合中的元素是有序的。TreeSet 不仅可以存储基本数据类型的元素,而且可以存储对象,只要这个对象实现了 Comparable 接口或者在创建 TreeSet 的时候传入一个 Comparator 对象。

3.1 TreeSet特点

1.有序性:TreeSet 中的元素是有序的,根据元素的自然顺序或者创建 TreeSet 时传入的 Comparator 来确定顺序。
2.唯一性:TreeSet 中的元素必须是唯一的,不会允许重复的元素存在。
3.高效的查找、插入和删除操作:由于 TreeSet 是基于红黑树实现的,因此对于查找、插入和删除操作的时间复杂度可以达到 O(log n)。

TreeSet同样有add()方法remove()方法contains()方法,也是需要迭代器(Iterator)for-each循环遍历,这里说点其他的。

3.1.1 正序
public class AppMain {

    public static void main(String[] args) {
        TreeSet<String> treeSet = new TreeSet<>();
        treeSet.add("f");
        treeSet.add("k");
        treeSet.add("a");
        treeSet.add("t");
        treeSet.add("g");
        System.out.printf("默认会以按小到大的排序:%s", treeSet);
    }
}
3.1.2 倒序
public class AppMain {

    public static void main(String[] args) {
        TreeSet<String> treeSet = new TreeSet<>(Comparator.reverseOrder());
        treeSet.add("f");
        treeSet.add("k");
        treeSet.add("a");
        treeSet.add("t");
        treeSet.add("g");
        System.out.printf("默认会以按小到大的排序:%s", treeSet);
    }
}

默认会以按大到小的排序:[t, k, g, f, a]

3.1.3 自定义
    public static void main(String[] args) {
        TreeSet<Integer> treeSet = new TreeSet<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                // 与下面等价 return o1.compareTo(o2);
                return (o1 < o2) ? -1 : ((o1 == o2) ? 0 : 1);
            }
        });
        treeSet.add(2);
        treeSet.add(7);
        treeSet.add(3);
        treeSet.add(6);
        treeSet.add(4);
        System.out.printf("默认会以按小到大的排序:%s", treeSet);
    }
}

默认会以按小到大的排序:[2, 3, 4, 6, 7]


总结

以上就是Set的基本使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值