1.Lambda
Lambda表达式本身就是对接口的实现。
- 最直观的作用就是使代码变得简洁。
public class Test {
public static void main(String[] args) {
Comparator comparator = (int a,int b) -> {
return a-b;
};//全格式基本语法
int com = comparator.compar(4,6);
System.out.println(com);
}
}
interface Comparator{
int compar(int a ,int b);
}
lambda类似匿名函数,lambda可以对接口进行简单的实现,但不是所有接口可以用lambda实现。
- 抽象方法只有一个
符号 | 含义 |
---|---|
() | 用来描述参数列表 |
{} | 用来表示方法体 |
-> | Lambda运算符 读作 goes to |
-
由于在接口的抽象方法中,已经定义了参数的数量和类型,所以 可以将参数的类型可以省略(如果需要省略参数类型,则每个参数的类型都要省略)。
-
如果参数列表中,参数的数量只有一个,此时小括号可以省略。
-
方法大括号:如果方法体中只有一条语句时,大括号可以省略。
-
如果方法体中唯一的一条语句是一个返回语句,return也可以省略。
以上面的代码为例,省略类型,小括号,大括号,return
public class Test {
public static void main(String[] args) {
Comparator comparator = (a, b) -> a-b;
int com = comparator.compar(4,6);
System.out.println(com);
}
}
interface Comparator{
int compar(int a ,int b);
}
方法的隶属者 ::方法名(参数类型和接口一致)
可以快速将一个Lambda表达式指向一个已经实现的方法。
public class Test {
public static void main(String[] args) {
Fa fa = a -> change(a);//a是传参
System.out.println(fa.test(2));
Fa fa2 = Test::change;
System.out.println(fa2.test(2));
}
public static int change(int a){
return 2 * a;
}
}
interface Fa{
int test(int d);
}
2.Lambda优化日志
Lambda作为参数,可以优化参数
@FunctionalInterface 函数式接口的意思,使用这个注解,即为只有一个函数的抽象类,即可以使用Lambda
public void Log{
public static void Log(int level, String s){
if(level == 1){//只有level等于1才可以输出
System.out.println(s);
}
}
public static void main(String[] args){
String s1 = "Hellow";
String s2 = "World";
String s3 = "Java";
Log(2, s1 + s2 + s3);
//此方法不会输出,但是会进行字符串的拼接,浪费了性能
showLog(2, () -> {
return s1 + s2 + s3;
});//此方法不会输出,但是不会进行字符串的拼接
}
}
interface showlog(){
String showLog();
}
3.函数式接口
3.1 Supplier接口
接口方法 T get()
Supplier被称之为生产型接口,使用接口的泛型是什么,返回什么类型
package it;
import java.util.function.Supplier;
public class DemoSupplier {
public static String getString(Supplier<String> sup){
return sup.get();
}
public static void main(String[] args) {
String s = getString(() -> "dasdjdiaj");
System.out.println(s);
}
}
3.2 Consumer接口
接口方法 accept(T t)
消费一个数据
package it;
import java.util.function.Consumer;
public class DemoConsumer {
public static void method(String name, Consumer<String> con){
con.accept(name);
}
public static void main(String[] args) {
method("zfjsdf", name ->{//反转字符串
System.out.println(new StringBuilder(name).reverse().toString());
});
}
}
3.3 andThen接口
接口方法:andThen
需要两个Consumer接口,连接在一起,在进行消费
package it;
import java.util.function.Consumer;
public class DemoAndThen {
public static void method(String s, Consumer<String> con1, Consumer<String> con2){
// con1.accept(s);
// con2.accept(s);
con1.andThen(con2).accept(s);
}
public static void main(String[] args) {
method("Hello",t ->{
System.out.println(t.toUpperCase());
},t ->{
System.out.println(t.toLowerCase());
});
}
}
3.4 Predicate接口
接口方法:test()
对某种类型的数据进行判断,得到一个boolean值
package it;
import java.util.function.Predicate;
public class DemoPredicate {
public static boolean checkString(String s, Predicate<String> pre) {
return pre.test(s);
}
public static void main(String[] args) {
String s = "das";
boolean b = checkString(s, str -> str.length() > 5);
System.out.println(b);
}
}
3.4.1 and,or,negate
与,或,非
package it;
import java.util.function.Predicate;
public class DemoPredicate_and {
public static boolean checkString(String s, Predicate<String> pre1,Predicate<String> pre2){
return pre1.and(pre2).test(s);
// return pre1.or(pre2).test(s);
}
public static void main(String[] args) {
String s ="sadf";
boolean b = checkString(s, st -> st.length() > 5, st -> st.length() < 5);
System.out.println(b);
}
}
Function借口
接口方法apply(T t)
将一个类型转换为另一个,t转换成R
package it;
import java.util.function.Function;
public class DemoFunction {
public static void change(String s, Function<String, Integer> fun) {
System.out.println(fun.apply(s));
}
public static void main(String[] args) {
String s = "12";
change(s,str -> Integer.parseInt(str));
}
}
Function andthen可以自定义函数模型拼接
Stream
package it;
import java.util.ArrayList;
import java.util.List;
public class DemoList {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("谢逊");
list.add("张三丰");
list.stream()
.filter(name -> name.startsWith("张"))
.filter(name -> name.length() == 3)
.forEach(name -> System.out.println(name));
}
}
流的思想
Stream流和io流并不是太相似
filter,map,skip并没有被执行,只有执行了count之后,才会执行,这就得益于Lambda的延迟处理
获取流
-
default Stream<E> stream()
集合中的默认方法,只对Collection有效
-
static <T> Stream<T> of(T... values)
可以将数组变成流
package it;
import java.util.*;
import java.util.stream.Stream;
public class DemoGetStream {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Stream<String> streamList = list.stream();
Set<String> set = new HashSet<>();
Stream<String> streamSet = set.stream();
//Map转换为Stream
Map<String,String> map = new HashMap<>();
Set<String> keySet = map.keySet();
Stream<String> StreamKey = keySet.stream();
Collection<String> values = map.values();
Stream<String> streamValues = values.stream();
Set<Map.Entry<String, String>> entries = map.entrySet();
Stream<Map.Entry<String, String>> entryStream = entries.stream();
//将数组转换为stream
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
Integer[] arr = {1,2,3,4,5};
Stream<Integer> arr1 = Stream.of(arr);
}
}
常用方法
- 延迟方法: 返回值类型仍然是Stream接口自身的方法,因此支持链式调用(除了终结方法,就是延迟方法,只要不是终结方法,返回的流都是新的流)
- 终结方法: 返回值类型不再是Stream接口自身的方法,,因此不支持链式调用(即调用了之后就不能调用Stream的方法了),这里只有forEach和count是终结方法,
foreach
void forEach(Consumer<? super T> action)
逐一处理
package it;
import java.util.stream.Stream;
public class DemoForEach {
public static void main(String[] args) {
Stream<String> stream = Stream.of("a", "b", "c", "d", "e");
stream.forEach(ch -> System.out.println(ch));
}
}
filter
Stream<T> filter(Predicate<? super T> predicate)
过滤
package it;
import java.util.stream.Stream;
public class DemoFilter {
public static void main(String[] args) {
Stream<String> stream = Stream.of("张无忌", "周芷若", "赵敏", "谢逊", "张三丰");
Stream<String> stream1 = stream.filter(name -> name.startsWith("张"));
stream1.forEach(name -> System.out.println(name));
}
}
map
<R> Stream<R> map(Function<? super T,? extends R> mapper)
映射
package it;
import java.util.stream.Stream;
public class DemoMap {
public static void main(String[] args) {
Stream<String> stream = Stream.of("1", "2", "3", "4");
Stream<Integer> stream1 = stream.map(s -> Integer.parseInt(s));
stream1.forEach(ch -> System.out.println(ch));
}
}
count
long count()
统计个数
package it;
import java.util.List;
import java.util.stream.Stream;
public class DemoCount {
public static void main(String[] args) {
List<Integer> list = List.of(1,2,3,4,5,6,7,8);
Stream<Integer> stream = list.stream();
long count = stream.count();
System.out.println(count);
}
}
limit
Stream<T> limit(long maxSize)
对流中的前maxSize个元素进行截取
package it;
import java.util.stream.Stream;
public class DemoLimit {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8);
stream.limit(5).forEach(ch -> System.out.println(ch));
}
}
skip
Stream<T> skip(long n)
跳过前n个元素
package it;
import java.util.stream.Stream;
public class DemoSkip {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8);
stream.skip(5).forEach(ch -> System.out.println(ch));
}
}
concat
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
将两个流合并
package it;
import java.util.stream.Stream;
public class DemoConcat {
public static void main(String[] args) {
Stream<String> stream = Stream.of("张无忌", "周芷若");
Stream<String> stream1 = Stream.of("赵敏", "谢逊", "张三丰");
Stream.concat(stream,stream1).forEach(name -> System.out.println(name));
}
}
sorted
package it;
import java.util.List;
import java.util.stream.Stream;
public class DemoCount {//自定义倒叙
public static void main(String[] args) {
List<Integer> list = List.of(423,2,423,312,4,54,4123,43);
Stream<Integer> stream = list.stream();
stream.sorted((s1,s2) -> (s1 < s2)?1 : -1).forEach(ch -> System.out.println(ch));
}
}