Java集(Set)
Java Set接口Java.util.Set表示对象的集合,其中Java Set中的每个对象都是唯一的。换句话说,在Java集中,同一对象不能出现多次。 Java Set接口是标准的Java接口,它是Java Collection接口的子类型,这意味着Set继承自Collection。
我们可以将任何Java对象添加到Java Set中。如果未使用Java泛型键入" Set",则我们甚至可以在同一Set中混合使用不同类型(类)的对象。然而,现实中通常不会在同一"集合"中混合不同类型的对象。
Java集与列表
Java Set和Java List接口非常相似。 Bot接口代表元素的集合。但是,有一些显着差异。这些差异体现在Set和List接口所包含的方法中。
Java Set和List接口之间的第一个区别是,同一元素在Java Set中不能出现多次。这与Java"列表"不同,在Java"列表"中,每个元素都可以出现多次。
Java Set和Java List接口之间的第二个区别是Set中的元素没有保证的内部顺序。 List中的元素具有内部顺序,并且可以按照该顺序进行迭代。
Java设置示例
这首先是一个简单的Java Set例子,让我们了解set的工作方式:
package com.Hyman.collections; import java.util.HashSet; public class SetExample { public static void main(String[] args) { Set setA = new HashSet(); setA.add(element); System.out.println( setA.contains(element) ); } }
本示例创建一个" HashSet",它是实现" Set"接口的Java API中的类之一。然后,它将字符串对象添加到集合中,最后检查集合中是否包含刚刚添加的元素。
设置实施
作为"集合"子类型,"集合"接口中的所有方法也可以在"设置"接口中使用。
由于" Set"是一个接口,因此我们需要实例化该接口的具体实现才能使用它。我们可以在Java Collections API的以下" Set"实现之间进行选择:
- java.util.EnumSet
- java.util.HashSet
- java.util.LinkedHashSet
- java.util.TreeSet
这些Set
实现中的每一个在迭代Set
时的元素顺序以及插入和访问Set中的元素所花费的时间(大O表示法)方面都有一些不同。
HashSet由HashMap支持。迭代元素时,它不能保证元素的顺序。
" LinkedHashSet"与" HashSet"的不同之处在于,它确保元素在迭代过程中的顺序与将其插入" LinkedHashSet"中的顺序相同。重新插入LinkedHashSet中已存在的元素不会更改此顺序。
TreeSet还可以保证元素在迭代时的顺序,但是顺序是元素的排序顺序。换句话说,如果我们在包含这些元素的"列表"或者数组上使用" Collections.sort()",则元素的排序顺序。这个顺序是由它们的自然顺序(如果它们实现"可比较")或者特定的"比较器"实现来确定的。
java.util.concurrent
包中也有Set的实现,但是我将并发实用程序放在本教程之外。
创建一个集合
以下是一些有关如何创建Set实例的示例:
package com.Hyman.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(); } }
通用集
默认情况下,我们可以将任何"对象"放入"集合"中,但是从Java 5开始,Java泛型可以限制我们可以插入"集合"中的对象的类型。这是一个例子:
Set<MyObject> set = new HashSet<MyObject>();
现在,该"集合"只能插入" MyObject"实例。然后,我们可以访问和迭代其元素,而无需强制转换它们。外观如下:
for(MyObject anObject : set){ //do someting to anObject... }
最好始终为Java Set指定通用类型,这是一种好习惯。本教程中的大多数示例都使用泛型类型。
有关Java泛型的更多信息,请参见Java泛型教程。
将元素添加到集合
要将元素添加到Set中,请调用其add()方法。这个方法是从Collection
接口继承的。这里有一些例子:
Set<String> setA = new HashSet<>(); setA.add("element 1"); setA.add("element 2"); setA.add("element 3");
三个add()
调用将一个String
实例添加到集合中。
迭代集合元素
有两种方法可以迭代Java Set的元素:
- 使用从Set中获得的Iterator。
- 使用for-each循环。
以下各节将介绍这两个选项。
如前所述,当迭代Set中的元素时,元素的顺序取决于我们使用哪种Set实现。
使用迭代器迭代集
要使用Java迭代器迭代"集合"的元素,我们必须首先从"集合"中获取"迭代器"。我们可以通过调用iterator()
方法从Set中获取一个Iterator。这是从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循环。这是使用for-each循环迭代Set元素的样子:
Set set = new HashSet(); for(Object object : set) { String element = (String) object; }
Set接口实现Java Iterable接口。这就是为什么我们可以使用for-each循环来迭代Set的元素的原因。
如果集合具有指定的泛型类型,则可以将该类型用作for-each循环内的变量类型。看起来是这样的:
Set<String> set = new HashSet<>(); for(String str : set) { System.out.println(str); }
这是将for-each循环与为for-each循环使用的Collection指定的通用类型结合使用的首选方法。
使用Java Stream API进行迭代设置
迭代Java Set的第三种方法是通过Java Stream API。要使用Java Stream API迭代Java Set,必须从Set中创建Stream。这是从Set中创建Java Stream并迭代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); });
我们可以在Java Stream API教程中阅读有关Java Stream API中可用选项的更多信息。
从集合中删除元素
我们可以通过调用remove(Object o)
方法从JavaSet
中删除元素。这是从Java Set中删除元素的示例:
set.remove("object-to-remove");
由于元素的顺序取决于Set的实现,因此无法根据Set中的索引删除对象。
从集合中删除所有元素
我们可以使用clear()方法从Java Set中删除所有元素。这是从Java Set中删除所有元素的示例:
set.clear();
添加另一个集合中的所有元素
Java" List"接口具有一个名为" addAll()"的方法,该方法将来自另一个" Collection"(" List"或者" Set")的所有元素添加到" Set"中。在集合论中,这对应于"集合"和另一个"集合"的并集。这是一个将另一个Set中的所有元素添加到Java 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"将包含String元素" four"以及来自set的三个String元素" one"," two"和" three"。
从另一个集合中删除所有元素
JavaSet
接口作为一种称为removeAll()
的方法,它删除了Set中的所有元素,这些元素也存在于另一个Collection中。在集合理论中,这称为"集合"与另一个"集合"之间的差异。这是从Java Set中删除所有在另一个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);
运行此Java示例后,set将会包含String元素one和two。元素"三"已删除,因为它存在于" set2"中,该元素已作为" set.removeAll(set2)"的参数提供。
保留另一个集合中存在的所有元素
Java Set接口还具有一种方法,该方法可以保留Set中的所有元素,这些元素也存在于另一个Collection中。在"集合"中找到的所有在其他"集合"中不存在的元素将被删除。在集合理论中,这被称为"集合"与另一个"集合"之间的交集。这是一个保留Java Set中所有元素的示例,这些元素也存在于另一个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);
运行此Java代码后," set"将仅包含字符串元素"三"。这是set和set2中都存在的唯一元素。
设定尺寸
我们可以使用size()
方法检查JavaSet
的大小。 Set的大小是Set中包含的元素数。这是读取Java Set大小的示例:
Set<String> set = new HashSet<>(); set.add("123"); set.add("456"); set.add("789"); int size = set.size();
执行完此Java代码后," size"变量的值将为3,因为在示例中创建的" Set"具有3个元素。
检查集是否为空
我们可以通过在Set上调用isEmpty()方法来检查Java Set是否为空,这意味着它不包含任何元素。这是一个检查Java Set是否为空的示例:
Set<String> set = new HashSet<>(); boolean isEmpty = set.isEmpty();
运行该Java代码后,isEmpty
变量将包含值true
,因为Set
为空(其中没有元素)。
我们还可以通过比较size()方法返回的值和0来检查Set是否为空。以下示例显示了如何:
Set<String> set = new HashSet<>(); boolean isEmpty = (set.size() == 0);
运行此Java代码后,isEmpty变量将包含值true,因为Set的size()方法返回0,因为示例中的Set不包含任何元素。
检查集合是否包含元素
我们可以通过调用contains()方法来检查Java Set是否包含给定的元素(对象)。这是检查JavaSet
是否包含给定元素的示例:
Set<String> set = new HashSet<>(); set.add("123"); set.add("456"); boolean contains123 = set.contains("123");
运行此Java代码后,contains123
变量将包含值true
,因为Set
实际上包含字符串123
。
为了确定Set是否包含元素,Set将在内部对其元素进行迭代,并将每个元素与作为参数传递的对象进行比较。比较使用元素的Java equals方法检查元素是否等于参数。
由于可以将" null"值添加到" Set"中,因此也可以检查" Set"是否包含" null"值。这是检查"集合"是否包含"空"值的方法:
set.add(null); containsElement = set.contains(null); System.out.println(containsElement);
显然,如果contains()的输入参数为null,那么contains()方法将不使用equals()方法与每个元素进行比较,而是使用==运算符。
将Java集转换为列表
我们可以通过创建" List"并调用其" addAll()"方法,并将" Set"作为参数传递给" addAll()"方法,从而将Java" Set"转换为Java" List"。这是将Java Set转换为List的示例:
Set<String> set = new HashSet<>(); set.add("123"); set.add("456"); List<String> list = new ArrayList<>(); list.addAll(set);
在运行此Java示例之后,"列表"将包含字符串元素" 123"和" 456",因为当调用"列表" addAll(set)时,这些都是设置中存在的所有元素。