美文网首页
lambda编程

lambda编程

作者: 寂静的春天1988 | 来源:发表于2020-08-04 11:03 被阅读0次

前期准备数据

public enum SkCategoryEnum {
    CLOTHING(10,"服装类"),
    ELECTRONICS(20,"数码类"),
    SPORTS(30,"运动类"),
    BOOKS(40,"图书类");
    
    private Integer code;
    
    private String name;

    private SkCategoryEnum(Integer code, String name) {
        this.code = code;
        this.name = name;
    }
}
public class Sku {
    
    private Integer skuId;
    
    private String skuName;
    
    private Double skuPrice;
    
    private Integer totalNum;
    
    private Double totalPrice;
    
    private Enum skCategory;

}

public class CarService {
    
    
    
    private static List<Sku> carSkuList=new ArrayList<Sku>() {
    

        {
            add(new Sku(62329, "无人机", 4999.00, 1, 4999.00,
                    SkCategoryEnum.ELECTRONICS));
            
            add(new Sku(62231, "vr一体机", 2299.00, 1, 2299.00,
                    SkCategoryEnum.ELECTRONICS));
            
            add(new Sku(42131, "耐克冲锋衣", 499.00, 1, 499.00,
                    SkCategoryEnum.CLOTHING));
            
            add(new Sku(55217, "牛仔裤", 100.00, 3, 300.00,
                    SkCategoryEnum.CLOTHING));
            
            add(new Sku(62262, "衬衫", 399.00, 1, 399.00,
                    SkCategoryEnum.CLOTHING));

            
            add(new Sku(44821, "耳机", 19.00, 1, 19.00,
                    SkCategoryEnum.ELECTRONICS));
            
            add(new Sku(77466, "java编程", 199.00, 1, 199.00,
                    SkCategoryEnum.BOOKS));
        }
    };

    
    
    
    public static List<Sku> getCartSkuList(){
        return carSkuList;
        }   
    
}

需求1:根据商品类型筛选出数据
实现:略,for循环判断即可

需求迭代:根据一个布尔值,为true根据类型比较,false根据总价比较
实现

    public  List<Sku> filterSkusByCategory(List<Sku> carSkuList,SkCategoryEnum category,Double totalPrice,boolean categoryOrPrice){
        List<Sku> result=new ArrayList<Sku>();
        for (Sku sku : carSkuList) {
            if(categoryOrPrice&&sku.getSkCategory().equals(category)) {
                result.add(sku);
            }else if(!categoryOrPrice && sku.getTotalPrice() >= totalPrice){
                result.add(sku);
            }
        }
        
        return result;
    }

思考:那么怎么应对这种筛选功能的迭代呢?

/**
 * sku选择谓词
 * @author user
 *
 */
public interface SkuPredicate {

    boolean test(Sku sku);
}

    /**
     * 根据不同的sku判断标准,对sku列表进行过滤
     * @param carSkuList
     * @param predicate
     * @return
     */
    public List<Sku> filterSkus(List<Sku> carSkuList,SkuPredicate predicate){
        List<Sku> result=new ArrayList<Sku>();
        for (Sku sku : carSkuList) {
            if(predicate.test(sku)) {
                result.add(sku);
            }
        }
        return result;
    }

定义了一个SkuPredicate接口,用它的多个实现类来专门实现不同标准下,判断sku是否符合标准。

思考:如果创建多个SkuPredicate的实现类,但是它只会使用一次,可以使用匿名类

    public static void main(String[] args) {
        List<Sku> cartSkuList=CarService.getCartSkuList();
                // 筛选总价大于1000的商品
        CarService.filterSkus(cartSkuList, new SkuPredicate() {
            
            public boolean test(Sku sku) {
                if(sku.getTotalPrice()>1000) {
                    return true;
                }
                return false;
            }
        });
    }

