Java8 Map 新增方法

Java8 中的 Map 接口新增了一批由 default 声明的默认方法。以下示例中列举了

  • getOrDefault(Object, V)
  • putIfAbsent(K, V)
  • remove(Object, Object)
  • replace(K, V)
  • replace(K, V, V)
  • replaceAll(BiFunction<? super K, ? super V, ? extends V>)
  • forEach(BiConsumer<? super K, ? super V>)
  • compute(K, BiFunction<? super K, ? super V, ? extends V>)
  • Map.Entry.comparingByValue() / Map.Entry.comparingByKey()

阅读更多

Java8 日期时间处理

在 Java8 之前,为了得到一个过去或未来的日期时间,我们往往需要组合 Date 和 Calendar 一起使用。不幸的是,这对组合并不那么好使,正所谓谁用谁知道,心照不宣吧。

Java8 中新增了一套全新的日期时间 API,它明确的将日期时间划分为 LocalDate、LocalTime 以及 LocalDateTime,分别用于表示日期、时间和日期时间,并且产生的结果是不可变的和线程安全的。

Month

月份在 Java8 中声明成了枚举类型,增强了代码的可读性和可靠性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 枚举类型
Month january = Month.JANUARY; // JANUARY
// 获取显示的名字
String displayName = january.getDisplayName(TextStyle.FULL, Locale.getDefault()); // 一月
// 月份+1, 得到的是2月份
Month february = january.plus(1); // FEBRUARY
// 2月份的天数最少的时候的值
int minDaysOfMonth = february.minLength(); // 28
// 2月份的天数最多的时候的值
int maxDaysOfMonth = february.maxLength(); // 29
// 获取2016年2月份的天数
int daysOfMonth = february.length(Year.isLeap(2016)); // 29
// 获取2月份表示的整数值
int februaryValue = february.getValue(); // 2
// 月份-2, 得到的是12月份
Month december = february.minus(2); // DECEMBER
// 用整数值构造月份, 1表示1月份, 4表示4月份...
Month april = Month.of(4); // APRIL

阅读更多

Java8 Stream

Java8 中新引入的 Stream 和以往的 I/O 流是完全不同的两个东西,Java8 中的 Stream 是对集合功能的增强,它结合 Java8 中新引入的 Lambda 表达式,可以使我们编写少量的代码就能够完成一些复杂的功能。

你可以对 Stream 进行两种操作,Intermediate 操作(中间操作)和 Terminal 操作(最终操作)。

Intermediate 操作是将修改后的 Stream 返回给调用方,因此,对一个 Stream 可以使用零个或多个 Intermediate 操作。

Terminal 操作是对 Stream 的最后一个操作,此后,该 Stream 无法再被操作,一个 Stream 只能有一个 Terminal 操作。

forEach

Terminal 操作,用于遍历元素。

1
2
3
4
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 3, 5, 2, 4, 6);
list.stream().forEach(System.out::print); // 135246
}

阅读更多

Java8 Optional

Optional 是 Java8 中新引入的一个类,它用于作为一个值可能为 null 或 non-null 的容器对象。如果一个方法的返回值是一个 Optional 类型,这是在向我们表明该方法的返回值可能为 null,调用时需要进行判空处理,这样可以有效的防止 NullPointerException 异常。如果通过调用 Optional.isPresent() 返回 true,则表明结果 non-null,此时可以放心调用 Optional.get() 获得此对象。

of

通过调用 Optional.of 可以构造一个 Optional 对象,参数要求是 non-null 值,否则抛出 NullPointerException 异常。

1
2
3
4
5
6
7
public static void main(String[] args) {
Optional<String> optional = Optional.of("foo");
if (optional.isPresent()) {
String result = optional.get();
System.out.println(result); // foo
}
}

阅读更多

Java8 Supplier

Supplier 是一个无参并返回一个任意类型值的函数式接口。

1
2
3
4
5
public static void main(String[] args) {
Supplier<Date> supplier = Date::new;
Date date = supplier.get();
System.out.println(date); // Fri Sep 16 00:20:19 CST 2016
}

阅读更多

Java8 Consumer

Consumer 是一个接收一个任意类型的参数并不产生任何结果的函数式接口。

