对问题和练习的答案:

Questions

  • 问题:在本课开始时,您了解了核心集合interface被组织为两个不同的继承树。特别地,一个interface不被视为 true 的Collection,因此位于其自己的树的顶部。该interface的名称是什么?
    答案:Map

  • 问:集合框架中的每个interface都使用<E>语法声明,这告诉您它是通用的。声明Collection实例时,指定其将包含的对象类型有什么好处?
    答:指定类型可以使编译器在编译时验证您放入集合中的对象类型是否正确,从而减少了运行时的错误。

  • 问题:哪个interface代表不允许重复元素的集合?
    答案:Set

  • 问题:什么interface构成集合层次结构的根?
    答案:Collection

  • 问题:哪个interface表示可能包含重复元素的有序集合?
    答案:List

  • 问题:哪个interface代表在处理之前保存元素的集合?
    答案:Queue

  • 问题:哪个interface代表将键 Map 到值的类型?
    答案:Map

  • 问题:哪个interface代表 deque?
    答案:Deque

  • 问题:列举三种不同的方法来迭代List的元素。
    答:您可以使用流,增强的for语句或迭代器在List上进行迭代。

  • 问题:对或错:聚合操作是修改基础集合的变异操作。
    答:错。聚合操作不会使基础集合发生变异。实际上,在调用集合的聚合操作时,必须小心不要使它变异。如果将来在某个时候将流更改为并行流,这样做可能会导致并发问题。

Exercises

  • 练习:编写一个程序,以随机 Sequences 打印其参数。不要复制参数数组。演示如何使用流和传统for 语句增强版来打印元素。
    Answer:
import java.util.*;

public class Ran {

    public static void main(String[] args) {
        
        // Get and shuffle the list of arguments
        List<String> argList = Arrays.asList(args);
        Collections.shuffle(argList);

        // Print out the elements using JDK 8 Streams
        argList.stream()
        .forEach(e->System.out.format("%s ",e));

        // Print out the elements using for-each
        for (String arg: argList) {
            System.out.format("%s ", arg);
        }

        System.out.println();
    }
}
  • 练习:以FindDups为例,并将其修改为使用SortedSet而不是Set。指定Comparator,以便在排序和标识集合元素时忽略大小写。
    Answer:
import java.util.*;

public class FindDups {
    public static void main(String[] args) {
        Set<String> s = new HashSet<String>();
        for (String a : args)
               s.add(a);
               System.out.println(s.size() + " distinct words: " + s);
    }
}
  • 练习:编写一个采用List<String>并将String.trim应用于每个元素的方法。
    Answer:
    增强的for语句不允许您修改List。使用Iterator类的实例可以删除元素,但不能替换现有元素或添加新元素。剩下ListIterator
import java.util.*;

public class ListTrim {
    static void listTrim(List<String> strings) {
        for (ListIterator<String> lit = strings.listIterator(); lit.hasNext(); ) {
            lit.set(lit.next().trim());
        }
    }

    public static void main(String[] args) {
        List<String> l = Arrays.asList(" red ", " white ", " blue ");
        listTrim(l);
        for (String s : l) {
            System.out.format("\"%s\"%n", s);
        }
    }
}
  • 练习:考虑四个核心interfaceSetListQueueMap。对于以下四个分配中的每个分配,指定四个核心interface中的哪个最适合,并说明如何使用它来实现分配。
    Answers:

  • Whimsical Toys Inc(WTI)需要记录其所有雇员的姓名。每个月,将从这些 Logging 随机选择一名员工,以获取免费玩具。
    使用List。通过选择一个介于0size()-1之间的数字来选择一个随机雇员。

  • WTI 决定将每个新产品都命名为一个员工,但只会使用名字,每个名称只能使用一次。准备唯一的名字列表。
    使用Set。实现此interface的集合不允许多次 Importing 同一元素。

  • WTI 决定只希望使用最受欢迎的玩具名称。计算每个名字的雇员人数。
    使用Map,其中键是名字,并且每个值都是具有该名字的员 Worker 数的计数。

  • WTI 为当地的 Long 曲棍球队获取季票,由员工共享。为此受欢迎的运动创建一个 await 列表。
    使用Queue。调用add()将员工添加到 await 列表,并调用remove()将其删除。