JAVA8-Labmda重构与调试

	interface Task{
        public void execute();
    }
    public static void doSomething(Runnable r){ r.run(); }
    public static void doSomething(Task a){ a.execute(); }

如果写成这样doSomething(() -> System.out.println("Danger danger!!"));并不清楚用的哪个方法。
可以改写成这样doSomething((Task)() -> System.out.println("Danger danger!!"));

将Lambda表达式转为方法引用
在这里插入图片描述
从命令式的数据处理到Stream

 List<String> dishNames = new ArrayList<>();
    for(Dish dish: menu){
        if(dish.getCalories() > 300){
            dishNames.add(dish.getName());
} }
menu.parallelStream()
        .filter(d -> d.getCalories() > 300)
        .map(Dish::getName)
        .collect(toList());

有些场景的代码执行后,结果不一定会被使用,从而造成性能浪费。而Lambda表达式是延迟执行的,这正好可以 作为解决方案,提升性能。

public class Demo03LoggerDelay {
    private static void log(int level, MessageBuilder builder) {
        if (level == 1) {
            System.out.println(builder.buildMessage());
        }
    }
    public static void main(String[] args) {
        String msgA = "Hello ";
        String msgB = "world ";
        String msgC = "Java ";
        log(2,() ->{
            System.out.println("Lambda执行!");
             return msgA + msgB + msgC;
        });
    }
}

环绕执行可以重用准备和清理阶段的逻辑。

@FunctionalInterface
public interface BufferedReaderProcessor {     
    String process(BufferedReader b) throws IOException; 
} 
public static String processFile(BufferedReaderProcessor p) throws IOException{    
    try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {                     
        return p.process(br);     
    } 
} 

策略模式

