1、对底层数据结构的改变,体现在诸如(hashmap,要写一篇专门的日志详解)
2、对底层的内存结构也变得不一样了,元空间metespace。原来的方法区
3、最为核心的是Lambda表达式与StreamAPI

Lambda

  • lambda是一个匿名函数(方法),我们可以把lambda表达式理解为,一段可以传递的代码。

直观感受Lambda效果
Pojo类

  1. public class Employee {
  2. private String name;
  3. private Integer age;
  4. private Double salary;
  5. public Employee(){
  6. }
  7. public Employee(String name, Integer age, Double salary){
  8. this.name = name;
  9. this.age = age;
  10. this.salary = salary;
  11. }
  12. public String getName() {
  13. return name;
  14. }
  15. public void setName(String name) {
  16. this.name = name;
  17. }
  18. public Integer getAge(){
  19. return age;
  20. }
  21. public void setAge(Integer age){
  22. this.age = age;
  23. }
  24. public void setSalary(Double salary){
  25. this.salary = salary;
  26. }
  27. public Double getSalary(){
  28. return salary;
  29. }
  30. @Override
  31. public String toString() {
  32. return "Employee{" +
  33. "name='" + name + '\'' +
  34. ", age=" + age +
  35. ", salary=" + salary +
  36. '}';
  37. }
  38. }
  1. List<Employee> employees = Arrays.asList(
  2. new Employee("张三",18,3318.44),
  3. new Employee("李四",15,2238.44),
  4. new Employee("王五",16,5627.44),
  5. new Employee("赵六",23,9274.44),
  6. new Employee("田七",54,8888.44)
  7. );

需求://获取公司员工年龄大于35的员工信息
//获取当前公司中员工工资大于5000的员工信息

  1. //获取当前公司中员工工资大于5000的员工信息
  2. public List<Employee> filterEmployees2(List<Employee> list){
  3. List<Employee> emps = new ArrayList<>();
  4. for (Employee emp : list){
  5. if(emp.getSalary() > 5000){
  6. emps.add(emp);
  7. }
  8. }
  9. return emps;
  10. }
  11. @Test
  12. public void test3(){
  13. List<Employee> emps = filterEmployees2(employees);
  14. for (Employee employee : emps){
  15. System.out.println(employee);
  16. }
  17. }
  18. //获取公司员工年龄大于35的员工信息
  19. public List<Employee> filterEmployees(List<Employee> list){
  20. List<Employee> emps = new ArrayList<>();
  21. for (Employee emp : list){
  22. if(emp.getAge() >20){
  23. emps.add(emp);
  24. }
  25. }
  26. return emps;
  27. }
  28. @Test
  29. public void test2(){
  30. List<Employee> emps = filterEmployees(employees);
  31. for (Employee employee : emps){
  32. System.out.println(employee);
  33. }
  34. }

优化方式一:策略设计模式+匿名内部类
设计接口:

  1. public interface MyPredicate<T> {
  2. public boolean test(T t);
  3. }

实现需求:

  1. public List<Employee> filterEmployee(List<Employee> list,MyPredicate<Employee> mp){
  2. List<Employee> emps = new ArrayList<>();
  3. for (Employee emp : list){
  4. if(mp.test(emp)){
  5. emps.add(emp);
  6. }
  7. }
  8. return emps;
  9. }
  10. @Test
  11. public void test6(){
  12. List<Employee> emps =filterEmployee(employees, new MyPredicate<Employee>(){
  13. @Override
  14. public boolean test(Employee employee) {
  15. return employee.getAge()<20;
  16. }
  17. });
  18. for(Employee employee: emps){
  19. System.out.println(employee);
  20. }
  21. }
  22. @Test
  23. public void test7(){
  24. List<Employee> emps =filterEmployee(employees, new MyPredicate<Employee>(){
  25. @Override
  26. public boolean test(Employee employee) {
  27. return employee.getSalary()<5000;
  28. }
  29. });
  30. for(Employee employee: emps){
  31. System.out.println(employee);
  32. }
  33. }

优化方式二: Lambda表达式
将上述的匿名内部类写的更简洁。

  1. public List<Employee> filterEmployee(List<Employee> list,MyPredicate<Employee> mp){
  2. List<Employee> emps = new ArrayList<>();
  3. for (Employee emp : list){
  4. if(mp.test(emp)){
  5. emps.add(emp);
  6. }
  7. }
  8. return emps;
  9. }
  10. @Test
  11. public void test8(){
  12. List<Employee> emps = filterEmployee(employees,(e) -> e.getSalary() < 5000);
  13. emps.forEach(System.out::println);
  14. }

优化方式三:Stream API

  1. @Test
  2. public void test9(){
  3. employees.stream()
  4. .filter((e)->e.getSalary()<5000)
  5. .forEach(System.out::println);
  6. }

Lambda表达式的语法

java8中引入了一个新的操作符“->”该操作符将Lambda表达式拆分为两部分。
左侧:Lambda表达式的参数列表
右侧:Lambda表达式中所需执行的功能,即Lambda体。
Lambda表达式需要“函数式接口”的支持。
函数式接口:接口中只有一个抽象方法。可以使用注解@FunctionalInterface修饰

语法格式一:无参数,无返回值
() -> System.out.println("Hello Lambda!");

  1. @Test
  2. public void test10(){
  3. int num = 99; //在jdk1.8以前,规则:在局部内部类中用了同级别的局部变量时,该变量必须被final修饰。
  4. //jdk1.8之后,不需要手动final修饰了,自动final修饰。
  5. Runnable r = new Runnable() {
  6. @Override
  7. public void run() {
  8. System.out.println("Hello World!" + num);
  9. }
  10. };
  11. r.run();
  12. System.out.println("------------");
  13. Runnable r1 = () -> System.out.println("Hello Lambda!" + num);
  14. r1.run();
  15. }

语法格式二:有一个参数,并且无返回值。
(x) -> System.out.println(x);

  1. @Test
  2. public void test11(){
  3. Consumer<String> con = (x) -> System.out.println(x);
  4. con.accept("朱柳洪牛逼");
  5. }

语法格式三:若只有一个参数,小括号可以省略不写
x -> System.out.println(x);

  1. @Test
  2. public void test12(){
  3. Consumer<String> con = x -> System.out.println(x);
  4. con.accept("朱柳洪牛逼");
  5. }

语法格式四:有两个及以上的参数,有返回值,并且Lambda体中有多条语句。

  1. @Test
  2. public void test13(){
  3. Comparator<Integer> comparator = (x, y) -> {
  4. System.out.println("朱柳洪牛逼");
  5. return Integer.compare(x,y);
  6. };
  7. }

语法格式五:若Lambda体中只有一条语句,return和大括号都可以省略不写。

  1. @Test
  2. public void test14(){
  3. Comparator<Integer> comparator = (x, y) -> Integer.compare(x,y);
  4. }

语法格式六:Lambda中的 参数列表的数据类型可以不写,因为JVM编译器通过上下文推断出数据类型,即“类型推断”。
Java8中有许多可以类型推断,而Java7中不可以的地方。