JDK1.8新特性

JDK1.8重点新特性

一、接口中默认方法修饰为普通方法

  1. 在jdk8之前,interface之中可以定义变量和方法,变量必须是public、static、final的,方法必须是public、abstract的,这些修饰符都是默认的。
  2. 在JDK 1.8开始 支持使用static和default 修饰 可以写方法体,不需要子类重写。
public interface Jdk18Interface {

    void addUser();

    /**
     * 默认方法,可以写方法体
     */
    default void getDefaultUser(){
        System.out.println("我是默认方法  可以写方法体");
    }

    /**
     * 静态方法,可以写方法体
     */
    static void getStaticUser(){
        System.out.println("我是静态方法 可以写方法体 ");
    }
}
public class Jdk18InterfaceImpl implements Jdk18Interface{

    /**
     * 默认和静态方法不是抽象方法 ,所以不需要重写
     */
    @Override
    public void addUser() {
        System.out.println("addUser");
    }
}

二、Lambda表达式

1、 Lambda优点,简化匿名内部类的调用

public static void main(String[] args) {
	 // 1.使用new的实现类的形式调用接口
	  StudentService service = new StudentServiceImpl();
	  service.addUser();
	
	  // 2.使用匿名内部接口调用
	  new StudentService() {
	      @Override
	      public void addUser() {
	          System.out.println("使用匿名内部类形式调用接口");
	      }
	  }.addUser();
	
	  //3.使用lambda调用接口
	  StudentService services = ()->{System.out.println("使用lambda调用接口");};
	  services.addUser();
}

2、 Lambda表达式的规范

使用Lambda表达式 依赖于函数接口
1.在接口中只允许有一个抽象方法
2.在函数接口中可以定义object类中方法
3.可以使用默认default或者静态static方法
4.@FunctionalInterface 表示该接口为函数接口

@FunctionalInterface
public interface StudentService {
    void addUser();

    /**
     * 定义默认方法
     */
    default void getUser(){

    }

    /**
     * 定义Object中的方法
     */
    String toString();
}
JDK中自带的函数接口:
java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener

3、 Lambda语法

()—参数列表
-> 分隔
{} 方法体
(函数接口的参数列表 不需要写类型 需要定义参数名称)->{方法体}

3.1 无参方法调用

@FunctionalInterface
public interface StudentService {
    void addUser();

    /**
     * 定义默认方法
     */
    default void getUser(){

    }

    /**
     * 定义Object中的方法
     */
    String toString();
}
public static void main(String[] args) {
        //无参方法调用
        StudentService service = ()->{
            System.out.println("使用lamdba表达式调用方法");
        };
        service.addUser();
    }

3.2 带参数和返回值方法调用

@FunctionalInterface
public interface StudentService {
    String get(int i,int j);
}
public static void main(String[] args) {
   //带参数和返回值
    StudentService service = (i,j)->{
        return i + "---" + j;
    };
    System.out.println(service.get(1,3));

	//精简后
    StudentService service1 = (i,j)-> i + "---" + j;
    System.out.println(service1.get(1,3));
}

4、 Lambda示例说明

4.1 集合遍历

public static void main(String[] args) {
    ArrayList<String> list = new ArrayList<>();
    list.add("张三");
    list.add("李四");
    list.add("王五");
    list.add("陈六");

    //遍历
    list.forEach(new Consumer<String>() {
        @Override
        public void accept(String s) {
            System.out.println(s);
        }
    });

    //使用lambda方式遍历
    list.forEach((s)->{
        System.out.println(s);
    });
}

4.2 集合排序

public static void main(String[] args) {
   List<UserEntry> list = new ArrayList<>();
   list.add(new UserEntry("张三",22));
   list.add(new UserEntry("李四",55));
   list.add(new UserEntry("王五",77));
   list.add(new UserEntry("陈六",32));

   //匿名内部类排序
   list.sort(new Comparator<UserEntry>() {
       @Override
       public int compare(UserEntry o1, UserEntry o2) {
           return o1.getAge() - o2.getAge();
       }
   });

   //使用lambda方式排序
   list.sort((o1,o2)->{
       return o1.getAge() - o2.getAge();
   });

   //遍历
   list.forEach((Consumer) o->{
       System.out.println(o.toString());
   });
}

三、stream流

1、 stream流可以指定对集合进行操作,执行非常复杂的查找、过滤和映射数据等操作。精简集合的遍历形式,实现集合 过滤、排序等。

1.1 stream流的中间操作

filter过滤器
distinct去重
sorted排序
limit分页

1.2 stream流的终止操作

forEach遍历
collect转换
min、max聚合
allMatch条件(所有元素匹配)
anyMatch条件(任意一个元素匹配)
noneMatch条件(所有元素都不匹配)

