Java集合-Set

简介: Java集合-Set

f7265aca4d731cfd8f6164c87dca3bb5.jpg

Java集合-Set

Set(java.util.Set)接口,Set中存放的一组没有重复数据的集合,换句话说,同样的元素在Set中只能出现一次。Set接口是一个标准的JAVA接口,是Collection的子类,所以Set继承了Collection 的所有特性。可以向Set中添加任何java对象,如果Set不是类型化的,没有使用Java泛型,那么您甚至可以在同一个集合中混合不同类型(类)的对象,实际开发中很少这么做。


Set和List

Set和List非常相似,两个接口都代表着元素的集合,但是也有一些明显的不同。这些差异反映在Set和List接口包含的方法中 ,List中可以存在相同的元素,而Set中不允许有重复的元素。第二个不同是,Set中的元素是没有顺序的,List中的元素是有顺序的,List可以按顺序进行迭代。


Set的例子

下面是简单的Set例子:

package com.jenkov.collections;
import java.util.HashSet;
public class SetExample {
    public static void main(String[] args) {
        Set setA = new HashSet();
        String element = “123”;
        setA.add(element);
        System.out.println( setA.contains(element) );
    }
}


上面例子创建一个HashSet,HashSet是Set接口的一个实现,然后往里面添加一个String对象的元素,添加完后检查是否包含此元素。


Set的实现

作为Collection 子类型,Collection 接口中的所有方法在Set接口中也可用。既然Set是个接口,实例化时就要使用具体的实现类。可以选择下面几个Collections API中的实现:

  • java.util.EnumSet
  • java.util.HashSet
  • java.util.LinkedHashSet
  • java.util.TreeSet

在迭代集合时,每一个集合实现在元素的顺序以及在集合中插入和访问元素所需的时间(big O表示法)方面的行为都略有不同。HashSet由HashMap支持,它不保证迭代元素时元素的顺序。LinkedHashSet 和HashSet 是不一样的,LinkedHashSet 可以保证元素的顺序与添加元素时的顺序一样,重新插入LinkedHashSet中已存在的元素不会更改此顺序。TreeSet 同样可以保证元素的迭代顺序,但是元素的顺序是排序后的顺序,换句话就是顺序是调用了 Collections.sort() 后的顺序,这个顺序由它们的自然顺序决定(如果它们实现了Comparable的话),或者由一个特定的Comparator 实现来确定。Set在java.util.concurrent中也有一些实现类,这个以后会讲述。


创建Set

下面是创建 Set实例:

package com.jenkov.collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
public class SetExample {
    public static void main(String[] args) {
        Set setA = new HashSet();
        Set setB = new LinkedHashSet();
        Set setC = new TreeSet();
    }
}


Set的泛型

默认可以在Set中添加Object,Java5以后新加了泛型,可以限制Set集合中的数据类型,下面是例子:

Set<MyObject> set = new HashSet<MyObject>();
Set中只能添加MyObject实例对象,访问或者迭代时不需要强制类型转换:
for(MyObject anObject : set){
   //do someting to anObject...
}


Set添加元素

可以通过add()方法向Set中添加元素,这个方法继承自Collection.下面是例子:

Set<String> setA = new HashSet<>();
setA.add("element 1");
setA.add("element 2");
setA.add("element 3");

调用了三次add()方法。


迭代Set元素

有两种方法迭代Set:

  • 使用Iterator迭代 Set
  • 使用 for-each 循环

这两种方法下面都会讲述,迭代元素的顺序取决于使用的Set实现类。

使用Iterator迭代Set

使用Iterator迭代Set,首先需要从Set中获取Iterator,下面是例子:

