ZetCode

Java 集合

最后修改于 2024 年 1 月 27 日

在本文中,我们将讨论集合。 Java 提供了专门的类用于数据存储和检索。

Java 5 引入了泛型集合。泛型集合更加灵活,并且是处理数据的首选方式。泛型集合增强了代码重用、类型安全和性能。

集合框架中有很多类。 其中一些,例如 ArrayBlockingQueueIdentityHashMap,是在特定情况下使用的专用容器。 我们将提到一些通用容器。

Java ArrayList

ArrayList 是一个动态的、可调整大小的数组。 它提供对其元素的随机访问。 随机访问意味着我们可以在恒定时间内获取任何元素。 ArrayList 会在添加数据时自动扩展。 与数组不同,ArrayList 可以保存多种数据类型的数据。 ArrayList 中的元素通过整数索引访问。 索引从零开始。 元素的索引以及在 ArrayList 末尾的插入和删除需要恒定时间。

在动态数组的中间插入或删除元素成本更高。 它需要移动所有后面的元素。 该过程需要线性时间。

您可以在 Java ArrayList 教程中找到有关 Java ArrayList 的更多信息。

com/zetcode/ArrayListSimpleEx.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ArrayListSimpleEx {

    public static void main(String[] args) {

        List<String> distros = new ArrayList<String>();
        distros.add("Manjaro");
        distros.add("Xubuntu");
        distros.add("Fedora");
        distros.add("elementary");

        for (String distro : distros) {

            System.out.println(distro);
        }

        List<String> capitals = Arrays.asList("Prague", "Bratislava", "Warsaw",
                "Budapest", "Washington");

        for (String capital : capitals) {

            System.out.println(capital);
        }
    }
}

该示例创建两个列表并打印它们的内容。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

必要的类位于 java.util 包中。

List<String> distros = new ArrayList<String>();

创建一个新的 ArrayList。 该列表可以包含字符串。 列表可以包含的类型在尖括号之间给出。

distros.add("Manjaro");
distros.add("Xubuntu");
distros.add("Fedora");
distros.add("elementary");

使用 add 方法,我们将四个条目添加到列表中。

for (String distro : distros) {

    System.out.println(distro);
}

我们使用增强的 for 循环来遍历列表。

List<String> capitals = Arrays.asList("Prague", "Bratislava", "Warsaw",
        "Budapest", "Washington");

我们可以使用 Arrays.asList 方法来初始化一个列表。

一个 ArrayList 可以包含多种数据类型。

com/zetcode/ArrayListMultipleEx.java
package com.zetcode;

import java.util.ArrayList;
import java.util.List;

class Base { }

public class ArrayListMultipleEx {

    public static void main(String[] args) {

        List da = new ArrayList();

        da.add("Java");
        da.add(3.5);
        da.add(55);
        da.add(new Base());

        for (Object el : da) {

            System.out.println(el);
        }
    }
}

该示例创建一个 ArrayList 集合。 它包含各种数据类型。

import java.util.ArrayList;

java.util 包中,我们导入 ArrayList 类。

List da = new ArrayList();

创建一个 ArrayList 集合。

da.add("Java");
da.add(3.5);
da.add(55);
da.add(new Base());

我们使用 add 方法向数组添加四个元素。

for (Object el : da) {

    System.out.println(el);
}

我们遍历数组列表并将它的元素打印到控制台。

$ java com.zetcode.ArrayListMultipleEx
Java
3.5
55
com.zetcode.Base@1535ac

在这里我们可以看到 com.zetcode.ArrayListMultipleEx 的输出。

下一个示例将展示一些 ArrayList 方法。

com/zetcode/ArrayListMethodsEx.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ArrayListMethodsEx {

    public static void main(String[] args) {

        List<String> names = new ArrayList<String>();
        names.add("Jane");
        names.add("Thomas");
        names.add("Robin");
        names.add("David");
        names.add("Becky");

        System.out.println(names);
        names.set(1, "Tom");
        System.out.println(names);

        System.out.format("There are %d elements in the collection%n",
                names.size());

        names.remove(1);
        System.out.format("There are %d elements in the collection%n",
                names.size());

        System.out.println(names.get(3));

        System.out.println("************");

        Iterator<String> it = names.iterator();

        while (it.hasNext()) {

            System.out.println(it.next());
        }
    }
}

