Java8基礎案例
阿新 • • 發佈:2017-12-18
兩個 opera 先來 etag require 默認方法 now() cal uri
類構造器引用
首先看個簡單的例子:
public class Car { public static Car create(final Supplier<Car> supplier) { return supplier.get(); } public void repair() { System.out.println("Repair: " + this.toString()); } } public class Main { public static void main(String[] args) { Car car = Car.create(Car::new); car.repair(); } }
Class::new 語法就是構造器引用
調用的是默認的構造函數。
類靜態方法引用
首先看下簡單的例子:
public class Car { public static Car create(final Supplier<Car> supplier) { return supplier.get(); } public static void collect(final Car car) { System.out.println("Collected " + car.toString()); } public void repair() { System.out.println("Repair: " + this.toString()); } } Arrays.asList(Car.create(Car::new), Car.create(Car::new)).forEach(Car::collect);
Car::collect 就是靜態方法引用的實現。
類方法引用和實例方法引用
首先來看一個簡單的例子:
類方法引用
Arrays.asList(Car.create(Car::new)).forEach(Car::repair);
實例方法引用
final Car car = Car.create(Car::new);
Arrays.asList(Car.create(Car::new)).forEach(car::repair);
很遺憾實例方法引用的編譯的時候報錯了。
類型推測機制
當使用範型類時編譯器可以自動推斷出確定的參數類型。
public class Value< T > { public static< T > T defaultValue() { return null; } } Java8寫法: Value.defaultValue() Java7寫法: Value<String>.defaultValue()
編譯器特性
字節碼中參數名字保留
先來看一個例子:
Method method = Main.class.getMethod("main", String[].class);
for (final Parameter parameter : method.getParameters()) {
System.out.println(" parameter : " + parameter.getName());
}
不開啟編譯器優化:
parameter : arg0
開啟編譯器優化:
parameter : args
處理空指針Optional
Integer a = null;
String b = "haha";
String c = null;
Optional<Integer> opA = Optional.ofNullable(a);
Optional<String> opB = Optional.ofNullable(b);
Optional<String> opC = Optional.ofNullable(c);
System.out.println("opA is null? " + (opA.isPresent() ? "否" : "是")); // 註意isPresent是反模式,即isNotNull的意思
System.out.println("opA : " + (opA.orElse(-1))); // print: -1
System.out.println("opB : " + (opB.orElseGet(() -> "none"))); // print: haha
System.out.println("opB : " + opB.map(s -> "jxp say:" + s).orElse("jxp say: none")); // opB : jxp say:haha
System.out.println("opC : " + opC.map(s -> "jxp say:" + s).orElse("jxp say: none")); // opB : jxp say:haha
Stream
forEach
首先看一個簡單的例子:
Arrays.asList("a", "b", "c").forEach(s -> System.out.println(s));
遍歷結果集並打印字符串
來看看forEach接口的定義:
package java.lang;
public interface Iterable<T> {
/**
* Performs the given action for each element of the {@code Iterable}
* until all elements have been processed or the action throws an
* exception. Unless otherwise specified by the implementing class,
* actions are performed in the order of iteration (if an iteration order
* is specified). Exceptions thrown by the action are relayed to the
* caller.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* for (T t : this)
* action.accept(t);
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
* @since 1.8
*/
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
}
可見接口上定義的是一個默認方法,這是jdk1.8的新特性,允許在接口上定義方式,這是集合類型最基礎的實現。
ArrayList也重寫了forEach方法:
package java.util;
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
@Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int expectedModCount = modCount;
@SuppressWarnings("unchecked")
final E[] elementData = (E[]) this.elementData;
final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) {
action.accept(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
}
filter
private static void useStreamFilter() {
List<User> users = Arrays.asList(
new User(1, "jiangxp", 10),
new User(2, "jiangyx", 13), new User(3,
"wanglf", 5));
List<User> filterUsers = users.stream().filter(s -> s.getAge() > 10).collect(Collectors.toList());
filterUsers.forEach(x -> System.out.println(x));
// filter 不會執行結果操作,而是將行為添加到stream提供的操作管線當中,只有執行最後的結果操作時,才會觸發filter行為。
}
parallel
private static void useStreamParallel() {
List<User> users = Arrays.asList(
new User(1, "jiangxp", 10),
new User(2, "jiangyx", 13), new User(3,
"wanglf", 5));
Integer totalAge = users.stream().parallel().map(s -> s.getAge()).reduce(0, Integer::sum);
System.out.println(totalAge);
// T reduce(T identity, BinaryOperator<T> accumulator);
// public static int sum(int a, int b) {
// return a + b;
// }
// 這兩個是如何關聯起來的?
}
collect
private static void useStreamCollectGroupBy() {
List<User> users = Arrays.asList(
new User(1, "jiangxp", 10),
new User(2, "jiangyx", 13), new User(3,
"wanglf", 10));
Map<Integer, List<User>> res = users.stream().collect(Collectors.groupingBy(s -> s.getAge()));
res.forEach((k, v) -> {
System.out.println(k);
v.forEach(s -> System.out.println(s));
});
}
Base64
在Java8中,Base64是一個標準庫
private static void useBase64() {
final String text = "我是中國人";
final String encoded = Base64.getEncoder().encodeToString(text.getBytes(StandardCharsets.UTF_8));
System.out.println(encoded);
final String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8);
System.out.println(decoded);
}
日期處理
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // 2017-07-06T10:38:35.043
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); // 2017-07-06
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); // 2017-07-06 10:38:35
String date = "2017-07-06";
LocalDate d1 = LocalDate.parse(date);
System.out.println(d1); // 2017-07-06
String date2 = "2017-07-06 10:38:35";
LocalDateTime d2 = LocalDateTime.parse(date2, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(d2); // 2017-07-06T10:38:35
參考資料
http://www.importnew.com/11908.html#NewFeatureOfLanguage
http://docs.oracle.com/javase/tutorial/java/javaOO/index.html
Java8基礎案例