文档

Java™ 教程-Java Tutorials 中文版
Trail: Collections
Lesson: Interfaces
主页>集合>接口

问题和练习的答案:

问题

  1. 问题:在本课程开始时,你了解到核心集合接口被组织为两个不同的继承树。特别是一个接口不被认为是真正的 Collection,因此位于其自己的树的顶部。这个接口的名称是什么?
    答案:Map

  2. 问题:集合框架中的每个接口都使用 <E> 语法声明,该语法告诉你它是泛型的。声明 Collection 实例时,指定它将包含的对象类型有什么好处?
    答案:指定类型允许编译器(在编译时)验证放入集合中的对象类型是否正确,从而减少运行时的错误。

  3. 问题:什么接口表示不允许重复元素的集合?
    答案:Set

  4. 问题:什么接口形成集合层次结构的根?
    答案:Collection

  5. 问题:什么接口表示可能包含重复元素的有序集合?
    答案:List

  6. 问题:什么接口表示在处理之前保存元素的集合?
    答案:Queue

  7. 问题:什么接口表示将键映射到值的类型?
    答案:Map

  8. 问题:什么接口代表双端队列?
    答案:Deque

  9. 问题:列举三种不同的方法来迭代 List 的元素。
    答案:你可以使用流,增强的 for 语句或迭代器迭代 List

  10. 问题:对或错:聚合操作是修改基础集合的可变型操作。
    答案:错。聚合操作不会改变底层集合。实际上,在调用其聚合操作时,必须小心不要改变集合。如果在将来的某个时刻将流更改为并行流,这样做可能会导致并发问题。

练习

  1. 练习:编写一个以随机顺序打印其参数的程序。不要复制参数数组。演示如何使用流和传统的增强 for 语句打印出元素。
    答案:
    
    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();
        }
    }
    
  2. 练习:取 FindDups 示例并将其修改为使用 SortedSet 而不是 Set。指定 Comparator,以便在排序和标识集合元素时忽略大小写。
    答案:
    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);
        }
    }
    
  3. 练习:编写一个方法,该方法采用 List<String> 并将 String.trim 应用于每个元素。
    答案:
    增强的 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);
            }
        }
    }
    
  4. 练习:考虑四个核心接口,SetListQueueMap。对于以下四个分配中的每一个,指定四个核心接口中哪一个最适合,并解释如何使用它来实现分配。
    回答:
    • 异想天开的玩具公司(WTI)需要记录其所有员工的姓名。每个月,将从这些记录中随机选择一名员工以获得免费玩具。
      使用 List。通过选择 0size()-1 之间的数字来选择随机员工。
    • WTI 决定每个新产品都以员工命名 — 但只会使用名字,每个名字只能使用一次。准备一个唯一名字的列表。
      使用 Set。实现此接口的集合不允许多次输入相同的元素。
    • WTI 决定只想使用最受欢迎的玩具名称。计算拥有每个名字的员工数量。
      使用 Map,其中键是名字,每个值是具有该名字的员工数量。
    • WTI 获得当地长曲棍球队的季票,由员工共享。为这项受欢迎的运动创建一个等待名单。
      使用 Queue。调用 add() 将员工添加到等待列表,然后 remove() 移除它们。

Previous page: Questions and Exercises: Interfaces