1
2
3
4
public static void main(String[] args) {
Consumer<String> consumer = (s) -> System.out.println("The input string is : " + s);
consumer.accept("Hello Java8"); // The input string is : Hello Java8
}

阅读更多

Java8 Function

Function 是一个接收一个参数并返回一个任意类型值的函数式接口。

1
2
3
4
5
public static void main(String[] args) {
Function<String, Integer> function = (s) -> s.length();
Integer result = function.apply("foo");
System.out.println(result); // 3
}

使用 Function 提供的默认方法可以组合多个 Function 一起工作。

1
2
3
4
5
6
public static void main(String[] args) {
Function<String, Integer> function1 = (s) -> s.length();
Function<Integer, Boolean> function2 = (i) -> i > 5;
Boolean result = function1.andThen(function2).apply("foo");
System.out.println(result); // false
}

andThen 是比较常见的一种用法,工作时,先执行 function1 再执行 function2。

阅读更多

Java8 Predicate

Predicate 是一个接收一个参数并返回一个 boolean 类型值的函数式接口。它用于判断输入的参数对象是否符合某个特定的规则。

1
2
3
4
5
public static void main(String[] args) {
Predicate<Integer> predicate = (n) -> n % 2 == 0;
boolean result = predicate.test(8);
System.out.println(result); // true
}

除此之外,你还可以组合 Predicate 中提供的默认方法 or(或)、and(与)、negate(非)进行更加复杂的逻辑判断。

1
2
3
4
5
public static void main(String[] args) {
Predicate<Integer> predicate = (n) -> n % 2 == 0;
boolean result = predicate.negate().test(8);
System.out.println(result); // false
}

阅读更多

Java8 方法引用

在了解 Lambda 表达式之后,我们来看这样一段代码:

1
2
3
4
5
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 3, 5, 2, 4, 6);
Collections.sort(list, (o1, o2) -> o1.compareTo(o2));
System.out.println(list); // [1, 2, 3, 4, 5, 6]
}

如果 Lambda 表达式中仅仅是调用了一个已存在的方法,在 Java8 中,可以使 :: 关键字来替代 Lambda 表达式。

关键字 :: 可以用来引用一个方法或构造器,这种特性称为方法引用。

1
2
3
4
5
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 3, 5, 2, 4, 6);
Collections.sort(list, Integer::compareTo);
System.out.println(list); // [1, 2, 3, 4, 5, 6]
}

阅读更多

Java8 Lambda 表达式

在 Java8 之前,当实现只有一个方法的接口,我们通常是通过使用匿名内部类的方式来重写接口的方法,以 Comparator 为例:

1
2
3
4
5
6
7
8
List<Integer> list = Arrays.asList(1, 3, 5, 2, 4, 6);
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
System.out.println(list); // [1, 2, 3, 4, 5, 6]

Java8 中引入了 Lambda 表达式,提供了更加简洁的语法:() -> {}

1
2
3
4
5
List<Integer> list = Arrays.asList(1, 3, 5, 2, 4, 6);
Collections.sort(list, (Integer o1, Integer o2) -> {
return o1.compareTo(o2);
});
System.out.println(list); // [1, 2, 3, 4, 5, 6]

阅读更多

Java8 接口默认方法

在 Java8 中,接口也可以为方法提供默认的实现,即,接口也可以有自己的实现方法,具体的做法是使用关键字 default 即可为接口声明一个默认的方法。

1
2
3
4
5
6
7
8
9
interface Predators {
void doSomething();
default void eat() {
System.out.println("eat meat");
}
}

阅读更多

网络爬虫

Crawler4j 是一个开源的 Java 类库提供一个用于抓取 Web 页面的简单接口。可以利用它来构建一个多线程的 Web 爬虫。

阅读更多

基于 memcached 的 tomcat 集群之 session 共享

实现在多台服务器之间共享 session 会话中的数据。

阅读更多

基于 POI 和反射机制实现通用写出 Excel 文档文件

分享一个基于 POI 和反射机制实现的通用的写出 Excel 文档文件工具类,及简写出数据到 Excel 文档

阅读更多

基于 POI 和反射机制实现通用读取 Excel 表格数据

分享一个基于 POI 和反射机制实现的通用的读取 Excel 表格数据工具类,读取 Excel 表格数据只需 2 行代码

阅读更多