Set<String> setA = new HashSet<>();
setA.add("element 1");
setA.add("element 2");
setA.add("element 3");
Iterator<String> iterator = set.iterator();
while(iterator.hasNext(){
  String element = iterator.next();
}

使用For-Each循环迭代Set

第二种方式是使用for-each循环迭代Set,下面是代码:

Set set = new HashSet();
for(Object object : set) {
    String element = (String) object;
}

Set接口实现了Iterable接口,所以Set可以使用for-each循环迭代,如果Set使用了泛型,那么迭代循环内部可以使用泛型的类型 :

Set<String> set = new HashSet<>();
for(String str : set) {
    System.out.println(str);
}

使用Stream API迭代Set

第三种方式是使用 Stream API迭代Set ,迭代时必须从Set中获取Stream,下面是代码:

Set<String> set = new HashSet<>();
set.add("one");
set.add("two");
set.add("three");
Stream<String> stream = set.stream();
stream.forEach((element) -> { System.out.println(element); });


从Set中移除元素

可以通过Set的remove(Object o)方法,从Set中移除一个元素,下面是例子:

set.remove("object-to-remove");

没有办法更加Set的索引删除元素,因为元素的顺序取决于Set的具体实现。


从Set中移除所有元素

可以调用Set的clear()方法,移除Set中所有的元素:

set.clear();


将另外一个集合的所有元素加到Set中

List接口中一个addAll()方法,可以增加 另一个 Collection (List或者Set)中的所有元素到 Set中,Set中也有对应的方法:

Set<String> set = new HashSet<>();
set.add("one");
set.add("two");
set.add("three");
Set<String> set2 = new HashSet<>();
set2.add("four");
set2.addAll(set);

代码执行后,set2中包含的元素是one,two , three 和four 。


移除另外一个集合在本集合中存在的所有元素

Set接口中存在removeAll()方法,就移除本集合和给定的Collection中同时存在的元素,在集合论中,这被称为集合与其他集合之间的区别,下面是代码:

Set<String> set = new HashSet<>();
set.add("one");
set.add("two");
set.add("three");
Set set2 = new HashSet();
set2.add("three");
set.removeAll(set2);

执行完代码后,set中包含的元素是one 和 two。元素three被移除,因为在set和set2中都存在。


保留两个集合中同时存在的元素

Set接口同样也有保留两个集合中同时存在的元素,也就是两个集合的交集 :

Set<String> set = new HashSet<>();
set.add("one");
set.add("two");
set.add("three");
Set<String> set2 = new HashSet<>();
set2.add("three");
set2.add("four");
set.retainAll(set2);

执行完代码后,set中只包含了three元素,因为只有这个元素同时存在set和set2中。


Set大小

可以通过Set的size()方法查看Set的大小:

Set<String> set = new HashSet<>();
set.add("123");
set.add("456");
set.add("789");
int size = set.size();

执行后,size的值是3,因为Set中已经加入了3个元素。


检查Set是否是空

可以调用Set的isEmpty()方法,检查Set是否是空:

Set<String> set = new HashSet<>();
boolean isEmpty = set.isEmpty();

执行代码后isEmpty 的值是空,因为Set中没有元素。也可以通过Set的size()是否是0来判断Set是否是空:

Set<String> set = new HashSet<>();
boolean isEmpty = (set.size() == 0);

执行代码后,isEmpty的值是true,因为Set中没有元素,所以size()的值是0.


Set是否包含某个指定元素

可以通过contains()方法检查Set中是否包含给定的元素,下面是例子:

Set<String> set = new HashSet<>();
set.add("123");
set.add("456");
boolean contains123 = set.contains("123");

执行后contains123的值是true,因为Set中包含字符串123。

为了确定Set中是否包含每个元素,Set内部用的equals()方法比较。但是Set中可以添加null值,所以也可以检查Set中是否包含null:

set.add(null);
containsElement = set.contains(null);
System.out.println(containsElement);

显然,contains()的参数是null, contains()方法比较不使用的==而不是equals()。


将Set转成List

可以通过  List 的 addAll()方法,将Set转成List

Set<String> set = new HashSet<>();
set.add("123");
set.add("456");
List<String> list = new ArrayList<>();
list.addAll(set);

执行后,List中包含 123 和 456。

目录
相关文章
|
19天前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
3天前
|
存储 NoSQL Redis
6)深度解密 Redis 的集合(Set)
6)深度解密 Redis 的集合(Set)
12 1
|
6天前
|
存储 前端开发 API
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
该文章详细介绍了ES6中Set和Map数据结构的特性和使用方法,并探讨了它们在前端开发中的具体应用,包括如何利用这些数据结构来解决常见的编程问题。
ES6的Set和Map你都知道吗?一文了解集合和字典在前端中的应用
|
8天前
|
存储 安全 Java
Java 常用集合分类
Java 常用集合分类
13 2
|
5天前
|
存储 数据处理 Python
Python中的Set集合:高效数据处理的利器
Python中的Set集合:高效数据处理的利器
13 0
|
2月前
|
Java
用JAVA架建List集合为树形结构的代码方法
这段代码定义了一个表示树形结构的 `Node` 类和一个用于构建树形结构的 `TreeController`。`Node` 类包含基本属性如 `id`、`pid`、`name` 和 `type`,以及子节点列表 `children`。`TreeController` 包含初始化节点列表并将其转换为树形结构的方法。通过过滤和分组操作实现树形结构的构建。详情可见:[代码示例链接1](http://www.zidongmutanji.com/zsjx/43551.html),[代码效果参考链接2](https://www.257342.com/sitemap/post.html)。
31 5
|
2月前
|
索引 Python 容器
为什么Python中会有集合set类型?
为什么Python中会有集合set类型?
|
2月前
|
存储 Java 程序员
Java中的集合框架:从入门到精通
【8月更文挑战第30天】在Java的世界里,集合框架是一块基石,它不仅承载着数据的存储和操作,还体现了面向对象编程的精髓。本篇文章将带你遨游Java集合框架的海洋,从基础概念到高级应用,一步步揭示它的奥秘。你将学会如何选择合适的集合类型,掌握集合的遍历技巧,以及理解集合框架背后的设计哲学。让我们一起探索这个强大工具,解锁数据结构的新视角。
|
2月前
|
存储 算法 Java
Java中的集合框架深度解析云上守护:云计算与网络安全的协同进化
【8月更文挑战第29天】在Java的世界中,集合框架是数据结构的代言人。它不仅让数据存储变得优雅而高效,还为程序员提供了一套丰富的工具箱。本文将带你深入理解集合框架的设计哲学,探索其背后的原理,并分享一些实用的使用技巧。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇通往高效编程的大门。
|
2月前
|
存储 算法 Java
Java 中的同步集合和并发集合
【8月更文挑战第22天】
25 5
下一篇
无影云桌面