美文网首页
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