Java 8 你需要掌握的新特性 5、杂项
5.1 字符串
Java 8 中,String类只添加了一个方法:join,作用是按照指定分隔符将多个字符串组合起来,可以认为它是split方法的反操作。
String joined = String.join("/", "usr", "local", "bin");
System.out.println(joined);
String[] ids = {"1", "3", "6"};
System.out.println(String.join(",", ids));
// 输出结果是
// usr/local/bin
// 1,3,6
5.2 集合
集合类最大的改变就是支持流操作。另外,还添加了其它一些有用的方法。
类/接口 | 新方法 |
---|---|
Iterable | forEach |
Collection | removeIf |
List | replaceAll, sort |
Map | forEach, replace, replaceAll, remove(key, value), putIfAbsent, compute, computeIfAbsent, computeIfPresent, merge |
Iterator | forEachRemaining |
其中大部分方法都能直接看出用途,只有compute*、merge、forEachRemaining比较陌生,简单介绍一下这几个方法:
1、compute
通过key和一个函数计算出新的值
Map<String, String> map = new HashMap<>();
map.put("key", "value");
System.out.println(map.compute("key", String::concat)); // 输出 keyvalue
2、merge
合并value,如果key不存在,使用给定的值作为value。与compute不同的是merge不处理key, eg:计数,如果存在key,+1;如果不存在,赋值为1
Map<String, Integer> map = new HashMap<>();
map.merge("key", 1, (i1, i2) -> i1 + i2);
System.out.println(map.get("key")); // 输出 1
map.merge("key", 1, (i1, i2) -> i1 + i2);
System.out.println(map.get("key")); // 输出 2
3、forEachRemaining
能够将Iterator中迭代剩余的元素传递给一个函数,eg:
List<String> list = Arrays.asList("a", "b", "c", "d", "e");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if ("c".equals(it.next())){
break;
}
}
it.forEachRemaining(s -> System.out.print(s + " ")); // 输出 d e
5.3 比较器
Comparator接口新增comparing方法,该方法接收一个函数,函数的返回值就是用于比较的对象。同时,支持多级比较。
// 先按照name进行排序,如果name一样,按照age排序
public static void main(String[] args) {
Person[] ps = {new Person("a", 20), new Person("b", 20), new Person("a", 18)};
Arrays.sort(ps, Comparator.comparing(Person::getName).thenComparing(Person::getAge));
System.out.println(Arrays.asList(ps)); // 输出 [Person{name='a', age=18}, Person{name='a', age=20}, Person{name='b', age=20}]
}
private static class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 省略get set
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
ps:Comparator接口还有其它的一些使用方式,就不一一列举了。
5.4 Base64 编码
Base64 编码是一种将非ASCII字符转为ASCII字符的编码方式,主要用于转换字节数组成为可打印的字符序列。在之前的版本,JDK 中提供了 sun.misc.BASE64Encoder 这个类,但是sun.misc 这个包是SUN公司的实现,并非J2SE规范的实现,而且BASE64Encoder 没有任何文档说明,所以我们一般会自己实现或使用第三方实现。终于,Java 8 提供了一个标准的编码器和解码器。
/*
* 三种编码器:
* 1、常规Base64编码器,没有换行
* 2、电子邮件是用的MIME标准编码器,每76个字符使用一个"\r\n"换行符
* 3、对URL和文件名安全的编码器,使用“-”和“_”替换“+”和“/”
*/
Base64.getEncoder();
Base64.getMimeEncoder();
Base64.getUrlEncoder();
5.5 Null 检查
Objects类新增了两个静态的断言(pridicate)方法,isNull 和 nonNull,这两个方法在使用流的时候非常实用。例如
stream.anyMatch(Objects::isNull); // 检查一个流是否含有null值
stream.filter(Objects::nonNull); // 获取所有非null的对象
5.6 JDBC
在Java 8 中,JDBC 已经升级到了4.2版本,该版本为 java.sql 包中的 Date、Time 和 Timestamp 类提供了一些方法,可以与 java.time 包中对应的 LocalDate、LocalTime 和 LocalDateTime 类互相进行转换。
Date date = new java.sql.Date(System.currentTimeMillis());
Instant instant = date.toInstant();
LocalDate localDate = date.toLocalDate();