public interface ValidationStrategy {
        boolean execute(String s);
}
public class IsAllLowerCase implements ValidationStrategy {
    public boolean execute(String s){
	return s.matches("[a-z]+");
 }
public class IsNumeric implements ValidationStrategy {
    public boolean execute(String s){
        return s.matches("\\d+");
 }
 public class Validator{
    private final ValidationStrategy strategy;
    public Validator(ValidationStrategy v){
        this.strategy = v;
    }
    public boolean validate(String s){
        return strategy.execute(s);
    } 
}
Validator numericValidator = new Validator(new IsNumeric());
boolean b1 = numericValidator.validate("aaaa");
Validator lowerCaseValidator = new Validator(new IsAllLowerCase ()); 
boolean b2 = lowerCaseValidator.validate("bbbb");
//使用Lambda,不需要声明新的类来实现不同的策略
Validator numericValidator = new Validator((String s) -> s.matches("[a-z]+"));
boolean b1 = numericValidator.validate("aaaa");
Validator lowerCaseValidator = new Validator((String s) -> s.matches("\\d+"));
boolean b2 = lowerCaseValidator.validate("bbbb");

模板方法

模板方法模型是一种行为设计模型。模板方法是一个定义在父类别的方法,在模板方法中会呼叫多个定义在父类别的其他方法,而这些方法有可能只是抽象方法并没有实作,模板方法仅决定这些抽象方法的执行顺序,这些抽象方法的实作由子类别负责,并且子类别不允许覆写模板方法。

//用户需要输入一个用户 户,之后应用才能从 行的数据库中得到用户的详细信息, 最终完成一些让用户满意的操作。
abstract class OnlineBanking {
        public void processCustomer(int id){
            Customer c = Database.getCustomerWithId(id);
            makeCustomerHappy(c);
}
    abstract void makeCustomerHappy(Customer c);
}
//使用Lambda表达式
public void processCustomer(int id, Consumer<Customer> makeCustomerHappy){ 
	Customer c = Database.getCustomerWithId(id); makeCustomerHappy.accept(c);
}
new OnlineBankingLambda().processCustomer(1337, (Customer c) -> System.out.println("Hello " + c.getName());

processCustomer方法搭建了在线银行算法的框架:获取客户提供的ID,然后提供服务让用户满意。

观察者模式

**观察者模式(**又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

public interface Observer {
    public void update(String message);
}
public class WeixinUser implements Observer {
    // 微信用户名
    private String name;
    public WeixinUser(String name) {
        this.name = name;
    }
    @Override
    public void update(String message) {
        System.out.println(name + "-" + message);
    }
}
public interface Subject {
    /**
     * 增加订阅者
     * @param observer
     */
    public void attach(Observer observer);
    /**
     * 删除订阅者
     * @param observer
     */
    public void detach(Observer observer);
    /**
     * 通知订阅者更新消息
     */
    public void notify(String message);
}
public class SubscriptionSubject implements Subject {
    //储存订阅公众号的微信用户
    private List<Observer> weixinUserlist = new ArrayList<Observer>();
    @Override
    public void attach(Observer observer) {
        weixinUserlist.add(observer);
    }
    @Override
    //删除订阅用户
    public void detach(Observer observer) {
        weixinUserlist.remove(observer);
    }
    @Override
    //通知方法
    public void notify(String message) {
        for (Observer observer : weixinUserlist) {
            observer.update(message);
        }
    }
}

//订阅公众号
mSubscriptionSubject.attach(user1);
//使用lambda
mSubscriptionSubject.attach((String s) -> { System.out.println(name + "-" + message);});

责任链模式

责任链模式是一种创建处理对象序列(比如操作序列)的通用方案。一个处理对象可能需要 在完成一些工作之后,将结果传递给另一个对象,这个对象接着做一些工作,再转交给下一个处理对象,以此类推。

public abstract class ProcessingObject<T> { 
 	protected ProcessingObject<T> successor;
	 public void setSuccessor(ProcessingObject<T> successor){
	   this.successor = successor;
	  }
     public T handle(T input){
           T r = handleWork(input);
           if(successor != null){
               return successor.handle(r);
           }
           return r; 
        }
       abstract protected T handleWork(T input);
    }
    public class HeaderTextProcessing extends ProcessingObject<String> { public String handleWork(String text){
            return "From Raoul, Mario and Alan: " + text;
        }
	}
	public class SpellCheckerProcessing extends ProcessingObject<String> {
	       public String handleWork(String text){
	        return text.replaceAll("labda", "lambda");
	} 
}

ProcessingObject<String> p1 = new HeaderTextProcessing();
ProcessingObject<String> p2 = new SpellCheckerProcessing();
p1.setSuccessor(p2);
String result = p1.handle("Aren't labdas really sexy?!!");
System.out.println(result);
//使用lambda
UnaryOperator<String> headerProcessing =
        (String text) -> "From Raoul, Mario and Alan: " + text;
    UnaryOperator<String> spellCheckerProcessing =
        (String text) -> text.replaceAll("labda", "lambda");
    Function<String, String> pipeline =
        headerProcessing.andThen(spellCheckerProcessing);
    String result = pipeline.apply("Aren't labdas really sexy?!!")

在这里插入图片描述

工厂模式

使用工厂模式,你无需向客户暴露实例化的逻辑就能完成对象的创建。比如,我们假定你为 一家 行工作,他们需要一种方式创建不同的金融产品 : 期权、股票,等等。

Supplier<Product> loanSupplier = Loan::new;
Loan loan = loanSupplier.get();

final static Map<String, Supplier<Product>> map = new HashMap<>(); static {
        map.put("loan", Loan::new);
        map.put("stock", Stock::new);
        map.put("bond", Bond::new);
}
public static Product createProduct(String name){
        Supplier<Product> p = map.get(name);
        if(p != null) return p.get();
        throw new IllegalArgumentException("No such product " + name);
}

对Lambda进行测试

 @Test
    public void testMoveRightBy() throws Exception {
        Point p1 = new Point(5, 5);
        Point p2 = p1.moveRightBy(10);
        assertEquals(15, p2.getX());
        assertEquals(5, p2.getY());
    }

Lambda调试

程序的每次方法调用都会产生相应的调用信息,包括程序中方法调用的位置 、该方法调用使用的参数、被调用方法的本地变量。这些信息被保存在栈帧上。

//错误代码
public class Debugging {
    public static void main(String[] args) {
        List<Point> points = Arrays.asList(new Point(12, 2), null);
        points.stream().map(p -> p.getX()).forEach(System.out::println); }
}

执行后报错
在这里插入图片描述
这时你的程序实际是在 图处理一个空引用。由于Stream流水线发生了错误,构成Stream流水线的整个方法调用序列都暴露在你面前了。栈跟踪中还包含类似加密的内容。
这些表示错误发生在Lambda表达式内部。由于Lambda表达式没有名字,所以编译器只能为它们指定一个名字。这个例子中,它的名字是lambda$main$0,看起来非常不直观。
注意:如果方法引用指向的是同一个类中声明的方法,那么它的名称是可以在栈跟踪中显示的。
我们可以使用日志调试

List<Integer> result =
  numbers.stream()
         .peek(x -> System.out.println("from stream: " + x))
         .map(x -> x + 17)
         .peek(x -> System.out.println("after map: " + x))
         .filter(x -> x % 2 == 0)
         .peek(x -> System.out.println("after filter: " + x))
         .limit(3)
         .peek(x -> System.out.println("after limit: " + x))
         .collect(toList());

peek的设计就是在流的每个元素恢复运行之前,插入执行一个动作。但是它不像forEach那样恢复整个流的运行,而是在一个元素上完成操
作之后,它只会将操作顺承到流水线中的下一个操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值