使用lambda来实现

    public static void main(String[] args) {
        List<Sku> cartSkuList=CarService.getCartSkuList();
        CarService.filterSkus(cartSkuList,(Sku sku) -> sku.getTotalPrice() > 1000 );
    }

可以看到使用lambda表达式来替代匿名函数,非常简洁

lambda表达式:
1、可以理解为一种匿名函数的代替
2、通过行为参数化传递代码

image.png image.png image.png

只有一个参数,小括号可以省略


image.png image.png image.png

函数式接口
1、接口只有一个抽象方法。
2、使用@FunctionalInterface,这个注解会校验是否符合函数式接口,也就第一条规则。
3、函数式接口的抽象方法签名:函数描述符

/**
 * 文件处理函数式接口
 * @author user
 *
 */
@FunctionalInterface
public interface FileConsumer {

    
    /**
     * 函数式接口抽象方法
     * @param fileContent 文件内容
     */
    void fileHandler(String fileContent);
}

public class FileService {
    
    
    public void fileHandle(String url,FileConsumer fileConsumer) {
        //1、获取文件内容 略
        
        // 2、调用FileConsumer类的处理方法
        String fileContent="aaadd";
        fileConsumer.fileHandler(fileContent);
    }
    
    public static void main(String[] args) {
        FileService fileService=new FileService();
        fileService.fileHandle("",fileContent -> System.out.println(fileContent));
    }
}

常用的函数接口和使用

image.png

所以上面的例子完全可以不用自己定义函数接口,而使用提供好的函数接口

public class FileService {
    
    
    
    public void fileHandle2(String url,Consumer<String> consumer) {
        //1、获取文件内容 略
        
        // 2、调用FileConsumer类的处理方法
        String fileContent="aaadd";
        consumer.accept(fileContent);
    }
    
    
    public static void main(String[] args) {
        FileService fileService=new FileService();
        fileService.fileHandle2("",fileContent -> System.out.println(fileContent));
    }
}

方法引用

调用特定方法的lambda表达式的一种快捷写法,可以让你重复的使用现有方法定义。并向lambda表达式义一样传递他们。

简单的说:调用一些特定的方法时,使用lambad表达式的快捷方式。


方法引用格式.png

有三种特定方法可以使用方法引用
1、指向静态方法的方法引用

public class FileService {
    
    public void fileHandle2(String url,Consumer<String> consumer) {
        //1、获取文件内容 略
        
        // 2、调用FileConsumer类的处理方法
        String fileContent="123";
        consumer.accept(fileContent);
    }
    
    
    public static void main(String[] args) {
        FileService fileService=new FileService();
        fileService.fileHandle2("",fileContent -> Integer.parseInt(fileContent));
        fileService.fileHandle2("",Integer::parseInt);

    }
}

2、指向任意类型的实例方法

public class FileService {
    
    public void fileHandle2(String url,Consumer<String> consumer) {
        //1、获取文件内容 略
        
        // 2、调用FileConsumer类的处理方法
        String fileContent="123";
        consumer.accept(fileContent);
    }
    
    
    public static void main(String[] args) {
        FileService fileService=new FileService();
        fileService.fileHandle2("",fileContent -> fileContent.length());
        fileService.fileHandle2("",String::length);
    }
}

指向任意类型的实例方法:这句话开始没看懂?什么叫实例方法?

百度了一下:实例方法就是当一个类创建了一个对象后,这个对象就可以调用该类的方法(对象方法)。

所以就好理解了,这里的fileContent已经被实例化了,所以可以使用方法引用

3、指向现有对象的实例方法的方法引用

    public static void main(String[] args) {
        FileService fileService=new FileService();
        StringBuilder stringBuilder = new StringBuilder();
        fileService.fileHandle2("",fileContent -> stringBuilder.append(fileContent));
        fileService.fileHandle2("",stringBuilder::append);
    }

相关文章

网友评论

      本文标题:lambda编程

      本文链接:https://www.haomeiwen.com/subject/arkdrktx.html