Java8新特性 细说Lambda

java的发展历史

1995年5月23日,Java语言诞生 1996年1月,第一个JDK-JDK1.0诞生
1996年4月,10个最主要的操作系统供应商申明将在其产品中嵌入JAVA技术 1996年9月,约8.3万个网页应用了JAVA技术来制作
1997年2月18日,JDK1.1发布 1997年4月2日,JavaOne会议召开,参与者逾一万人,创当时全球同类会议规模之纪录
1997年9月,JavaDeveloperConnection社区成员超过十万 1998年2月,JDK1.1被下载超过2,000,000次
1998年12月8日,JAVA2企业平台J2EE发布
1999年6月,SUN公司发布Java的三个版本:标准版(JavaSE,以前是J2SE)、企业版(JavaEE以前是J2EE)和微型版(JavaME,以前是J2ME)
2000年5月8日,JDK1.3发布 2000年5月29日,JDK1.4发布
2001年6月5日,NOKIA宣布,到2003年将出售1亿部支持Java的手机 2001年9月24日,J2EE1.3发布
2002年2月26日,J2SE1.4发布,自此Java的计算能力有了大幅提升
2004年9月30日18:00PM,J2SE1.5发布,成为Java语言发展史上的又一里程碑。为了表示该版本的重要性,J2SE1.5更名为Java
SE 5.0 2005年6月,JavaOne大会召开,SUN公司公开Java SE
6。此时,Java的各种版本已经更名,以取消其中的数字“2”:J2EE更名为Java EE,J2SE更名为Java
SE,J2ME更名为Java ME 2006年12月,SUN公司发布JRE6.0
2009年04月20日,甲骨文74亿美元收购Sun。取得java的版权。
2010年11月,由于甲骨文对于Java社区的不友善,因此Apache扬言将退出JCP[3]。
2011年7月28日,甲骨文发布java7.0的正式版。 最新版本
甲骨文的Java总架构师马克·雷纳德在2011年JavaOne大会上为大家透露了Java 8的新功能,同时也谈到了一些关于Java
9的计划。[4]

java8是Oracle在2014年3月19日发布正式版的,和JDK7(2011年7月发布)相隔了近3年(拖的时间堪比JDK7和JDK6之间的时间,与历史版本发布间隔相比排在第二位,JDK6发布是2006,JDK7与之相比之间差了5年,这两个版本发布时间间隔最长,中间发生了Oracle收购SUN的大事件,JDK6因此曾成为使用率最高的JDK,),中间因意见不统一多次延迟。

体现Lambda的特点以及比较
lambda表达式的一般格式如下
(x, y) -> Integer.compare(x, y).
为了能够理解lambda表达式,咱们直接上代码
需求:获取公司员工年龄大于35岁的员工信息
没学过java8之前都是这种样子的

package com.java8.test;

public class Employee {
    private String name;
    private int age;
    private double salary;

    public Employee() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Employee(String name, int age, double salary) {
        super();
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Employee [name=" + name + ", age=" + age + ", salary=" + salary + "]";
    }
    // 获取当前公司中员工年龄大于35的员工信息
    @Test
    public void test3() {

        List<Employee> employees = filterEmployee(employee);
        for (Employee ee : employees) {
            System.out.println(ee.toString());
        }
    }
//奖励方法便利过滤是否符合条件,符合条件的加入到list结合中
    public static List<Employee> filterEmployee(List<Employee> employees) {
        List<Employee> newemp = new ArrayList<Employee>();
        for (Employee emp : employees) {
            if (emp.getAge() >= 35) {
                newemp.add(emp);
            }
        }
        return newemp;
    }
}

=================================================
优化代码一
建立一个Mypredicate<T>接口
package com.java8.test;

public interface MyPredicate<T> {
    public boolean test(T t);
}
--------------------------------
实现接口
public class FilterEmployeeByAge implements MyPredicate<Employee> {

    @Override
    public boolean test(Employee t) {
        // TODO Auto-generated method stub
        return t.getAge()>=35;
    }

}


================
建立测试方法
    @Test
    public void test4() {
        List<Employee> list = filterEmployee(employee, new FilterEmployeeByAge());
        //遍历输出集合
        for (Employee e : list) {
            System.out.println(e.toString());
        }
    }

