zoukankan      html  css  js  c++  java
  • 《Java基础知识》Java Lambda表达式

    接触Lambda表达式的时候,第一感觉就是,这个是啥?我居然看不懂,于是开始寻找资料,必须弄懂它。

    先来看一个案例:

    @FunctionalInterface
    public interface MyLamda {
        void test1(String y);
    }
    import demo.knowledgepoints.Lambda.inf.MyLamda;
    
    public class LambdaTest {
        public static void main(String[] args) {
            MyLamda m = (y) ->{ System.out.println("ss"+y);};
            m.test1("s");
        }
    }

    运行结果:

    非Lambda方式:

    import demo.knowledgepoints.Lambda.inf.MyLamda;
    
    public class MyLamdaIml implements MyLamda {
        @Override
        public void test1(String y) {
            System.out.println("ss"+y);
        }
    
        public static void main(String[] args) {
            MyLamdaIml myLamdaIml = new MyLamdaIml();
            myLamdaIml.test1("s");
        }
    }

    运行结果:

    对比一下这两种方式:明显感觉使用Lambda表达式的更加简洁,由Java8引入,让我们一起来看看Lambda表达式的优点和不足。

    1. Lambda表达式 语法:() -> {}; 通过上述案例我们看出,这个语法,就是替代了一个实现类和实现类中方法。

    () 里面y为入参,{} 为方法体,类名被隐藏,方法名被隐藏。

    2. Lambda表达式,接口(MyLamda)只能有且只有一个抽象方法。同时通过注解@FunctionalInterface可以做到编译的时候校验抽象方法,

    不满足要求,给出编译报错。

    3. (y) 可以写成 (String y),  {}里面可以省略 return。并且当方法中只有一行代码时,{} 也可以省略  ;() 里面只有一个参数() 也可以省略,

    最简写法 y -> System.out.println("ss"+y);

    知道Lambda表达式的概念,就要结合实际情况来使用。

    案例:

    Java的Runable接口 有注解@FunctionalInterface。

    @FunctionalInterface
    public interface Runnable {
        /**
         * When an object implementing interface <code>Runnable</code> is used
         * to create a thread, starting the thread causes the object's
         * <code>run</code> method to be called in that separately executing
         * thread.
         * <p>
         * The general contract of the method <code>run</code> is that it may
         * take any action whatsoever.
         *
         * @see     java.lang.Thread#run()
         */
        public abstract void run();
    }

    于是:

    public class LambdaTest {
        public static void main(String[] args) {
            Runnable runnable = () -> System.out.println("线程启动");
            Thread thread = new Thread(runnable);
            thread.start();
        }
    }

    运行结果:

    import java.util.Arrays;
    import java.util.List;
    
    public class LambdaTest {
        public static void main(String[] args) {
            System.out.println("Java 8之前:---------------------------------------------");
            List<String> features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
            for (String feature : features) {
                System.out.println(feature);
            }
            System.out.println("Java 8之后:---------------------------------------------");
            List features1 = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
            features1.forEach(n -> System.out.println(n));
            System.out.println("使用Java 8的方法引用更方便,方法引用由::双冒号操作符标示,看起来像C++的作用域解析运算符");
            features1.forEach(System.out::println);
        }
    }

    运行结果:

    Java8引入函数式编程,还提供了一个强大的工具类: java.util.function,该类非常适合对集合数据做过滤操作。

    案例:

    import java.util.Arrays;
    import java.util.List;
    import java.util.function.Predicate;
    
    public class LambdaTest {
        public static void main(String[] args) {
            List<String> languages = Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp");
    
            System.out.println("第一个字符是J的字符串:");
            filter(languages, (str)->str.startsWith("J"));
    
            System.out.println("最后一个字符是a的字符串:");
            filter(languages, (str)->str.endsWith("a"));
    
            System.out.println("打印全部:");
            filter(languages, (str)->true);
    
            System.out.println("都不打印:");
            filter(languages, (str)->false);
    
            System.out.println("打印字符串长度超过4:");
            filter(languages, (str)->str.length() > 4);
    
        }
    
        public static void filter(List<String> names, Predicate<String> condition) {
            for(String name: names)  {
                if(condition.test(name)) {
                    System.out.print(name + " ");
                }
            }
            System.out.println();
        }
    }

    运行结果:

    java.util.function.Predicate 允许将两个或更多的 Predicate 合成一个。它提供类似于逻辑操作符AND和OR的方法,名字叫做and()和or(),用于将传入 filter() 方法的条件合并起来。

    案例:

    import java.util.Arrays;
    import java.util.List;
    import java.util.function.Predicate;
    
    public class LambdaTest {
        public static void main(String[] args) {
            List<String> names = Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp");
            // 甚至可以用and()、or()逻辑函数来合并Predicate,
            // 例如要找到所有以J开始,长度为四个字母的名字,你可以合并两个Predicate并传入
            Predicate<String> startsWithJ = (n) -> n.startsWith("J");
            Predicate<String> fourLetterLong = (n) -> n.length() == 4;
            names.stream().filter(startsWithJ.and(fourLetterLong))
                    .forEach((n) -> System.out.print("字符串开头为“J” 且 字符长度等于4:" + n));
    
        }
    }

    运行结果:

    函数式编程概念map,改变元素值。

    案例:

    import java.util.Arrays;
    import java.util.List;
    
    public class LambdaTest {
        public static void main(String[] args) {
            // 使用lambda表达式
            List<Integer> costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
            costBeforeTax.stream().map((cost) -> cost + .12*cost).forEach(n -> System.out.print(n+"; "));
            System.out.println();
            double bill = costBeforeTax.stream().map((cost) -> cost + .12*cost).reduce((sum, cost) -> sum + cost).get();
            System.out.println("Total : " + bill);
        }
    }

    运行结果:

    案例:(filter 将满足条件的数据组成新的List)

    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    
    public class LambdaTest {
        public static void main(String[] args) {
            List<String> strList = Arrays.asList("abc","bcd","defg","jk");
            List<String> filtered = strList.stream().filter(x -> x.length()> 2).collect(Collectors.toList());
            System.out.printf("原List : %s, 新list : %s", strList, filtered);
        }
    }

    运行结果:

    案例:(map() 对元素进行转化,distinct() 方法来对集合进行去重)

    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    
    public class LambdaTest {
        public static void main(String[] args) {
            List<String> G7 = Arrays.asList("USA", "Japan", "France", "Germany", "Italy", "U.K.","Canada");
            String G7Countries = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(", "));
            System.out.println(G7Countries);
    
            List<Integer> numbers = Arrays.asList(9, 10, 3, 4, 7, 3, 4);
            List<Integer> distinct = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
            System.out.printf("原List : %s,  平方后的新List : %s", numbers, distinct);
        }
    }

    运行结果:

    案例:(最大,最小,和,平均)

    import java.util.Arrays;
    import java.util.IntSummaryStatistics;
    import java.util.List;
    
    public class LambdaTest {
        public static void main(String[] args) {
            //获取数字的个数、最小值、最大值、总和以及平均值
            List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);
            IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x).summaryStatistics();
            System.out.println("List的最大值: " + stats.getMax());
            System.out.println("List的最小值: " + stats.getMin());
            System.out.println("List的之和: " + stats.getSum());
            System.out.println("List的平均值: " + stats.getAverage());
        }
    
    }

    运行结果:

    自定义流

    public class Demo {
    
        public static void main(String[] args) throws Exception{
            Random random = new Random();
            // 生成自己的流
            Stream<Integer> generateRandom = Stream.generate(random::nextInt);
            generateRandom.limit(5).forEach(System.out::println);
            // 生成自己的流
            Stream<UUID> generate = Stream.generate(UUID::randomUUID);
            generate.limit(5).forEach(System.out::println);
        }
    }

    运行结果:

    总结:

    lambda表达式:

    1. 简化代码。

    2. 对集合操作方便。

    缺点:

    1. 局限强,不易进行复杂操作。

    2. 数据量小,性能极差(慎用)。

    参考:https://www.cnblogs.com/coprince/p/8692972.html

    This moment will nap, you will have a dream; But this moment study,you will interpret a dream.
  • 相关阅读:
    几种函数调用方式
    MOSS 2010:Visual Studio 2010开发体验(11)——扩展SharePoint Explorer
    MOSS 2010:Visual Studio 2010开发体验(14)——列表开发之事件接收器
    MOSS 开发之服务帐号过期的问题
    关于工作流(Workflow Foundation)的一些总结归纳
    Infopath 2010的变化
    MOSS 2010:Visual Studio 2010开发体验(13)——列表开发之列表实例
    MTOM效率测试
    MTOM以及在WCF中的应用
    在Outlook中设置农历生日周期性事件
  • 原文地址:https://www.cnblogs.com/jssj/p/11580717.html
Copyright © 2011-2022 走看看