最开始的时候读取一行文件,当我们需要读取两行的时候,我们需要复制代码改造
public static String processFileLimited() throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader("lambdasinaction/chap3/data.txt"))) {
return br.readLine();
}
}
后来我们改造成Lambda
public interface BufferedReaderProcessor{
public String process(BufferedReader b) throws IOException;
}
public static String processFile(BufferedReaderProcessor p) throws IOException {
try(BufferedReader br = new BufferedReader(
new FileReader("lambdasinaction/chap3/data.txt"))){
return p.process(br);
}
}
我们使用函数式接口来传递行为,控制我们读取或者操作的逻辑。下面改成读取两行
String oneLine = processFile((BufferedReader b) -> b.readLine());
String twoLines = processFile((BufferedReader b) -> b.readLine() + b.readLine());
我们每一次的使用自己的接口,这样接口会很多,很杂乱,Java8自带了一些函数式的接口给我们。
Predicate接口定义的是一个test
方法接口,返回的是一个Boolean值
@FunctionalInterface
public interface Predicate {
boolean test(T t);
}
用法
public static List filter(List list, Predicate p){
List result = new ArrayList<>();
for(T t : list){
if(p.test(t)){
result.add(t);
}
}
return result;
}
Predicate noEmpty = (String s) -> !s.isEmpty();
List list = filter(lists, noEmpty);//判断是否为空,不为空的加入到list中
Consumer接口定义的是一个accept
方法接口,是一个void方法
@FunctionalInterface
public interface Consumer {
void accept(T t);
}
用法
public static void forEach(List list, Consumer c) {
for (T t : list) {
c.accpt(t);
}
}
forEach(list, (Interger i) -> sout(i));//输出list中的所有值
Function接口定义的是一个apply
方法接口,返回的是一个泛型
@FunctionalInterface
public interface Function {
R apply(T t);
}
用法:
public static list map(List list, Function f) {
List result = new ArrayList<>();
for (T t : list) {
result.add(f.apply(t));
}
return result;
}
List list = map(list, (String s) -> s.length);//将传入的String值的长度加入到list中去
对比function包下面的这三个接口,我们发现他们只是返回的值不同,我们三次都是传入了一个list和一个泛型,predicate是判断list的值是否为空,Consumer是将list里面的值输出,Function是将list的值根据传入的泛型规则加入到list里面去。非常的灵活。
当你需要使用方法引用时,目标引用放在分隔符 : : 前面,方法的名称放在后面
比如Apple::getWeight
就是引用了Apple的getWight方法,不需要括号,因为没有实际的调用这个方法
方法引用就是Lambda表达式(Apple a) -> a.getWeight()
的快捷方式
指向静态方法
Lambda | (args) -> ClassName.staticMethod(args) |
---|---|
方法引用 | ClassName::staticMethod |
指向实例方法
Lambda | (args0, rest) -> args0.instanceMethod(rest)//args0是ClassName类型 |
---|---|
方法引用 | ClassName::staticMethod |
指向现有对象的实例方法
Lambda | (args) -> expr.instanceMethod(args) |
---|---|
方法引用 | expr::instanceMethod |
参考内容:Java8实战