Java集(Set)

时间:2020-01-09 10:35:49  来源:igfitidea点击:

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)时,这些都是设置中存在的所有元素。