在该示例中,我们展示了 ArrayList 容器的一些有用方法。

List<String> names = new ArrayList<String>();

创建一个泛型 ArrayList。 我们将元素的数据类型限制为 String 数据类型。 这是通过在 <> 字符之间写入数据类型来完成的。

names.add("Jane");
names.add("Thomas");
names.add("Robin");
names.add("David");
names.add("Becky");

我们向数组列表添加五个字符串元素。

System.out.println(names);

将容器作为参数传递给 println 方法将调用容器的 toString 方法。 它将集合转换为字符串。

names.set(1, "Tom");

set 方法将指定索引处的元素替换为给定的元素。“Thomas”被替换为“Tom”。

System.out.format("There are %d elements in the collection%n",
        names.size());

ArrayList 的大小由 size 方法确定。

names.remove(1);

我们从集合中删除第二个元素。 参数是集合的索引。

System.out.println(names.get(3));

get 方法检索容器的第四个元素。

Iterator<String> it = names.iterator();

while (it.hasNext()) {

    System.out.println(it.next());
}

我们使用 Iterator 对象遍历容器。 hasNext 方法检查是否还有一些元素,而 next 方法检索迭代中的下一个元素。

$ java com.zetcode.ArrayListMethodsEx
[Jane, Thomas, Robin, David, Becky]
[Jane, Tom, Robin, David, Becky]
There are 5 elements in the collection
There are 4 elements in the collection
Becky
************
Jane
Robin
David
Becky

这是 com.zetcode.ArrayListMethodsEx 示例的示例输出。

在下一个示例中,我们将继续展示 ArrayList 的方法。

com/zetcode/ArrayListMethodsEx2.java
package com.zetcode;

import java.util.ArrayList;
import java.util.List;

public class ArrayListMethodsEx2 {

    public static void main(String[] args) {

        List<String> names = new ArrayList<>();

        names.add("Jane");
        names.add(0, "Thomas");
        names.add(1, "Robin");
        names.add("David");
        names.add("Becky");

        System.out.println(names);

        System.out.println(names.isEmpty());
        System.out.println(names.contains("Jane"));
        System.out.println(names.contains("Robert"));

        System.out.println(names.indexOf("Jane"));

        System.out.println(names.subList(1, 4));

        names.clear();
        System.out.println(names.isEmpty());
        System.out.println(names);
    }
}

我们展示了另外五个可用于处理 ArrayList 的方法。

List<String> names = new ArrayList<>();

自 Java 7 以来,可以在泛型类的构造函数调用中省略显式类型参数。编译器会推断泛型类构造函数的参数类型。

names.add("Jane");
names.add(0, "Thomas");

add 方法向容器添加一个新项目。 重载的第二个选项指定项目将放置的索引。 最后,“Thomas”字符串位于“Jane”字符串之前。

System.out.println(names.isEmpty());

empty 方法检查容器是否为空。 该行返回 false。 此时,我们在容器中有五个字符串。

System.out.println(names.contains("Jane"));

contains 方法确定指定的元素是否存在于容器中。

System.out.println(names.indexOf("Jane"));

indexOf 方法返回指定元素第一次出现的索引,如果列表不包含该元素,则返回 -1。

System.out.println(names.subList(1, 4));

subList 方法返回列表中指定索引之间的切片。 第一个索引处的元素包含在切片中,第二个索引处的元素不包含在切片中。

names.clear();

clear 方法从容器中删除所有元素。

$ java com.zetcode.ArrayListMethodsEx2
[Thomas, Robin, Jane, David, Becky]
false
true
false
2
[Robin, Jane, David]
true
[]

我们可以将其他列表添加到列表中。

com/zetcode/ListOfLists.java
package com.zetcode;

import java.util.ArrayList;
import java.util.List;

public class ListOfLists {