策略设计模式
    public List<Employee> filterEmployee(List<Employee> list, MyPredicate<Employee> mp) {
        List<Employee> employees = new ArrayList<Employee>();
        for (Employee e : list) {
            if (mp.test(e)) {
                employees.add(e);
            }
        }
        return employees;
    }
===================================================
优化方式二,通过内部类来控制方法的实现,不用进行书写实现类来实现接口,我们可以通过内部类来书写方法的实现,
// 优化方式二
    @Test
    public void test5() {
        List<Employee> list = filterEmployee(employee, new MyPredicate<Employee>() {

            @Override
            public boolean test(Employee t) {
                // TODO Auto-generated method stub
                return t.getSalary() <= 5000;
            }
        });
        for (Employee e : list) {
            System.out.println(e.toString());
        }
    }

其中filterEmployee方法是同上边公用的,employee是一个全局变量集合,在本文中没有写出来
===============================================
优化方式三、使用Lambda表达式来书写
    // 优化方式三
    // Lambda表达式
    @Test
    public void test6() {
        List<Employee> filterEmployee = filterEmployee(employee, (e) -> e.getSalary() <= 5000);
        filterEmployee.forEach(System.out::println);
    }
在这里我们先不说Lambda如何实现该方法的,读者可以先熟悉一下代码,稍后会详细说明Lambda的使用以及语法。从这可以看出,Lambda的代码块很少,
================================================
优化方式四
//优化方式四
    @Test
    public void test7(){
        employee.stream()
            .filter((e)->e.getSalary()>=5000)
            .limit(2)
            .forEach(System.out::println);
        System.out.println("=============");
        employee.stream()
        .map(Employee::getName)
        .forEach(System.out::println);
    }

lambda表达式

/**
* 1.lambda 表达式的基础语法,java8中引入了一个新的操作符,“->” 该操作符 或Lambda操作符箭头操作符将Lambda表达式拆分为两部分,
*
* 左侧:Lambda 表达式参数列表 右侧:Lambda 表达式中所需要执行的功能,即Lambda体
*
* 语法格式一、无参数,无返回值 ()->System.out.println(“hellow”); ()->System.out.println(
* “hello Lambda”);
* 语法格式二:有一个参数,并且无返回值 Consumer consumer = (x) ->
* System.out.println(x);
* 语法格式三:只有一个参数,参数小括号可以省略不写 x->System.out.println(x)
* Consumer consumer = (x) -> System.out.println(x);// 对Consumer的实现
* Consumer consumer1 = x -> System.out.println(x);// 一个参数小括号可以不写
* consumer.accept(“平顶山学院”); 语法格式四:若有两个以上的参数,有返回值,并且Lambda体中有多条语句 Comparator
* comparator = (x, y) -> {
*
* System.out.println(“函数式接口”); return Integer.compare(x, y); };
*
* 语法格式五:若Lambda体中只有一条语句,return 和大括号都可以省略不写 Comparator
* com1=(x,y)->Integer.compare(x, y);
*
*
* 语法格式六、Lambda表达式的参数列表的数据类型可以省略补写,因为jvm编译器可以通过上下文推断出, (Integer x,Integer
* y)->System.out.println(“”)
* 总结: 上联:左右遇一括号省, 下联:左侧推断类型省 横批:能省则省
* 二、Lambda表达式需要”函数式接口“的支持
* 函数式接口:借口中只有一个抽象方法的借口,成为函数式接口,可以使用注解@FunctionInterface修饰 可以检查是否是函数式接口,
*
*/
java8提供了Consumer接口,我们可以通过这个接口来描述lambda特性
eg:

@Test
    public void test2() {
        Consumer<String> consumer = (x) -> System.out.println(x);// 对Consumer的实现
        Consumer<String> consumer1 = x -> System.out.println(x);// 一个参数小括号可以不写
        consumer.accept("平顶山学院");
    }
解析:我们可以发现,Consumer接口有一个accept(T t)方法,我们利用那个(x)->Systme.out.println(x)  ->左侧括号表示该方法一个参数,右侧表示没有返回值我们可以写个输出语句来验证执行。
下边两个例子相同
@Test
    public void test3() {
        Comparator<Integer> comparator = (x, y) -> {
            System.out.println("函数式接口");
            return Integer.compare(x, y);//表示该方法有返回值
        };
        comparator.compare(1, 2);//执行接口方法
    }

    @Test
    public void test4() {
        Comparator<Integer> com1 = (x, y) -> Integer.compare(x, y);
    }

