Java8 入门
Lambda 表达式
Lambda Expression:匿名函数,闭包。
闭包的书写格式:
// 单条表达式语句
(args)->expression
// 多条表达式语句
(args)->{
expression;
expression;
}
示例:
import java.util.function.BiFunction;
import java.util.function.Function;
import org.junit.Test;
public class LambdaTest {
// 没有参数没有返回值的lambda
@Test
public void testRunnable() {
Runnable runnable = () -> System.out.println("this is a Runnable1!");
new Thread(runnable).start();
runnable = () -> {
System.out.println("this is a Runnable2!");
};
new Thread(runnable).start();
runnable = () -> {
String x = "this is a Runnable3!";
System.out.println(x);
};
new Thread(runnable).start();
runnable = this::printlnNow;
new Thread(runnable).start();
new Thread(() -> System.out.println("this is a Runnable1!")).start();
new Thread(() -> {
System.out.println("this is a Runnable2!");
}).start();
new Thread(() -> {
System.out.println("this is a Runnable2!");
}).start();
new Thread(() -> {
String x = "this is a Runnable3!";
System.out.println(x);
}).start();
new Thread(this::printlnNow).start();
}
// 一个参数有返回值的lambda
@Test
public void testFunction() {
Function<String, Integer> function = (input) -> Integer.valueOf(input);
System.out.println(function.apply("1234"));
function = input -> Integer.valueOf(input);
System.out.println(function.apply("1234"));
function = Integer::valueOf;
System.out.println(function.apply("1234"));
function = input -> {
input = input + "";
return Integer.valueOf(input);
};
System.out.println(function.apply("1234"));
}
// 多个参数有返回值的lambda
@Test
public void testBiFunction() {
BiFunction<Integer, Integer, Integer> biFunction = (a, b) -> Math.min(a, b);
// biFunction = a, b -> Math.min(a, b); // error
System.out.println("min value is : " + biFunction.apply(1, 2));
biFunction = Math::max;
System.out.println("max value is : " + biFunction.apply(1, 2));
}
public void printlnNow() {
System.out.println("now is " + System.currentTimeMillis());
}
}
方法引用
- 类静态方法引用
ClassName::methodName
- 实例上的实例方法引用
instanceReference::methodName
- 类型上的实例方法引用
Class::methodName
- 构造方法引用
Class::new
- 数组构造方法引用
TypeName[]::new
示例:
Supplier<Long> supplie = System::currentTimeMillis;
System.out.println("current time millis : " + supplie.get());
Consumer<String> consumer = System.out::println;
consumer.accept("this is a string");
Supplier<Date> supplier = Date::new;
System.out.println(supplier.get());
/// 类型上的实例方法引用
Function<Date, Integer> function1 = Object::hashCode;
Function<Date, Integer> function2 = Date::hashCode;
function1.apply(new Date());
function2.apply(new Date());
默认方法
使用默认方法可以再接口里增加新行为并且与老的代码保持兼容[原来的实现类不需要修改]。
public interface DefaultFormat {
static long previousDayimTeMillis() {
return System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1);
}
default String format() {
return "yyyy-MM-dd HH:mm:ss.SSS";
}
}
一个接口继承一个包含默认方法的接口时:
- 直接继承方法
- 重新声明方法
- 实现默认方法
public interface DefaultFormat1 extends DefaultFormat {
}
public interface DefaultFormat2 extends DefaultFormat {
String format();
}
public interface DefaultFormat3 extends DefaultFormat {
default String format() {
return "yyyy-MM-dd";
}
}
抽象类和接口区别???
多继承???
Function and FunctionalInterface
- java.util.function包下提供了一些函数
Function<T, R> // 转换
Consumer<T> // 消费
Predicate<T> // 判断
Supplier<T> // 供给
BiFunction<T, U, R>
BiConsumer<T, U>
BiPredicate<T, U>
//-----------------//
//-----------------//
Function<String, Integer> function = Integer::valueOf;
Consumer<String> consumer = System.out::println;
Predicate<String> predicate = StringUtils::isBlank;
Supplier<Long> supplier = System::currentTimeMillis;
BiFunction<Integer, Integer, Integer> biFunction = Math::min;
BiConsumer<String, String> biConsumer = (a, b) -> System.out.println(a + " and " + b);
BiPredicate<String, String> biPredicate = Objects::equals;
-
@FunctionalInterface
函数式接口
示例:
@FunctionalInterface
public interface MyInterface {
void call();
}
// 没有抽象方法,无法编译
// @FunctionalInterface
// public interface MyInterface1 {
// }
// @FunctionalInterface
// public interface MyInterface2 {
// default void call() {
// }
// }
@FunctionalInterface
public interface MyInterface3 {
default void call() {
}
void tell();
}
// 多于一个抽象方法,无法编译
// @FunctionalInterface
// public interface MyInterface4 {
//
// void call();
//
// void tell();
// }
@FunctionalInterface
public interface MyInterface5 {
void call();
// 与Object类中定义的方法一样
String toString();
int hashCode();
boolean equals(Object x);
}
函数式接口
是指仅仅只包含一个抽象方法的接口- 该注解只能标记在”有且仅有一个抽象方法”的接口上。
- JDK8接口中的静态方法和默认方法,都不算是抽象方法.
- 接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。
- 该注解不是必须的.不加该注解,如果接口符合函数式接口定义,也可以。该注解只是让编译器对函数式接口进行规范性检查。
Stream API
List<Integer> numbers = Arrays.asList(7, 7, 8, 9, 9, 1, 2, 3, 4, 5, 6, 7);
// distinct 去重复
System.out.println(numbers.stream().distinct().collect(Collectors.toList()));
// skip 丢弃前n个
System.out.println(numbers.stream().skip(1).collect(Collectors.toList()));
// limit
System.out.println(numbers.stream().limit(1).collect(Collectors.toList()));
// filter 过滤
System.out.println(numbers.stream().filter((i) -> i % 2 == 0).collect(Collectors.toList()));
// map 转换
System.out.println(numbers.stream().map((i) -> i * 10).collect(Collectors.toList()));
// flatMap
System.out.println(Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6), Arrays.asList(7, 8, 9))
.stream().flatMap(list -> list.stream().map(i -> i * 10)).collect(Collectors.toList()));
// sorted
System.out.println(numbers.stream().map((i) -> i * 10).sorted().collect(Collectors.toList()));
// peek
numbers.stream().peek(System.out::println).sorted().peek(i -> System.out.println("peek:" + i))
.collect(Collectors.toList());
// min
System.out.println(numbers.stream().min(Integer::compare).get());
// max
System.out.println(numbers.stream().max(Integer::compare).get());
// count
System.out.println(numbers.stream().filter(i -> i % 3 == 0).count());
// match
numbers.stream().anyMatch(i -> i % 2 == 0);
numbers.stream().allMatch(i -> i > 0);
numbers.stream().noneMatch(i -> i > 10);
System.out.println(numbers.stream().map(i -> i * 10).reduce((a, b) -> a + b).get());
numbers.stream().forEach(System.out::println);
numbers.forEach(System.out::println);