    public static void main(String[] args) {

        List<Integer> l1 = new ArrayList<>();
        l1.add(1);
        l1.add(2);
        l1.add(3);

        List<Integer> l2 = new ArrayList<>();
        l2.add(4);
        l2.add(5);
        l2.add(6);

        List<Integer> l3 = new ArrayList<>();
        l3.add(7);
        l3.add(8);
        l3.add(9);

        List<List<Integer>> nums = new ArrayList<>();
        nums.add(l1);
        nums.add(l2);
        nums.add(l3);

        System.out.println(nums);

        for (List<Integer> list : nums) {

            for (Integer n : list) {

                System.out.printf("%d ", n);
            }

            System.out.println();
        }
    }
}

该示例创建三个整数列表。 稍后,这些列表被添加到另一个第四个列表中。

List<Integer> l1 = new ArrayList<>();
l1.add(1);
l1.add(2);
l1.add(3);

创建一个整数列表。

List<List> nums = new ArrayList<>();
nums.add(l1);
nums.add(l2);
nums.add(l3);

创建一个列表的列表。

for (List<Integer> list : nums) {

    for (Integer n : list) {

        System.out.printf("%d ", n);
    }

    System.out.println();
}

我们使用两个 for 循环来遍历所有元素。

$ java com.zetcode.ListOfListsEx
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
1 2 3
4 5 6
7 8 9

Java 遍历列表

在下一节中,我们将展示如何在 Java 中遍历列表。

com/zetcode/TraversingList.java
package com.zetcode;

import java.util.ArrayList;
import java.util.List;

public class TraversingList {

    public static void main(String[] args) {

        List<String> martialArts = new ArrayList<>();
        martialArts.add("Silat");
        martialArts.add("Wing chun");
        martialArts.add("Karate");
        martialArts.add("Judo");
        martialArts.add("Aikido");

        for (int i=0; i < martialArts.size(); i++) {

            System.out.printf("%s ", martialArts.get(i));
        }

        System.out.print("\n");

        for (String e: martialArts) {

            System.out.printf("%s ", e);
        }

        System.out.print("\n");

        martialArts.forEach((e) -> System.out.printf("%s ", e));

        System.out.print("\n");
    }
}

我们有一个字符串列表;我们展示了在 Java 中遍历列表的三种方法。

for (int i=0; i < martialArts.size(); i++) {

    System.out.printf("%s ", martialArts.get(i));
}

使用传统的 for 循环遍历列表。

for (String e: martialArts) {

    System.out.printf("%s ", e);
}

这里使用增强的 for 循环遍历列表。

martialArts.forEach((e) -> System.out.printf("%s ", e));

第三种方法使用 forEach 方法和 lambda 表达式。

$ java com.zetcode.TraversingList
Silat Wing chun Karate Judo Aikido
Silat Wing chun Karate Judo Aikido
Silat Wing chun Karate Judo Aikido

Java LinkedList

LinkedList 是 Java 中的双向链表。 元素的插入和删除需要恒定时间。 链表提供对其元素的顺序访问,这意味着获取元素需要线性时间。 因为链表需要额外的存储空间来存储引用,所以它们不适用于小数据项(例如字符)的列表。

当将 ArrayListLinkedList 进行比较时,ArrayList 可以快速访问特定元素,但添加到两端可能很慢,尤其是在中间删除时。 LinkedList 可以快速添加和删除元素,但访问特定元素的速度很慢。

LinkedListEx.java
package com.zetcode;

import java.util.LinkedList;

public class LinkedListEx {

    public static void main(String[] args) {

        LinkedList<Integer> nums = new LinkedList<>();

        nums.add(5);
        nums.add(10);
        nums.add(13);
        nums.add(12);
        nums.add(15);
        nums.add(23);

        System.out.println(nums);

        nums.removeFirst();
        nums.removeLast();
        nums.addFirst(17);
        nums.addLast(77);

        System.out.println(nums);
    }
}

这是一个带有某些方法的 LinkedList 示例。

LinkedList<Integer> nums = new LinkedList<>();

LinkedList 包含整数。

nums.add(5);
nums.add(10);

我们将数字添加到列表中。 自动装箱将原始 int 类型包装到 Integer 对象。

nums.removeFirst();
nums.removeLast();

这两种方法从容器中删除第一个和最后一个元素。

nums.addFirst(17);
nums.addLast(77);

我们在列表的开头和结尾添加一个元素。