书写一个需求:对一个数进行运算

package com.java8.test;
public interface MyFun {
    public Integer getValue(Integer num);
}
    // 需求:对一个数进行运算
    @Test
    public void test5() {
        Integer integer = operation(100, (x) -> x * x);
        System.out.println(integer);
        System.out.println(operation(200, (y)->y+200));
    }
    public Integer operation(Integer num, MyFun mf) {
        return mf.getValue(num);
    }

下边我们可以做几个实例来巩固一下

// 对list集合进行排序,如果年龄相同按照姓名进行排序
    List<Employee> employee = Arrays.asList(new Employee("张三", 18, 91258.3), new Employee("李四", 22, 8525.3),
            new Employee("刘强", 21, 4562.3), new Employee("王鸣三", 22, 8951.2), new Employee("李四强", 42, 3582.7));

    @Test
    public void test() {
        Collections.sort(employee, (e1, e2) -> {
            if (e1.getAge() == e2.getAge()) {
                return e1.getName().compareTo(e2.getName());
            } else {
                return Integer.compare(e1.getAge(), e2.getAge());
            }
        });
        for (Employee e : employee) {
            System.out.println(e.toString());
        }
    }
@Test
    public void test2() {
        /*
         * String strHandle = strHandle("\t\t\t 平顶山学院  ", (str)->str.trim());
         * System.out.println(strHandle);
         */
        String str = strHandle("adadefasd", (x) -> x.toUpperCase());
        System.out.println(str);
    }

    // 需求:用于处理字符串
    public String strHandle(String str, MyFunction my) {
        return my.getValue(str);
    }
@FunctionalInterface
public interface MyFunction {

    public String getValue(String str);
}

package com.java8.test.review;


public interface MyFunction2<T, R> {
    public R getValue(T t1, T t2);

}

@Test
    public void test3() {
        op(100L, 200L, (x, y) -> x + y);
        op(100L, 200L, (x,y)->x*y);
    }
    // 对于两个Long数据进行处理
    public void op(Long o1, Long o2, MyFunction2<Long, Long> mf) {
        System.out.println(mf.getValue(o1, o2));
    }

java8内置对象
/**
* java8内置的四大核心函数式接口,
* Consumer 混淆型接口 void accept(T t);
*
* Supplier :供给型接口 T get();
*
* Function

public class TestLambda {
    // 断言型接口 Predicate<T>
    @Test
    public void test4() {
        List<String> list=Arrays.asList("hello","zhangsan","liss","liuqiang");

        List<String> result=filterStr(list, (e)->e.length()>4);
        for(String list2:result){
            System.out.println(list2);
        }

    }
    // 需求:将满足条件的字符串放入到集合中

    public List<String> filterStr(List<String> list, Predicate<String> predicate) {
        List<String> list2 = new ArrayList<>();
        for (String s : list) {
            if (predicate.test(s)) {
                list2.add(s);
            }
        }
        return list2;
    }

    // 函数型接口Function<T,R> T 为参数类型,R为返回值类型
    @Test
    public void test3() {
        String string = strHandler("   平顶山学院   ", (e) -> e.trim());
        System.out.println(string);
        String string2 = strHandler("adeFdsgssadf", (e) -> e.toUpperCase());
        System.out.println(string2);
        String string3 = strHandler("weidianlun,zhangsanling,dingpiengju", (e) -> e.subSequence(2, 5).toString());
        System.out.println(string3);

    }

    // 需求用于处理字符串
    public String strHandler(String string, Function<String, String> function) {
        return function.apply(string);

    };

    // 供给型接口Supplier<T>
    @Test
    public void test2() {
        List<Integer> list = getNumList(10, () -> (int) (Math.random() * 100));
        for (Integer i : list) {
            System.out.print("-" + i);
        }
    }

    // 产生一些整数,并放入到集合中
    public List<Integer> getNumList(int num, Supplier<Integer> su) {
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < num; i++) {
            Integer integer = su.get();
            list.add(integer);
        }
        return list;
    }

    // Consumer<T> 消费型接口
    @Test
    public void test1() {
        xiaofei(1000d, (e) -> System.out.println("每次消费" + e + "元"));
    }

    public void xiaofei(Double money, Consumer<Double> consumer) {
        consumer.accept(money);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uniquewdl

匆忙的人生,总有你喜欢的文章

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值