熟练使用Lambda表达式
函数式接口 有且仅有一个抽象方法的接口
- 可以有默认 静态 私有方法 但是抽象方法只能有一个
- 函数式接口 可以作为方法的参数和返回值使用
和Stream相关的几个函数式接口
Interface Predicate<T>
可以用作lambda表达式或方法引用的赋值对象。 用于判断
覆盖方法:
boolean test(T t)
判断方法
Interface Consumer<T>
对元素进行操作 消费型接口
覆盖方法:
void accept(T t)
对给定的参数执行此操作。
Interface Function<T,R>
apply
将T类型转换成R类型
Stream
对集合和数组进行简化操作
- stream 流 流式模型 类似于生产线
- 并不存储数据 只是对数据进行操作
- 使用流的基本步骤:1 获取数据源(集合 数组) 2 数据转换 3 执行操作想要的结果
Stream流属于管道流 一次性 使用过后就不能再调用方法
将stream1流进行过滤 赋值给stream2流 这时调用stream1进行forEach方法 会出现异常
获取所有姓张的三字姓名 并遍历
public class StreamDemo1 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("张三丰");
list.add("张无忌");
list.add("张强");
list.add("赵敏");
Stream<String> stream = list.stream();
stream.filter((name)->name.startsWith("张"))
.filter((name)->name.length()==3).forEach((name)-> System.out.println(name));
}
}
获取Stream方法
集合获取
所有单列集合都可以通过.stream(); 来获取 Map集合可以使用keyset Map.Entry 获取
Stream接口的静态方法.of获取数组的对应流 不能把简单数据类型传入
Stream有两种方法
延迟方法 :调用方法后返回值类型依旧是Stream流类型 支持链式调用
终结方法:调用不再是Stream流类型方法 count forEach
forEach 方法
ArrayList中效率 >fori > interator
void forEach(Consumer<? super T> action)
对此流的每个元素执行操作。
forEach
方法内部调用了Consumer接口中的accept()
方法
传入Consumer接口的实现类后 , forEach
方法会 调用实现类复写后的accept
方法
接收一个Consumer接口类型函数将每一个流元素交给该函数处理
Filter 过滤方法
将原流进行过滤返回新的Stream流
调用test
方法 实现类进行复写
map映射方法
将一种类型的流转换成另一个类型的流
也可以用于对流中数据共同进行操作(例如 给数组中的各个数字+3)
Stream<String> stream = Stream.of("1", "2", "3");
Stream<Integer> stream1 = stream.map((String num) -> {
return Integer.parseInt(num);
});
limit方法
截取前几个元素 形成新的流
要三个元素 括号中就填3
skip方法
跳过前几个元素
concat 将两个流合并成一个流
Stream.concat(stream1,stream2);
方法引用
方法引用是只需要使用方法的名字,而具体调用交给函数式接口,需要和Lambda表达式配合使用。
List<String> list = Arrays.asList("a","b","c");
list.forEach(str -> System.out.print(str));//这两句运行结果一样
list.forEach(System.out::print);
1 通过对象名 引用成员方法
instance::method
/**
*
* 给一个字符串进行大写
*/
public class MethodInDemo1 {
public static String show(String s,ToUoCase toUoCase){
String up = toUoCase.getUp(s);
return up;
}
public static void main(String[] args) {
String hello = show("hello", new FunctionDemo1()::toUpMethod);
System.out.println(hello);
/* show("hello", new ToUoCase() {
@Override
public String getUp(String s) {
return new FunctionDemo1().toUpMethod(s);
}
});*/
}
}
public class FunctionDemo1 {
public String toUpMethod(String s){
String s1 = s.toUpperCase();
return s1;
}
}
@FunctionalInterface
public interface ToUoCase {
public abstract String getUp(String s);
}
2 通过类调用静态方法Class::static_method
/**
* 创建一个接口 通过static方法引用实现 绝对值功能*/
interface Abs{
public abstract int absMethod(int num);
}
class FunctionDemo2{
public static int anInt(int i){
return Math.abs(i);
}
}
public class MethodDemo2 {
public static void getNum(int num,Abs a){
int i = a.absMethod(num);
System.out.println(i);
}
public static void main(String[] args) {
getNum(-10,FunctionDemo2::anInt);
// getNum(-10,num -> FunctionDemo2.anInt(num));
/* getNum(-10, new Abs() {
@Override
public int absMethod(int num) {
return FunctionDemo2.anInt(num);
}
});*/
}
}
3.this调用本类方法 super调用父类方法 this::method
@FunctionalInterface
interface Rachable {
public abstract void buy();
}
public class Husband {
public void buyHouse() {
System.out.println("在北京二环买房子");
}
public void marry(Rachable rachable){
rachable.buy();
}
public void soHappy(){
// marry(()->this.buyHouse());
marry(this::buyHouse);
}
public static void main(String[] args) {
new Husband().soHappy();
}
}
4 调用带参数构造方法 Class::new
数组int[] ::new
//调用带参数构造方法
interface CreatePerson {
public abstract Person createPeron(String name);
}
public class NewPersonDemo {
public static Person createPerson(String name, CreatePerson createPerson) {
return createPerson.createPeron(name);
}
public static void main(String[] args) {
/* Person person = createPerson("程泽琪", new CreatePerson() {
@Override
public Person createPeron(String name) {
return new Person(name);
}
});*/
// Person person = createPerson("程泽琪", (name) -> new Person(name));
Person person = createPerson("程泽琪", Person::new);
System.out.println(person);
}
}
网友评论