$ java com.zetcode.LinkedListEx
[5, 10, 13, 12, 15, 23]
[17, 10, 13, 12, 15, 77]

链表包含的元素两次打印到控制台。

Java HashMap

HashMap 是一个存储键/值对的容器。 每个键都与一个值相关联。 键必须是唯一的。 在其他编程语言中,此容器类型称为关联数组或字典。 HashMap 占用更多内存,因为每个值都有一个键。

删除和插入操作需要恒定时间。 HashMap 可以存储空值。

Java HaspMap 教程中了解有关哈希映射的更多信息。

com/zetcode/HashMapEx.java
package com.zetcode;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class HashMapEx {

    public static void main(String[] args) {

        Map<String, String> domains = new HashMap<>();

        domains.put("de", "Germany");
        domains.put("sk", "Slovakia");
        domains.put("us", "United States");
        domains.put("ru", "Russia");
        domains.put("hu", "Hungary");
        domains.put("pl", "Poland");

        System.out.println(domains.get("pl"));

        for (String item : domains.values()) {

            System.out.println(item);
        }

        Set keys = domains.keySet();

        System.out.println(keys);
    }
}

我们有一个 HashMap,我们在其中将域名映射到它们的国家名称。

Map<String, String> domains = new HashMap<>();

我们创建一个具有字符串键和值的 HashMap

domains.put("de", "Germany");
domains.put("sk", "Slovakia");
domains.put("us", "United States");
...

我们将一些数据放入 HashMap 中。 第一个字符串是键。 第二个是值。

System.out.println(domains.get("pl"));

我们通过它的键检索一个特定的值。 对于检索操作,我们使用 get 方法。

for (String item : domains.values()) {

    System.out.println(item);
}

values 方法返回域 HashMap 中包含的值的集合。 我们使用 for 循环遍历这些值并将它们打印到控制台。

Set keys = domains.keySet();

keySet 方法在 Set 集合中返回 HashMap 的键。 Set 是唯一元素的集合。

System.out.println(keys);

集合的元素被打印到控制台。

$ java com.zetcode.HashMapEx
Poland
Germany
Slovakia
Hungary
Poland
United States
Russia
[de, sk, hu, pl, us, ru]

在下一个示例中,我们将创建一个自定义颜色对象的映射。

com/zetcode/HashMapEx2.java
package com.zetcode;

import java.util.HashMap;
import java.util.Map;

class Colour {

    private String name;
    private String code;

    public Colour(String name, String code) {
        this.name = name;
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}

public class HashMapEx2 {


    public static void main(String[] args) {

        Map<Integer, Colour> cols = new HashMap<>();

        cols.put(1, new Colour("AliceBlue", "#f0f8ff"));
        cols.put(2, new Colour("GreenYellow", "#adff2f"));
        cols.put(3, new Colour("IndianRed", "#cd5c5c"));
        cols.put(4, new Colour("khaki", "#f0e68c"));

        System.out.printf("The size of the map is %d%n", cols.size());

        int key = 4;

        if (cols.containsKey(key)) {

            System.out.printf("The map contains key %d%n", key);
        }

        cols.remove(1);

        System.out.printf("The size of the map is %d%n", cols.size());

        cols.replace(3, new Colour("VioletRed", "#d02090"));

        Colour col = cols.get(3);

        System.out.printf("Colour name:%s colour code:%s %n",
                col.getName(), col.getCode());
    }
}

在此示例中,我们介绍以下三种方法:containsKeyremovereplace

class Colour {

    private String name;
    private String code;

