1.接口与Lambda 表示式
函数式接口(FunctionalInterface): 就是只包含一个抽象方法的声明,用@FunctionalInterface表示, 常见的有Comparator, Predicate, Function, Supplier, Consumer,只有函数式接口才能缩写成 Lambda 表示式
@FunctionalInterface
interface HelloDemo {
public abstract void sayHi();
// 接口内可以定义默认方法, 默认方法不算抽象方法,因为它有方法体
public default void sayGood() {
System.out.println("you are so good ...");
}
// 接口内可以定义静态方法
public static void sayGoodAndHi() {
System.out.println("hi, you are so good ..");
}
}
class HelloEveryOne implements HelloDemo {
@Override
public void sayHi() {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
// 默认方法不强制实现,实现类能够直接使用
HelloEveryOne helloEveryOne = new HelloEveryOne();
helloEveryOne.sayGood();
// lambda表达式常见用法
HelloDemo helloDemo = (() -> System.out.println("haha ++++++++++++++")); // 重写sayHi方法
helloDemo.sayHi();
List<String> list = Arrays.asList("a", "c", "b");
list.sort((a, b) -> a.compareTo(b)); // 升序
list.forEach(a -> System.out.println(a));
list.forEach(System.out::println); // 使用::调用静态方法
}
}
2.Predicate
Predicate: 是一个可以指定入参类型,并返回 boolean 值的函数式接口。它内部提供了一些带有默认实现的方法,可以被用来组合一个复杂的逻辑判断(and, or, negate)
// and 相当于 && 能断路
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
Predicate<String> predicate = (s) -> s != null;
Predicate<String> predicate2 = (s) -> !s .equals("");
Predicate<String> predicate3 = predicate.and(predicate2);
boolean flag = predicate3.test(null);
// or 相当于 || 能断路
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
Predicate<String> predicate = (s) -> s != null;
Predicate<String> predicate2 = (s) -> !s.equals("");
Predicate<String> predicate3 = predicate.or(predicate2);
boolean flag = predicate3.test(null);
// negate 相当于 !
default Predicate<T> negate() {
return (t) -> !test(t);
}
Predicate<String> predicate2 = (s) -> s.equals("");
boolean flag = predicate2.negate().test("a");
// isEqual判断两个值是否相等
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef) ? Objects::isNull
: object -> targetRef.equals(object);
}
boolean flag = Predicate.isEqual(null).test("");
3.Function
Function: 对元素进行功能处理,如:类型转换,字母大小写切换
Function<String, Integer> toInteger = Integer::valueOf;
Function<String, String> toUpperCase = String::toUpperCase;
Function<String, String> backToString = toInteger.andThen(String::valueOf);
Function<String, Integer> composeToString =toInteger.compose(String::valueOf);
// apply() 调用当前Function函数接口并传入参数,返回结果
String a = backToString.apply("123"); // "123"
Integer b = composeToString.apply("123"); // 123
// 先执行传入的Function函数接口,然后再执行当前Function函数接口
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
// 先执行当前Function函数接口,然后再执行传入的Function函数接口
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
// 产生一个输入参数类型与输出参数类型相同的Function函数接口
static <T> Function<T, T> identity() {
return t -> t;
}
// 将String转成Integer
ToIntFunction<String> toIntFunction = Integer::parseInt;
int c = toIntFunction.applyAsInt("2");
// 将String转成Long
ToLongFunction<String> toLongFunction = Long::parseLong;
long d = toLongFunction.applyAsLong("43");
// 将String转成Double
ToDoubleFunction<String> toDoubleFunction = Double::parseDouble;
double f = toDoubleFunction.applyAsDouble("5");
4.Supplier
Supplier生产者: 它不接受入参,直接为我们生产一个指定的结果
// 调用TestJava类的构造方法生成对象
Supplier<TestJava> personSupplier = TestJava::new;
TestJava testJava = personSupplier.get();
// 调用TestJava类的getMessage方法
Supplier<String> supplier = TestJava::getMessage;
// 获得getMessage的返回值
System.out.println(supplier.get());
5.Consumer
Consumer消费着:接受入参,用来被消费
lass HelloEveryOne {
private String firstName;
private String lastName;
private int age;
private int classId;
/**
* @return the age
*/
public int getAge() {
return age;
}
/**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
}
/**
* @return the classId
*/
public int getClassId() {
return classId;
}
/**
* @param classId the classId to set
*/
public void setClassId(int classId) {
this.classId = classId;
}
/**
* @return the firstName
*/
public String getFirstName() {
return firstName;
}
/**
* @param firstName the firstName to set
*/
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* @return the lastName
*/
public String getLastName() {
return lastName;
}
/**
* @param lastName the lastName to set
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
public HelloEveryOne() {
}
public HelloEveryOne(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public HelloEveryOne(int age, int classId, String firstName, String lastName) {
this.age = age;
this.classId = classId;
this.firstName = firstName;
this.lastName = lastName;
}
public String say() {
return "say";
}
}
Consumer<HelloEveryOne> greeter = (p) -> System.out.println("Hello, " + p.getFirstName());
Consumer<HelloEveryOne> greeter2 = (p) -> System.out.println("Hello, " + p.getLastName());
// 传入参数并调用该Consumer定义的方法
greeter.accept(new HelloEveryOne("Luke", "Skywalker"));
// 先调用当前Consumer定义的方法,然后调用andThen里面Consumer定义的方法
greeter.andThen(greeter2).accept(new HelloEveryOne("Luke", "Skywalker"));
6.Comparator
Comparator<HelloEveryOne> comparator = (p1, p2) -> p1.getFirstName().compareTo(p2.getFirstName());
HelloEveryOne p1 = new HelloEveryOne(2, 1, "John", "Doe");
HelloEveryOne p2 = new HelloEveryOne(2, 2, "Alice", "Wonderland");
int a = comparator.compare(p1, p2); // 相当于p1.getFirstName().compareTo(p2.getFirstName), 返回两个参数相差多少
int b = comparator.reversed().compare(p1, p2); // 相当于p2.getFirstName().compareTo(p1.getFirstName), 返回两个参数相差多少
Comparator<HelloEveryOne> ageComparator = (p3, p4) -> p3.getAge() - p4.getAge();
Comparator<HelloEveryOne> classIdComparator = (p5, p6) -> p5.getClassId() - p6.getClassId();
// 先比较年龄,如果年龄相同,再继续比较班级id
int c = ageComparator.thenComparing(classIdComparator).compare(p1, p2);
System.out.println(c); // 结果: -1
// 先将比较的值类型转换,然后再比较
default <U extends Comparable<? super U>> Comparator<T> thenComparing(
Function<? super T, ? extends U> keyExtractor)
{
return thenComparing(comparing(keyExtractor));
}
// 先将比较的值转成int,然后再比较
default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor) {
return thenComparing(comparingInt(keyExtractor));
}
// 先将比较的值转成long,然后再比较
default Comparator<T> thenComparingLong(ToLongFunction<? super T> keyExtractor) {
return thenComparing(comparingLong(keyExtractor));
}
// 先将比较的值转成double,然后再比较
default Comparator<T> thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) {
return thenComparing(comparingDouble(keyExtractor));
}
// 用于处理比较值为null情况下,避免抛出异常
// 如果第一个值为null,第二个值不为null,返回-1
// 如果第一个值不为null,第二个值为null,返回1
// 如果两个值都为null,返回0
// 如果比较器为null,返回0,其他情况按compare()比较
public static <T> Comparator<T> nullsFirst(Comparator<? super T> comparator) {
return new Comparators.NullComparator<>(true, comparator);
}
// 如果第一个值为null,第二个值不为null,返回1
// 如果第一个值不为null,第二个值为null,返回-1
// 如果两个值都为null,返回0
// 如果比较器为null,返回0,其他情况按compare()比较
public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
return new Comparators.NullComparator<>(false, comparator);
}
NullComparator(boolean nullFirst, Comparator<? super T> real) {
this.nullFirst = nullFirst;
this.real = (Comparator<T>) real;
}
@Override
public int compare(T a, T b) {
if (a == null) {
return (b == null) ? 0 : (nullFirst ? -1 : 1);
} else if (b == null) {
return nullFirst ? 1: -1;
} else {
return (real == null) ? 0 : real.compare(a, b);
}
}
7.Optional
Optional.ofNullable(T value): 能传null值
Optional.of(T value): 不能传null值,否则会报NullpointerException
Optional<String> optional = Optional.ofNullable(null);
// 判断optional的值是否不为null
boolean isNotNull = optional.isPresent();
// 获取optional的值,如果为null,会报NoSuchElementException
String value = optional.get();
// 如果optional的值为null,会返回other,否则会返回optional的值
String defaultValue = optional.orElse("fallback");
8.Stream
实现了Collection接口才有stream(), Map没有
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("1");
list.add("4");
Stream<String> stringStream = list.stream();
// 根据条件过滤
Predicate<String> predicate = s -> s.equals("a");
stringStream.filter(predicate.or(s -> s.equals("c"))).forEach(System.out::println);
stringStream.filter(s -> s.equals("d")).forEach(System.out::println);
// map():对每一个元素做功能处理,如:类型转换 mapToInt mapToLong mapToDouble
stringStream.map(Integer:: valueOf).forEach(System.out::println);
List<String> list1 = new ArrayList<>();
list1.add("4");
list1.add("5");
Map<String, List<String>> map = new HashMap<>();
map.put("list", list);
map.put("list1", list1);
Map<String, List<Integer>> map1 = new HashMap<>();
// flatMap():将多个list合并到一个list flatMapToInt flatMapToLong flatMapToDouble
map.values().stream().flatMap(l -> l.stream()).forEach(System.out::println);
map.values().stream().flatMapToInt(l -> l.stream().mapToInt(Integer::parseInt)).forEach(System.out::println);
map.values().stream().flatMapToLong(l -> l.stream().mapToLong(Long::parseLong)).forEach(System.out::println);
map.values().stream().flatMapToDouble(l -> l.stream().mapToDouble(Double::parseDouble)).forEach(System.out::println);
// distinct():将list中的元素去重
list.stream().distinct().forEach(System.out::println);
// sorted():升序排列
list.stream().sorted().forEach(System.out::println);
list.stream().sorted(((a, b) -> (b.compareTo(a)))).forEach(System.out::println);
// peek():为集合中的元素添加功能行为
list.stream().filter(e -> e.equals("1"))
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
// limit(): 控制返回结果条数,和mongodb数据库的limit意义一样
list.stream().filter(e -> !e.equals("2")).limit(2).forEach(System.out::println);
// skip(): 跳过多少条,和mongodb数据库的skip意义一样
list.stream().skip(1).forEach(System.out::println);
// for循环 :
forEach(Consumer<? super T> action)
forEachOrdered(Consumer<? super T> action);
stringStream.forEach((s) -> System.out.println("ooo " +s));
stringStream.forEachOrdered((s) -> System.out.println("ooo " +s));
// Object[] toArray();
toArray(IntFunction<A[]> generator)
List<Integer> intList = Arrays.asList(1, 3, 5);
Integer[] array = intList.stream().toArray(Integer[]::new);
int[] arr = intList.stream().mapToInt(Integer::new).toArray();
String[] stringArr = stringStream.toArray(String[]::new);
reduce(T identity, BinaryOperator<T> accumulator);
reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner)
reduce(BinaryOperator<T> accumulator)
int sum = intList.stream().reduce(0, Integer::sum);
intList.stream().reduce((a, b) -> a*b).ifPresent(System.out::println);
// 注意:它们的计算结果必须和stream中的元素类型相同,如上面的代码示例,stream中的类型为int,那么计算结果也必须为int,这导致了灵活性的不足,甚至无法完成某些任务, 比入我们咬对一个一系列int值求和,但是求和的结果用一个int类型已经放不下,必须升级为long类型,此实第三签名就能发挥价值了,它不将执行结果与stream中元素的类型绑死。
long result = intList.stream().reduce(0L,(a,b) -> a + b, (a,b)-> 0L );
List<Integer> numList = Arrays.asList(1, 2, 3, 4, 5, 6);
ArrayList<String> result2 = numList.stream().reduce(new ArrayList<String>(), (a, b) -> {
a.add("element-" + Integer.toString(b));
return a;
}, (a, b) -> null);
collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner);
collect(Collector<? super T, A, R> collector)
// 将list转set
Set<String> set = stringStream.collect(Collectors.toSet());
// 生成新的list
List<String> newList = stringStream.collect(Collectors.toList());
// 将元素等于“1”的分成一组,其他分成一组
stringStream.collect(Collectors.groupingBy(a -> a.equals("1")));
// 将集合分割成两部分,true为等于“1”的元素, false为不等于“1”的元素
Map<Boolean, List<String>> resultMap = stringStream.collect(Collectors.partitioningBy(a -> a.equals("1")));
// 将list以,拼接生成字符串
String res = stringStream.collect(Collectors.joining(","));
// 获取并行流: 并行流是通过多线程来处理的,能够充分利用多核CPU 的优势,处理速度更快。
list.parallelStream();
// 统计集合元素个数
long res = list.stream.count();