2、 Stream创建方式

parallelStream为并行流采用多线程执行
Stream采用单线程执行
parallelStream效率比Stream要高
区别:
串行流:单线程的方式操作; 数据量比较少的时候。
并行流:多线程方式操作;数据量比较大的时候,原理:
Fork join 将一个大的任务拆分n多个小的子任务并行执行,
最后在统计结果,有可能会非常消耗cpu的资源。

3、 Stream具体使用,操作集合

3.1 Stream将List转换为Set

public static void main(String[] args) {
    List<UserEntry> list = new ArrayList<>();
    list.add(new UserEntry("张三",22));
    list.add(new UserEntry("李四",55));
    list.add(new UserEntry("王五",77));
    list.add(new UserEntry("陈六",32));

    //List集合转为Set
    Set<UserEntry> collect = list.stream().collect(Collectors.toSet());
    System.out.println(collect);
}

3.2 Stream将List转换为Map

public static void main(String[] args) {

    List<UserEntry> list = new ArrayList<>();
    list.add(new UserEntry("张三", 22));
    list.add(new UserEntry("李四", 55));
    list.add(new UserEntry("王五", 77));
    list.add(new UserEntry("陈六", 32));

    //将list转换为Map
    // key 为string 类型, value为 UserEntity  集合中的数据:UserEntity
    Map<String, UserEntry> collect = list.stream().collect(Collectors.toMap(
            new Function<UserEntry, String>() {
                @Override
                public String apply(UserEntry userEntry) {
                    return userEntry.getName();
                }
            },
            new Function<UserEntry, UserEntry>() {
                @Override
                public UserEntry apply(UserEntry userEntry) {
                    return userEntry;
                }
            }));

    // 普通遍历
    collect.forEach(new BiConsumer<String, UserEntry>() {
        @Override
        public void accept(String s, UserEntry userEntry) {
            System.out.println(s + ":" + userEntry.toString());
        }
    });

    //lambda方式遍历
    collect.forEach((s, userEntry) -> {
        System.out.println(s + ":" + userEntry.toString());
    });
}

3.3 Stream将Reduce 求和

public static void main(String[] args) {

    //Stream.of()创建整数流
    Stream<Integer> integerStream = Stream.of(10, 20, 30, 40);
    //使用匿名内部类方式
    Optional<Integer> reduce2 = integerStream.reduce(new BinaryOperator<Integer>() {
        @Override
        public Integer apply(Integer integer, Integer integer2) {
            return integer + integer2;
        }
    });
    System.out.println(reduce2.get());

    //使用lambda方式简化匿名内部类的调用
    Optional<Integer> reduce1 = integerStream.reduce((a1, a2) -> {
        return a1 + a2;
    });
    System.out.println(reduce1.get());

    //对象中的属性求和
    List<UserEntry> list = new ArrayList<>();
    list.add(new UserEntry("张三", 22));
    list.add(new UserEntry("李四", 55));
    list.add(new UserEntry("王五", 77));
    list.add(new UserEntry("陈六", 32));

    //使用reduce求和
    Optional<UserEntry> reduce = list.stream().reduce((userEntry1, userEntry2) -> {
        userEntry1.setAge(userEntry1.getAge() + userEntry2.getAge());
        return userEntry1;
    });
    System.out.println(reduce.get());
}

3.4 Stream Max和Min

public static void main(String[] args) {
    List<UserEntry> list = new ArrayList<>();
    list.add(new UserEntry("张三", 22));
    list.add(new UserEntry("李四", 55));
    list.add(new UserEntry("王五", 77));
    list.add(new UserEntry("陈六", 32));

    //找到年龄最大的的学生
    Optional<UserEntry> max = list.stream().max(new Comparator<UserEntry>() {
        @Override
        public int compare(UserEntry o1, UserEntry o2) {
            return o1.getAge() - o2.getAge();
        }
    });
    System.out.println(max.get());

    //lambda方式 找到年龄最大的的学生
    Optional<UserEntry> max1 = list.stream().max((o1, o2) -> {
        return o1.getAge() - o2.getAge();
    });
    System.out.println(max1.get());

    //lambda方式 找到年龄最小的的学生
    Optional<UserEntry> min = list.stream().min((o1, o2) -> {
        return o1.getAge() - o2.getAge();
    });
    System.out.println(min.get());
}

3.5 Stream Match 匹配