    public Colour(String name, String code) {
        this.name = name;
        this.code = code;
    }
...
}

自定义颜色对象包含颜色名称和颜色代码属性。

Map<Integer, Colour> cols = new HashMap<>();

创建一个映射,其中键是整数,值是 Colour 对象。

if (cols.containsKey(key)) {

    System.out.printf("The map contains key %d%n", key);
}

containsKey 方法确定键是否存在于映射中。

cols.remove(1);

remove 方法从映射中删除具有指定键的对象。

cols.replace(3, new Colour("VioletRed", "#d02090"));

replace 方法替换指定键的条目。

$ java com.zetcode.HashMapEx2
The size of the map is 4
The map contains key 4
The size of the map is 3
Colour name:VioletRed colour code:#d02090

计数单词

在以下示例中,我们统计文本文件中单词的出现次数。 我们使用 HashMap 来存储单词及其出现次数。

thermopylae.txt
The Battle of Thermopylae was fought between an alliance of Greek city-states,
led by King Leonidas of Sparta, and the Persian Empire of Xerxes I over the
course of three days, during the second Persian invasion of Greece.
It took place simultaneously with the naval battle at Artemisium, in August
or September 480 BC, at the narrow coastal pass of Thermopylae.
The Persian invasion was a delayed response to the defeat of the first Persian
invasion of Greece, which had been ended by the Athenian victory at the Battle
of Marathon in 490 BC. Xerxes had amassed a huge army and navy, and set out to
conquer all of Greece.

我们从 thermopylae.txt 文件中读取内容。 该文件位于 src/resources/ 目录中。

com/zetcode/CountingWordsEx.java
package com.zetcode;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CountingWordsEx {

    public static void main(String[] args) throws IOException {

        Map<String, Integer> wordCount = new HashMap<>();

        String fileName = "src/resources/thermopylae.txt";

        List<String> lines = Files.readAllLines(Paths.get(fileName),
                StandardCharsets.UTF_8);

        for (String line : lines) {

            String[] words = line.split("\\s+");

            for (String word : words) {

                if (word.endsWith(".") || word.endsWith(",")) {
                    word = word.substring(0, word.length()-1);
                }

                if (wordCount.containsKey(word)) {
                    wordCount.put(word, wordCount.get(word) + 1);

                } else {
                    wordCount.put(word, 1);
                }
            }
        }

        for (String key : wordCount.keySet()) {
            System.out.println(key + ": " + wordCount.get(key));
        }
    }
}

该示例从文件中读取文本,将句子拆分为单词并计算它们在文本中的频率。

Map<String, Integer> wordCount = new HashMap<>();

wordCount 是一个映射,其中键是单词,频率是整数。

String fileName = "src/resources/thermopylae.txt";

List<String> lines = Files.readAllLines(Paths.get(fileName),
        StandardCharsets.UTF_8);

我们使用 Files.readAllLines 方法一次性读取所有内容。

for (String line : lines) {

    String[] words = line.split("\\s+");
...

我们遍历这些行并将它们拆分为单词; 这些单词由空格分隔。

if (word.endsWith(".") || word.endsWith(",")) {
    word = word.substring(0, word.length()-1);
}

我们删除尾随的点号和逗号。

if (wordCount.containsKey(word)) {
    wordCount.put(word, wordCount.get(word) + 1);

} else {
    wordCount.put(word, 1);
}

如果单词已在映射中,我们会增加它的频率; 否则,我们将其插入到映射中并将其频率设置为 1。

for (String key : wordCount.keySet()) {
    System.out.println(key + ": " + wordCount.get(key));
}

我们迭代该映射并打印其键/值对。

$ java com.zetcode.CountingWordsEx
been: 1
Athenian: 1
alliance: 1
navy: 1
fought: 1
led: 1
delayed: 1
had: 2
during: 1
three: 1
second: 1
Greece: 3
Leonidas: 1
...

这是该示例的部分输出。

Java TreeMap

TreeMap 是一个映射,它根据其键的自然顺序进行排序。 虽然 HashMap 在时间上更有效,但 TreeMap 在空间上更有效。

com/zetcode/TreeMapEx.java
package com.zetcode;

import java.util.TreeMap;

public class TreeMapEx {

    public static void main(String[] args) {

        TreeMap<String, String> domains = new TreeMap<>();

        domains.put("de", "Germany");
        domains.put("sk", "Slovakia");
        domains.put("us", "United States");
        domains.put("ru", "Russia");
        domains.put("hu", "Hungary");
        domains.put("pl", "Poland");

        System.out.println(domains);
        System.out.println(domains.descendingMap());
    }
}

在该示例中,我们创建一个 TreeMap 并将域名及其国家名称放入其中。

TreeMap<String, String> domains = new TreeMap<>();

创建一个 TreeMap

System.out.println(domains);

这将以它们的自然排序顺序(升序)打印键/值。

System.out.println(domains.descendingMap());

descendingMap 方法返回此映射中包含的映射的反向顺序视图。

$ java com.zetcode.TreeMapEx
{de=Germany, hu=Hungary, pl=Poland, ru=Russia, sk=Slovakia, us=United States}
{us=United States, sk=Slovakia, ru=Russia, pl=Poland, hu=Hungary, de=Germany}

com.zetcode.TreeMapEx 程序以升序和降序打印了带有它们值的键。

Java HashSet

HashSet 是一个不包含重复元素的集合。 此类为基本操作(添加、删除、包含和大小)提供恒定时间性能。 HashSet 不提供元素的排序。

com/zetcode/HashSetEx.java
package com.zetcode;

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

public class HashSetEx {

    public static void main(String[] args) {

        Set<String> brands = new HashSet<>();

        brands.add("Pepsi");
        brands.add("Amazon");
        brands.add("Volvo");
        brands.add("IBM");
        brands.add("IBM");

        System.out.println(brands);

        System.out.println(brands.isEmpty());
        System.out.println(brands.contains("Volvo"));
        brands.remove("Volvo");
        System.out.println(brands.contains("Volvo"));

        brands.clear();
        System.out.println(brands);
    }
}

在一个名称下只能注册一个品牌。 因此,品牌名称是 HashSet 的一个很好的例子。

Set<String> brands = new HashSet<>();

brands.add("Pepsi");
brands.add("Amazon");
brands.add("Volvo");
brands.add("IBM");
brands.add("IBM");

我们创建一个 HashSet 并添加新元素。 IBM 品牌被添加了两次。 但是,IBM 在容器中只出现一次。

System.out.println(brands);

我们一次性打印所有元素。

System.out.println(brands.isEmpty());

isEmpty 方法检查容器是否为空。

System.out.println(brands.contains("Volvo"));

使用 contains 方法,我们检查 Volvo 品牌是否存在于品牌容器中。 该行打印 true

brands.remove("Volvo");
System.out.println(brands.contains("Volvo"));

我们从品牌容器中删除 Volvo 品牌。 第二行打印 false

brands.clear();

clear 方法从集合中删除所有元素。

$ java com.zetcode.HashSetEx
[IBM, Pepsi, Volvo, Amazon]
false
true
false
[]

Java TreeSet

TreeSet 是一个集合,它具有使用其自然顺序排序的元素。 TreeSetHashSet 慢。 HashSet 可以包含空值,而 TreeSet 不能。

com/zetcode/TreeSetEx.java
package com.zetcode;

import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;

public class TreeSetEx {

    public static void main(String[] args) {

        List<String> brands = new ArrayList<>();

        brands.add("Pepsi");
        brands.add("Amazon");
        brands.add("Volvo");
        brands.add("IBM");
        brands.add("HP");
        brands.add("Apple");
        brands.add("Starbucks");

        TreeSet<String> brands2 = new TreeSet<>();
        brands2.addAll(brands);

        System.out.println(brands2);
        System.out.println(brands2.descendingSet());

        System.out.println(brands2.first());
        System.out.println(brands2.last());

        System.out.println(brands2.headSet("IBM", true));
        System.out.println(brands2.tailSet("IBM", false));
        System.out.println(brands2.subSet("Apple", true, "Starbucks", true));
    }
}

在此示例中,我们使用 TreeSet

List<String> brands = new ArrayList<>();

brands.add("Pepsi");
brands.add("Amazon");
brands.add("Volvo");
brands.add("IBM");
brands.add("HP");
brands.add("Apple");
brands.add("Starbucks");

创建一个各种品牌的 ArrayList

TreeSet<String> brands2 = new TreeSet<>();
brands2.addAll(brands);

addAll 方法的帮助下,从 ArrayList 容器创建一个新的 TreeSet

System.out.println(brands2);
System.out.println(brands2.descendingSet());

容器的元素以升序和降序打印到控制台。

System.out.println(brands2.first());
System.out.println(brands2.last());

我们打印容器的第一个和最后一个元素。

System.out.println(brands2.headSet("IBM", true));

headSet 方法返回集合的切片,该切片的元素小于指定的元素。 第二个参数控制是否包含指定的元素。

System.out.println(brands2.tailSet("IBM", false));

tailSet 方法返回集合的切片,该切片的元素大于指定的元素。

System.out.println(brands2.subSet("Apple", true, "Starbucks", true));

subSet 方法返回容器的一部分,该容器的元素的范围从第一个指定的元素到第二个指定的元素。

$ java com.zetcode.TreeSetEx
[Amazon, Apple, HP, IBM, Pepsi, Starbucks, Volvo]
[Volvo, Starbucks, Pepsi, IBM, HP, Apple, Amazon]
Amazon
Volvo
[Amazon, Apple, HP, IBM]
[Pepsi, Starbucks, Volvo]
[Apple, HP, IBM, Pepsi, Starbucks]

Java Collections 类

Collections 是一个实用程序类,它提供了许多用于处理容器的有用方法。 它完全由静态方法组成。 某些方法不适用于所有集合类型。 例如,不可能在 HashSet 上使用 sort 方法,因为此容器不支持排序的元素。

com/zetcode/CollectionsEx.java
package com.zetcode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class CollectionsEx {

    public static void main(String[] args) {

        Integer[] nums = { 4, 3, 2, 4, 5, 6, 4, 2, 7, 8, 9, 0, 1 };

        List<Integer> ns = new ArrayList<>(Arrays.asList(nums));
        System.out.println("Default order:");
        System.out.println(ns);

        System.out.println("Ascending order:");
        Collections.sort(ns);
        System.out.println(ns);

        System.out.println("Descending order:");
        Collections.reverse(ns);
        System.out.println(ns);

        System.out.println("Swapping the first and the last elements:");
        Collections.swap(ns, 0, ns.size()-1);
        System.out.println(ns);

        System.out.println("Replacing all 4s with 0s:");
        Collections.replaceAll(ns, 4, 0);
        System.out.println(ns);

        System.out.println("Random order:");
        Collections.shuffle(ns);
        System.out.println(ns);

        System.out.println(Collections.max(ns));
        System.out.println(Collections.min(ns));
    }
}

在该示例中,我们使用 Collections 类的几种方法。

Integer[] nums = { 4, 3, 2, 4, 5, 6, 4, 2, 7, 8, 9, 0, 1 };

ArrayList<Integer> ns = new ArrayList<>(Arrays.asList(nums));

从整数数组创建一个 ArrayListArrays 类的 asList 方法用于将数组转换为列表,然后将其传递给构造函数。

Collections.sort(ns);

sort 方法按升序对元素进行排序。

Collections.reverse(ns);

reverse 方法反转列表中元素的顺序。

Collections.swap(ns, 0, ns.size()-1);

swap 方法交换两个元素。 在我们的例子中,第一个元素与最后一个元素交换。

Collections.replaceAll(ns, 4, 0);

此行将所有出现的数字 4 替换为 0。

Collections.shuffle(ns);

shuffle 方法随机重新排序容器中的元素。

System.out.println(Collections.max(ns));
System.out.println(Collections.min(ns));

在这里,我们打印列表的最大值和最小值。

$ java com.zetcode.CollectionsEx
Default order:
[4, 3, 2, 4, 5, 6, 4, 2, 7, 8, 9, 0, 1]
Ascending order:
[0, 1, 2, 2, 3, 4, 4, 4, 5, 6, 7, 8, 9]
Descending order:
[9, 8, 7, 6, 5, 4, 4, 4, 3, 2, 2, 1, 0]
Swapping the first and the last elements:
[0, 8, 7, 6, 5, 4, 4, 4, 3, 2, 2, 1, 9]
Replacing all 4s with 0s:
[0, 8, 7, 6, 5, 0, 0, 0, 3, 2, 2, 1, 9]
Random order:
[1, 6, 2, 8, 0, 2, 0, 9, 5, 0, 7, 3, 0]
9
0

这是 com.zetcode.CollectionsEx 程序的示例输出。

来源

Java 集合 - 语言参考

在本文中,我们使用了 Java 中的集合。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。 我从 2007 年开始撰写编程文章。迄今为止,我撰写了超过 1,400 篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有Java教程