跳转至

Java 集合

原文:http://zetcode.com/lang/java/collections/

在本章中,我们将处理集合。 Java 提供了用于数据存储和检索的专门类。 在前面的章节中,我们描述了数组。 集合是对数组的增强。

Java 5 引入了通用集合。 通用集合更灵活,它们是使用数据的首选方式。 通用集合可增强代码重用性,类型安全性和性能。

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

Java ArrayList

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

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

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

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-each循环遍历列表。

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

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

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

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方法。

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()方法用给定元素替换指定索引处的元素。 "Tomas"替换为"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的方法。

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.ArrayListMethodsEx2的输出。

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

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 

这是com.zetcode.ListOfListsEx的输出。

Java 遍历列表

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

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-each循环进行遍历。

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可以存储空值。

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]

这是示例的输出。

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

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());
    }
}

在此示例中,我们提出以下三种方法:containsKey()remove()replace()

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 

This is the output of the example.

单词计数

在下面的示例中,我们计算文本文件中单词的出现次数。 我们使用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/目录中。

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更节省空间。

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不提供元素的排序。

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()方法,我们检查品牌容器中是否存在沃尔沃品牌。 该行打印true

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

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

brands.clear();

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

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

这是com.zetcode.HashSetEx程序的输出。

Java TreeSet

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

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]

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

Java Collections

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

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));

ArrayList由整数数组创建。 Arrays类的asList()方法用于将数组转换为列表,然后将其传递给构造器。

Collections.sort(ns); 

sort()方法以升序对元素进行排序。

Collections.reverse(ns);

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

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

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

Collections.replaceAll(ns, 4, 0);

该行用 0 替换所有出现的数字 4。

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 集合。



回到顶部