# 问题和练习
# 问题
您打算编写使用几个基本集合接口的程序:Set,List,Queue,和 Map。您不确定哪个实现最好, 所以您决定使用通用实现,直到您更好地了解您的程序如何在现实世界中运行。这些是哪些实现?
答:
- Set:HashSet
- List:ArrayList
- Queue:LinkedList
- Map:HashMap
如果你需要一个 Set 提供有序迭代的实现,你应该使用哪个类?
答:TreeSet 保证排序后的集合按照元素顺序升序排列,按照元素的自然顺序或 Comparator 提供的顺序排序。
您使用哪个类来访问包装器实现? 答:您使用的 Collections 是提供对集合进行操作或返回集合的静态方法的类。
# 练习
写一个程序,读取由第一个命令行参数指定的文本文件到一个 List。然后程序应该从文件中打印出随机的行, 打印的行数由第二个命令行参数指定。编写程序,以便一次分配正确大小的集合,而不是在读入文件时逐渐扩展。 提示:要确定文件中的行数,使用 java.io.File.length 获取文件的大小,然后除以平均线的假定大小。
答:由于要随机访问,所以我们使用 ArrayList。通过文件大小除以 50 来估计,然后翻倍
import java.util.*;
import java.io.*;
public class FileList {
public static void main(String[] args) {
final int assumedLineLength = 50;
File file = new File(args[0]);
List<String> fileList =
new ArrayList<String>((int)(file.length() / assumedLineLength) * 2);
BufferedReader reader = null;
int lineCount = 0;
try {
reader = new BufferedReader(new FileReader(file));
for (String line = reader.readLine(); line != null;
line = reader.readLine()) {
fileList.add(line);
lineCount++;
}
} catch (IOException e) {
System.err.format("Could not read %s: %s%n", file, e);
System.exit(1);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {}
}
}
int repeats = Integer.parseInt(args[1]);
Random random = new Random();
for (int i = 0; i < repeats; i++) {
System.out.format("%d: %s%n", i,
fileList.get(random.nextInt(lineCount - 1)));
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
这个程序实际上大部分时间是在文件中读取的,所以预先分配 ArrayList 对它的性能影响不大。 当您的程序重复创建大型 ArrayList 对象而不介入 I / O 时,提前指定初始容量更有用。