函数式接口
函数式接口表示接口中有且仅有一个抽象方法的接口,可以允许有其他方法
可以调用@FuctionalInterface进行标记
函数式接口的使用
1.作为方法的形式参数使用
调用方法,实际传递的可以是匿名内部类,也可以是Lambda表达式
2.作为方法的返回值使用
实际返回的可以是匿名内部类,也可以是Lambda表达式
Supplier接口
Supplier 是一个生产型接口,内部有一个get()方法用来获取一个T类型的数据。
public class Demo {
public static void main(String[] args) {
//传递的匿名内部类
mathod(new Supplier<String>() {
@Override
public String get() {
return "haha";
}
});
//lambda表达式
mathod(()->"mm");
}
public static void mathod(Supplier<String> s){
String str = s.get();
System.out.println(str);
}
}
public class Domo01 {
public static void main(String[] args) {
int []arry={10,20,30,40,85};
//获取一个数组最大值
method(() ->{
int max=arry[0];
for (int i = 1; i < arry.length; i++) {
if(arry[i]>max){
max=arry[i];
}
}
return max;
} );
}
public static void method(Supplier<Integer> sup){
Integer result = sup.get();
System.out.println(result);
}
}
Consumer接口
Consumer 是一个消费型接口,内部有一个accept(T t)方法用来消费T类型的数据。
public class Demo {
public static void main(String[] args) {
method("Listen to me",(String s)->{
String s1 = s.toLowerCase();
System.out.println(s1);
});
method2("To be continue",(String s)->{
String s1 = s.toLowerCase();
System.out.println(s1);
},(String s2)->{
String s = s2.toUpperCase();
System.out.println(s);
},(String s)->{
System.out.println(s);
}
);
}
public static void method(String s, Consumer<String> con){
con.accept(s);
}
public static void method2(String s,Consumer<String> con1,Consumer<String> con2,Consumer<String> consumer3){
con1.andThen(con2).andThen(consumer3).accept(s);
}
}
Predicata接口
Predicate 是一个校验型接口,内部有一个test(T t)方法用校验T类型的数据是否符合要求。
public boolean test(T t)
对T类型的数据进行校验,校验方式由Lambda表达式提供
public Predicate<T> negate()
对test(T t)校验的结果进行取反,类似于"!"运算
public Predicate<T> and(Predicate<T> t)
对两个Predicate<T>进行连接,类似于"&&"运算,只有两次校验都为true结果才为true
public Predicate<T> or(Predicate<T> t)
对两个Predicate<T>进行连接,类似于"||"运算,只有两次校验都为false结果才为flase
public class Demo1 {
public static void main(String[] args) {
method("hello.java", (String s) -> {
boolean b = s.endsWith(".java");
return b;
}
);
method2("hello.java", (String s) -> {
boolean b = s.endsWith(".java");
return b;
}, (String s) -> {
return s.length() > 5;
});
}
public static void method(String s, Predicate<String> p) {
boolean test = p.negate().test(s);
System.out.println(test);
}
public static void method2(String s, Predicate<String> p1, Predicate<String> p2) {
boolean test = p1.and(p2).test(s);
System.out.println(test);
}
}
public class Demo2 {
public static void main(String[] args) {
String[] array = {"林青霞,20", "李艳,30", "蔡旭混,25"};
ArrayList<String> strings = myFilter(array, (s) -> {
return s.split(",")[0].length() > 2;
}, (s) -> {
String sage = s.split(",")[1];
int i = Integer.parseInt(sage);
return i > 23;
});
// System.out.println(strings);
}
public static ArrayList<String> myFilter(String[] array, Predicate<String> p1, Predicate<String> p2) {
ArrayList<String> list = new ArrayList<>();
for (String str : array) {
if (p1.and(p2).test(str))
list.add(str);
}
System.out.println(list);
return list;
}
}
Function接口
Function<R,T>是一个转换型接口,内部有一个apply(R r)方法,可以用来把R类型的数据转换为T类型的数据。
public T apply(R r)
把R类型的数据转换为T类型的数据
public Function<T,W> andThen(Function<R,T> fun)
对两个Function<R,T>进行连接,对数据进行两次转换
第一次转换:R类型转换为T类型
第二次转换: T类型转换为W类型
public class Demo3 {
public static void main(String[] args) throws ParseException {
String s = new String("1997-11-13 11:12:55");
method(s, (s1) -> {
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date pase = null;
try {
pase = simpleDateFormat1.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
return pase;
}, pase ->
{
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
String format = simpleDateFormat2.format(pase);
return format;
}
);
}
public static void method(String s, Function<String, Date> f1, Function<Date, String> f2) {
String apply = f1.andThen(f2).apply(s);
System.out.println(apply);
}
}
Stream流
Stream流表示一种编程方式【流式编程】,可以很方便的对集合或者数组进行操作。
Stream流的操作方式有三个步骤
1.生成流
2.中间操作
3.终结操作
Stream生成流
//List集合生成流
List<String> list=new ArrayList<>();
Stream<String> s1=list.stream();
//Set集合生成流
Set<String> set=new HashSet<>();
Stream<String> s2=set.stream();
//Map集合生成流
Map<String,String> map=new HashMap<>();
//Map集合生成键的流
Stream<String> s3=map.keySet().stream();
//Map集合生成值的流
Stream<String> s4=map.values().stream();
//Map集合获取【键值对】的流
Stream<Map.Entry<String,String>> s5=map.entrySet().stream();
//数组生成流
Integer[] array={10,20,304,40};
Stream<Integer> s6=Stream.of(array);
中间操作
filter:用于对集合/数组中的元素进行过滤
limit:截取前面的n个元素
skip:跳过前面的n个元素
sorted:对集合/数组进行默认排序(正序 从低到高),如果想按照自定义排序,就需要制定比较器
concat:把两个流合并为一个流,它是静态直接调用Stream类名调用即可
distinct:去除重复元素
map:把流中的数据从一个类型转换为另一个类型
mapToInt:把流中数据转换为整数,生成一个IntStream(专门对整数操作的流)
终结操作
forEach:用于对集合/数组中的元素进行遍历
count:统计流中的元素个数
- 过滤练习
Integer[] array={1,4,5,6,3,7,8,9,2,10};
//生成流
Stream<Integer> stream = Stream.of(array);
//先过滤,再打印
stream.filter(s -> s%2==0).forEach(s-> System.out.println(s));
- 截取和跳过练习
ArrayList<Integer> list=new ArrayList<>();
Collections.addAll(list,1,3,6,4,5,8,9,2,10);
//截取集合中的前n个元素
//list.stream().limit(8).forEach(s-> System.out.println(s));
//跳过前面的n个元素
//list.stream().skip(3).forEach(integer -> System.out.println(integer));
//截取前面8个元素,再跳过前面3个,再过滤偶数,再打印输出
list.stream()
.limit(8)
.skip(3)
.filter(integer -> integer%2==0)
.forEach(integer -> System.out.println(integer));
- 统计个数练习
ArrayList<Integer> list=new ArrayList<>();
Collections.addAll(list,1,3,6,4,5,8,9,2,10);
//计算集合中偶数元素有多少个
long count = list.stream().filter(integer -> integer % 2 == 0).count();
System.out.println(count);
- 排序练习
ArrayList<Integer> list=new ArrayList<>();
Collections.addAll(list,1,3,6,4,5,8,9,2,10);
//对集合中的元素排序
list.stream().sorted().forEach(integer -> System.out.println(integer));
//降序排列
//list.stream().sorted((t1, t2) ->t2-t1 ).forEach(integer -> System.out.println(integer));
//list.stream().sorted((t1, t2) ->t2-t1 ).forEach(System.out::println);
- 合并和去重练习
public class Demo6 {
public static void main(String[] args) {
ArrayList<Integer> arrl1 = new ArrayList<Integer>();
ArrayList<Integer> arrl2 = new ArrayList<Integer>();
Collections.addAll(arrl1,1,2,3,4,5);
Collections.addAll(arrl2,5,6,7,8,9);
Stream<Integer> stream = arrl1.stream();
Stream<Integer> stream1 = arrl2.stream();
Stream.concat(stream,stream1).distinct().forEach(s-> System.out.println(s));
}
}
- 转换练习
public class Demo7 {
public static void main(String[] args) {
String[] array={"33","55","44","66"};
IntStream intStream = Stream.of(array).mapToInt(s -> Integer.parseInt(s));
int max = intStream.max().getAsInt();
System.out.println(max);
}
}