3.5.1 anyMatch表示,判断的条件里,任意一个元素成功,返回true
public static void main(String[] args) {
    //使用Stream.of方法 创建对象流
    Stream<UserEntry> userEntryStream = Stream.of(
            new UserEntry("张三", 22),
            new UserEntry("李四", 55),
            new UserEntry("王五", 77),
            new UserEntry("陈六", 32),
            new UserEntry("陈六", 50)
    );

    //判断集合中是否存在学生陈六,年龄大于40
    boolean flag = userEntryStream.anyMatch(new Predicate<UserEntry>() {
        @Override
        public boolean test(UserEntry userEntry) {
            return userEntry.getName().equals("陈六") && userEntry.getAge() > 40;
        }
    });
    System.out.println(flag);

    //使用lambda方式
    boolean flag2 = userEntryStream.anyMatch((userEntry) -> {
        return userEntry.getName().equals("陈六") && userEntry.getAge() > 40;
    });
    System.out.println(flag2);
}
3.5.2 allMatch表示,判断条件里的元素,所有的都是,返回true
public static void main(String[] args) {

  //使用Stream.of方法 创建对象流
    Stream<UserEntry> userEntryStream = Stream.of(
            new UserEntry("张三", 22),
            new UserEntry("李四", 55),
            new UserEntry("王五", 77),
            new UserEntry("陈六", 32),
            new UserEntry("陈六", 50)
    );

    //判断集合中的对象属性名称是否都是陈六,且年龄是40岁
    boolean flag = userEntryStream.allMatch((userEntry) -> {
        return userEntry.getName().equals("陈六") && userEntry.getAge() == 40;
    });
    System.out.println(flag);
}

3.5 Stream 过滤器filter()

public static void main(String[] args) {
    Stream<UserEntry> userEntryStream = Stream.of(
            new UserEntry("张三", 22),
            new UserEntry("李四", 55),
            new UserEntry("王五", 77),
            new UserEntry("陈六", 15),
            new UserEntry("陈六", 32),
            new UserEntry("陈六", 60),
            new UserEntry("陈六", 90)
    );

    //查找集合中,年龄大于30岁,姓名是陈六的学生
   userEntryStream.filter((userEntry) -> {
        return userEntry.getAge() > 30 && userEntry.getName().equals("陈六");
    }).forEach((userEntry)->{
       System.out.println(userEntry.toString());
   });
}

3.6 Stream 过滤器sorted()

public static void main(String[] args) {
    Stream<UserEntry> userEntryStream = Stream.of(
            new UserEntry("张三", 22),
            new UserEntry("李四", 55),
            new UserEntry("王五", 77),
            new UserEntry("陈六", 15),
            new UserEntry("陈六", 32),
            new UserEntry("陈六", 60),
            new UserEntry("陈六", 90)
    );

    //根据年龄升序排列数据
    userEntryStream.sorted((userEntry1,userEntry2)->{
        return userEntry1.getAge() -userEntry2.getAge();
    }).forEach(userEntry -> System.out.println(userEntry.toString()));
}

3.7 Stream limit(从头开始获取)和skip(跳过)

3.7.1 limit
public static void main(String[] args) {
  Stream<UserEntry> userEntryStream = Stream.of(
           new UserEntry("张三", 22),
           new UserEntry("李四", 55),
           new UserEntry("王五", 77),
           new UserEntry("陈六", 15),
           new UserEntry("陈六", 32),
           new UserEntry("陈六", 60),
           new UserEntry("陈六", 90)
   );
   
   //从集合中取前3个对象输出
   userEntryStream.limit(3).forEach(userEntry -> System.out.println(userEntry.toString()));
}
3.7.2 skip
public static void main(String[] args) {
  Stream<UserEntry> userEntryStream = Stream.of(
            new UserEntry("张三", 22),
            new UserEntry("李四", 55),
            new UserEntry("王五", 77),
            new UserEntry("陈六", 15),
            new UserEntry("陈六", 32),
            new UserEntry("陈六", 60),
            new UserEntry("陈六", 90)
    );

    //从集合中取前3个对象输出
    userEntryStream.limit(3).forEach(userEntry -> System.out.println(userEntry.toString()));
}

3.8 Stream of()

1、Stream.of用于为给定元素创建顺序流,可以传递单个参数,也可以传递多个参数,创建的是有限元素流。
2、Stream.generate方法可以创建无限元素流;
示例1:创建整数流
Stream integerStream = Stream.of(10, 20, 30, 40);
示例2:创建字符串流
Stream integerStream = Stream.of(“张三”, “李四”, “王五”, “陈六”);
示例3:创建对象流
Stream userEntryStream = Stream.of(
new UserEntry(“张三”, 22),
new UserEntry(“李四”, 55),
new UserEntry(“王五”, 77),
new UserEntry(“陈六”, 15),
new UserEntry(“陈六”, 32),
new UserEntry(“陈六”, 60),
new UserEntry(“陈六”, 90)
);

你可能感兴趣的:(java,java,JDK1.8)