0%

On Java 8 (2) 集合、流式编程、文件、字符串、数组

§ 集合

Java 集合类库采用“持有对象”的思想,并将其分为两个不同的概念,表示为类库的基本接口:

  • 集合。一个独立元素的序列,如 ListSetQueue
  • 映射。一组成对的 “键值对” 对象。如 Map 被称为关联数组,也被称作字典。 TreeMap 保持键始终处于排序状态。

不要在新代码中使用遗留类: VectorHashtableStack

列表 List

有两种类型的 List:

  • ArrayList,擅长随机访问元素,但在 List 中间插入和删除元素时速度较慢。
  • LinkedList,它通过代价较低的在 List 中间进行的插入和删除操作,提供了优化的顺序访问。LinkedList 对于随机访问来说相对较慢,但它具有比 ArrayList 更大的特征集。

堆栈 Stack

堆栈式后进先出集合。Java6 添加了 ArrayDeque,包含了实现堆栈的方法:

1
Deque<String> stack = new ArrayDeque<>();

集合 Set

Set 不保存重复的元素。Set 最常见的用途是测试 归属性,可以很轻松地询问某个对象是否在一个 Set 中。

因此,查找通常是 Set 最重要的操作,通常会选择 HashSet 实现,该实现针对快速查找进行了优化.

映射 Map

队列 Queue

队列是典型的先进先出集合。

LinkedList 实现了 Queue 接口,并且提供了一些方法支持队列行为,是 Queue 的一种实现。

1
Queue<Integer> queue = new LinkedList<>();

§ 流式编程

Java 8 通过在接口中添加 default 修饰的方法,实现将流式方法平滑的迁移到现有类中。

1
Stream.of(new Bubble(1), new Bubble(2), new Bubble(3)).forEach(System.out::println)

每个集合都可以通过调用 stream() 方法来产生一个流。

创建流

还有有很多创建流的方法,如 IntStream 类提供了 range() 方法用于生成整型序列的流。

1
2
3
4
5
6
for (int i : range(10, 20).toArray()) {
result += i;
}

// 更简洁的方式使用
System.out.println(range(10, 20).sum());

中间操作

map()flatMapsorted()

Optional 类

终端操作

  • 数组 toArray() 将流转化为数组
  • 循环 forEach()
  • 集合 collect()
  • 组合 reduce()
  • 匹配 allMath()anyMatch()noneMatch()
  • 查找 findFirst()findAny()
  • 信息 count()max()min()

§ 文件

Java 7 和 8 引入了巨大的改进,一些新元素放在 java.nio.file 下面。并且 Java8 新增的 streams 与文件结合使得文件操作编程更加优雅。

一定要研究 java.nio.file 的文档,尤其是 java.nio.file.Files

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
String file = userDir + DS + "file" + DS + "a.txt";
Path path = Paths.get(file);

System.out.println(path.isAbsolute());
System.out.println(path.getParent());
System.out.println(path.getFileName());
System.out.println(path.getFileSystem());
System.out.println(path.getRoot());

if (Files.exists(path)) {
System.out.println(Files.isRegularFile(path));
System.out.println(Files.isDirectory(path));
System.out.println(Files.isExecutable(path));
System.out.println(Files.isReadable(path));
System.out.println(Files.isWritable(path));
System.out.println(Files.getFileStore(path));
System.out.println(Files.size(path));
}

§ 字符串

String 对象是不可变的。查看 JDK 文档你就会发现,String 类中每一个看起来会修改 String 值的方法,实际上都是创建了一个全新的 String 对象,以包含修改后的字符串内容。

§ 数组

java.util.Arrays 包含了许多其他有用的静态程序方法。

Arrays.copyOf()copyOfRange() 复制数组比 for 循环复制要快得多。

Arrays.asList() 返回的不是真正的 java.util.ArrayList,而是 Arrays 中的内部类 ArrayList,比如不支持 add() 等方法,

所以数组转换为 List 通常建议的做法是:

1
2
3
String[] stringArray = new String[] { "A", "B", "C", "D" }; 

List stringList = new ArrayList<>(Arrays.asList())