一、核心函数式接口
(1)、Consumer
消费型接口 ,传递参数,使用参数做一个处理。没有返回值
底层源码
@FunctionalInterface
public interface Consumer<T> {
void accept(T var1);
default Consumer<T> andThen(Consumer<? super T> var1) {
Objects.requireNonNull(var1);
return (var2) -> {
this.accept(var2);
var1.accept(var2);
};
}
}
案例
public static void main(String[] args) {
String str = "Hello World";
Consumer<String> consumer = (String s) -> {
str.length();
};
consumer.accept(str);
}
//======================================
public static void main(String[] args) {
String str = "Hello world";
Consumer<String> c1 = ((String s1 )-> System.out.println(s1.length()));
Consumer<String> mc1 = (String s1)->{
System.out.println(s1.length());
};
Consumer<String> mc2 = (String s1)->{
System.out.println(s1.toUpperCase());
};
Consumer<String> mc3 = s1->{
System.out.println(s1.substring(0,5));
};
// mc2.accept(str);
mc1.andThen(mc2.andThen(mc3)).accept(str);
(2)、Supplier
供给型接口, 无需要传递参数,返回对象
底层源码
@FunctionalInterface
public interface Supplier<T> {
T get();
}
案例
public static void main(String[] args) {
Supplier<Integer> supplier = ()->{
return new Random(10).nextInt();
};
int random = supplier.get();
System.out.println(random);
}
(3)、Function
功能型接口,需要传递参数,根据参数做处理,将处理结果返回
底层源码
@FunctionalInterface
public interface Function<T, R> {
R apply(T var1);
default <V> Function<V, R> compose(Function<? super V, ? extends T> var1) {
Objects.requireNonNull(var1);
return (var2) -> {
return this.apply(var1.apply(var2));
};
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> var1) {
Objects.requireNonNull(var1);
return (var2) -> {
return var1.apply(this.apply(var2));
};
}
static <T> Function<T, T> identity() {
return (var0) -> {
return var0;
};
}
}
案例
String s = "Hello World" ;
//需要实现功能,将字符串转换成大小
Function<String,String> f1 = (String s1)->{
System.out.println("1操作");
return s1.toUpperCase();
};
//System.out.println( f1.apply(s) );
Function<String,String> f2 = s1->{
System.out.println("2操作");
return s1.substring(0,3);
};
//f1处理后,再进行一次f2的处理
//System.out.println( f1.andThen(f2).apply(s) );
//f1处理前,先进行一次f2的处理
System.out.println( f1.compose(f2).apply(s) );
(4)、Predicate
断言型接口,传递参数,根据参数做判断,返回boolean
底层源码
@FunctionalInterface
public interface Predicate<T> {
boolean test(T var1);
default Predicate<T> and(Predicate<? super T> var1) {
Objects.requireNonNull(var1);
return (var2) -> {
return this.test(var2) && var1.test(var2);
};
}
default Predicate<T> negate() {
return (var1) -> {
return !this.test(var1);
};
}
default Predicate<T> or(Predicate<? super T> var1) {
Objects.requireNonNull(var1);
return (var2) -> {
return this.test(var2) || var1.test(var2);
};
}
static <T> Predicate<T> isEqual(Object var0) {
return null == var0 ? Objects::isNull : (var1) -> {
return var0.equals(var1);
};
}
案例
public static void main(String[] args) {
User user = new User("zn","123");
Predicate<User> predicate = (User user1) ->{
return user1.uname.equals("zn") && user1.upass.equals("123");
};
predicate.test(user);
}
(5)、扩展: BiFunction
可以进行计算
底层源码:
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T var1, U var2);
default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> var1) {
Objects.requireNonNull(var1);
return (var2, var3) -> {
return var1.apply(this.apply(var2, var3));
};
}
}
案例
public static void main(String[] args) {
BiFunction<Integer,Integer,Integer> bi = (a,b) -> {
return a+b;
};
System.out.println(bi.apply(5,10));
}
二、Stream
获取流
list.stream();
set.stream();
collection.stream();
//================
Stream.of(1,2,3,4,5);
//====================================
//获取limit方法中传入的参数个
Stream.generate(()->"Hello").limit(100);
//============================================
//第一个参数是新流中的初始元素,
//然后使用该数据做第二个参数也就是UnaryOperator函数的入参去计算第二元素,
//然后把新计算得到的第二个元素作为入参继续计算第三个元素,以此循环可以制造无限个元素
Stream.iterate(1,(i)->++i).limit(100)
终端操作
这种操作会产生一个结果的,如果一个流被消费过了,那它就不能被重用的。
forEach()
public static void main(String[] args) {
List<Car> cars = Arrays.asList(
new Car("宝马","蓝色",300000),
new Car("奔驰","黑色",400000),
new Car("奥迪","红色",450000),
new Car("保时捷","蓝色",600000),
new Car("本田","白色",2000000),
new Car("比亚迪","白色",220000),
new Car("理想","黑色",250000)
);
cars.stream().forEach(car -> System.out.println(car));
// -------------- 等价于 ----------->
cars.stream().forEach(System.out::println);
}
count
long count = cars.stream().count();
System.out.println(count);
max,min
Optional<Car> max = cars.stream().max((car1, car2) -> car1.getPrice() - car2.getPrice());
System.out.println(max.toString());
Optional<Car> max = cars.stream().min((car1, car2) -> car1.getPrice() - car2.getPrice());
System.out.println(min.toString());
汇总
IntSummaryStatistics collect = cars.stream().collect(
Collectors.summarizingInt(car -> car.getPrice()));
System.out.println(collect);
分组
Map<String, List<Car>> collect1 = cars.stream().collect(Collectors.groupingBy(car ->car.getColor()));
System.out.println(collect1);
中间操作
中间操作可以用来创建执行一系列动作的管道。
中间操作不是立即发生的。相反,当在中间操作创建的新流上执行完终端操作后,中间操作指定的操作才会发生。所以中间操作是延迟发生的,中间操作的延迟行为主要是让流API能够更加高效地执行。
filter
cars.stream()
.filter(car->"黑色".equals(car.color))
.forEach(System.out::println);
map
cars.stream().map(car -> {
return new Car(car.getName(), car.getPrice());
}).forEach(System.out::println);
sorted()
//排序
cars.stream()
.sorted((c1,c2)->c1.price-c2.price)
.forEach(System.out::println);
limit() & skip()
//分页,从那条记录开始,取几条记录, 从0开始取3条(0,1,2),从3开始取3条(3,4,5),从6开始取3条(7,8,9)
cars.stream()
.sorted((c1,c2)->c1.price-c2.price)
.skip(4) //跳过几个,因为时从0开始条,这个条过几个,也可以理解为从第几个开始
.limit(3)
.forEach(System.out::println);