美文网首页
Java8 新特征

Java8 新特征

作者: 潜心之力 | 来源:发表于2019-08-23 10:43 被阅读0次
    一、操作集合
    定义实体类
    public class User{
      private Integer id;
      private String name;
      CONSTRUCTOR; -> 省略构造方法
      GETTER AND SETTER; -> 省略属性的方法
    
      @Override
      public boolean equals(Object obj) { -> distinct()
          if (obj instanceof User) {
              return this.getId().equals(((User) obj).getId());
          }
          return false;
      }
    
      @Override
      public int hashCode() { -> distinct()
          return this.getId();
      }
    }
    
    定义对象集合
    List<User> list = new ArrayList<>();
    User w = new User(1,"w");
    User j = new User(2,"j");
    User x = new User(3,"x");
    list.add(w);
    list.add(j);
    list.add(x);
    
    集合对象通过ID属性分组
    Map<Integer,List<User>> map = list.stream()
    .collect(Collectors.groupingBy(User::getId));
    
    集合通过自定义条件分组
    Map<Boolean,List<String>> map = list.stream()
    .map(User::getName)
    .collect(partitioningBy(s -> s.length() > 1));
    
    集合对象通过ID属性排序
    list.stream().sorted(Comparator.comparing(User::getId));
    list.stream().sorted(); -> 自然排序
    list.stream().sorted(Comparator.reverseOrder()); -> 自然逆向排序
    
    集合对象通过ID属性过滤
    List<User> filter = list.stream() -> 保留符合条件的元素
    .filter(user -> user.getId().equals(1)).collect(Collectors.toList());
    
    集合过滤重复对象
    list = list.stream().distinct().collect(Collectors.toList());
    
    取出集合前i个对象
    list = list.stream().limit(i).collect(Collectors.toList());
    
    忽略集合前i个对象
    list = list.stream().skip(i).collect(Collectors.toList());
    
    集合对象的ID属性求和
    BigDecimal decimal = list.stream()
    .map(User::getId)
    .reduce(BigDecimal.ZERO, BigDecimal::add);
    
    集合的属性拼接
    String join = list.stream()
    .map(User::getName)
    .collect(Collectors.joining("-","start","end"));
    
    操作集合对象的属性
    list = list.stream().peek(l -> l.setId(l.getId()*i))
    .collect(Collectors.toList());
    
    集合对象通过ID属性排重
    List<User> unique = list.stream()
    .collect(collectingAndThen(
    toCollection(() -> new TreeSet<>(
    comparingLong(User::getId))),ArrayList::new));
    
    获取集合对象里的ID属性的集合
    List<Integer> ids = list.stream()
    .map(User::getId) -> ID的GETTER方法
    .collect(Collectors.toList());
    
    MAP集合
    1、keyMapper:Key的映射函数 2、valueMapper:Value的映射函数
    3、mergeFunction:Key冲突时Value的合并函数 4、mapSupplier:Map的构造器
    Map<Integer,User> map = list.stream()
    .collect(Collectors.toMap(User::getId,Function.identity())); -> key为Id,value为自身对象
    Map<Integer,User> map = list.stream()
    .collect(Collectors.toMap(User::getId,o -> o,
    (oldValue,newValue) -> oldValue,HashMap::new)); -> key为Id,value为自身对象
    Map<Integer,User> map = list.stream()
    .collect(Collectors.toMap(User::getId,User::getName)); -> key为Id,value为Name
    
    Set集合(List有序允许重复值,Set无序不允许重复值)
    Stream<String> name = Stream.of("w","j","x");
    Set<String> set = name.collect(Collectors.toSet());
    
    []数组
    User[] array = list.stream().toArray(User[]::new);
    User[] array = list.toArray();
    
    集合长度
    long count = list.stream().count();
    long count = list.stream().collect(Collectors.counting());
    
    元素匹配
    boolean b = list.stream().anyMatch(user -> user.getId().equals(1)); -> 任意成立
    boolean b = list.stream().allMatch(user -> user.getId().equals(1)); -> 全部成立
    boolean b = list.stream().noneMatch(user -> user.getId().equals(1)); -> 全部不成立
    
    流的扁平化
    String[] array = {"flat","map"};
    List<String> list = Arrays.stream(array).map(str -> str.split(""))
    .flatMap(Arrays::stream).collect(Collectors.toList());
    List<String> list = Stream.of(array).flatMap(str -> 
    Arrays.stream(str.split(""))).collect(Collectors.toList());
    
    自定义集合类型
    List<String> collection = list.stream()
    .map(User::getName) 
    .collect(Collectors.toCollection(ArrayList::new));
    
    串行流和并行流
    list.stream().foreach(System.out::println); -> 串行流有序
    list.parallelStream().foreachOrdered(System.out::println); -> 并行流无序
    
    IntSummaryStatistics statistics = list.stream()
    .collect(Collectors.summarizingInt(User::getId));
    statistics.getMax(); -> 最大值
    statistics.getMin(); -> 最小值
    statistics.getAverage(); -> 平均值
    statistics.getSum(); -> 总值
    
    Integer[] number = {1,2,3,4,5,6,7,8,9};
    Arrays.stream(number).collect(Collectors.averagingInt(Integer::new)); -> 平均值
    Arrays.stream(number).collect(Collectors.summingInt(Integer::new)); -> 总值
    Arrays.stream(number).mapToInt(Integer::new).sum()); -> 总值
    Optional<Integer> max = Arrays.stream(number).collect(Collectors.maxBy(Integer::max));
    Optional<Integer> min = Arrays.stream(number).collect(Collectors.minBy(Integer::min));
    Optional<Integer> max = Arrays.stream(number).max(Comparator.comparing(Function.identity()));
    Optional<Integer> min = Arrays.stream(number).min(Comparator.naturalOrder());
    
    Optional<Object> obj = Optional.empty(); -> 创建一个空的Optional对象
    Optional<Object> obj = Optional.of(new Object()); -> 创建一个非空的Optional对象
    Optional<Object> obj = Optional.ofNullable(null); -> 创建一个可空的Optional对象
    
    obj.isPresent(); -> 对象是否存在
    obj.get(); -> 获取对象,不存在时会抛出异常
    obj.orElseGet(()->new Object()); -> 存在时返回原有对象,反之返回入参
    obj.ifPresent((obj) -> { ... }); -> 对象存在时执行方法体
    obj.orElse(new Object()); -> 对象存在时返回原有对象,反之返回入参
    obj.orElseThrow(RuntimeException::new); -> 对象不存在时抛出自定义异常
    obj.map(Object::getObject); -> 返回值自动被Optional包装
    obj.flatMap(obj -> Optional.empty()); -> 返回值需要手动包装Optional
    
    Map<String, Integer> map = Maps.newHashMap();
    map.put("x", 3);
    map.put("j", 2);
    map.put("w", 1);
    
    Map通过value顺序排序
    Map<String, Integer> order = map.entrySet().stream()
            .sorted(Map.Entry.comparingByValue(Comparator.naturalOrder()))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                    (oldValue, newValue) -> oldValue, LinkedHashMap::new));
    
    Map通过value倒序排序
    Map<String, Integer> reverse1 = map.entrySet().stream()
            .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                    (oldValue, newValue) -> oldValue, LinkedHashMap::new));
    Map<String, Integer> reverse2 = new LinkedHashMap<>();
    map.entrySet().stream().sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
            .forEachOrdered(x -> reverse.put(x.getKey(), x.getValue()));
    
    二、循环迭代
    List<String> list = Arrays.asList("w","j","x");
    
    普通版
    for(int i=0;i<list.size();i++){
      String str = list.get(i);
    }
    
    增强版
    for(String str:list){
      System.out.println(str);
    }
    
    迭代器
    Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()){
      System.out.println(iterator.next());
    }
    
    Java8
    list.forEach(new Consumer<String>() {
        @Override
        public void accept(String s) {
            System.out.println(s);
        }
    });
    
    Lambda表达式
    list.forEach(str -> System.out.println(str));
    
    Map<String,String> map = new HashMap<>();
    map.put("name","wjx");
    map.put("age","20");
    
    普通版
    for (Map.Entry<String,String> entry:map.entrySet()){
      String key =  entry.getKey();
      String value = entry.getValue();
    }
    
    key版
    for (String key:map.keySet()){
        String value = map.get(key);
    }
    
    value版
    for (String value:map.values()){
        System.out.println(value);
    }
    
    迭代器
    Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
    while (iterator.hasNext()){
      Map.Entry<String, String> entry = iterator.next();
      String key =  entry.getKey();
      String value = entry.getValue();
    }
    
    Java8
    map.forEach(new BiConsumer<String, String>() {
      @Override
      public void accept(String key, String value) {
        System.out.println(key);
        System.out.println(value);
      }
    });
    
    Lambda表达式
    map.forEach((k,v) -> System.out.println(k+v);
    
    三、函数式接口
    • 只包含一个抽象方法,可以包含多个静态方法和默认方法,可以定义Java.Lang.Object类的所有方法
    • @FunctionalInterface,声明在函数式接口上,如果接口上存在多个抽象方法则会编译报错,但函数式接口不一定用此注解
    • JDK8前的接口方法修饰符为abstract,必须由实现类重写方法。JDK8新引入default和static修饰符,支持方法体,实现类可以不重写方法。接口方法默认修饰符为public,方法同样不能被private和protected修饰符修饰。
    @FunctionalInterface
    public interface Runnable {
        public abstract void run();
    }
    
    new Thread(new Runnable() { -> 传统写法
        @Override
        public void run() {
          System.out.println("Thread is started");
        }
    }).start();
    
    new Thread(()->{ -> Lambda写法
      System.out.println("Thread is started");
    }).start();
    
    • default 修饰接口方法
    default void method(){ -> 可继承,通过类对象调用方法
        System.out.println("default method");
    }
    
    • static 修饰接口方法
    static void method(){ -> 不可继承,通过类名调用方法
        System.out.println("static method");
    }
    
    • Supplier 提供者,接口方法不接受参数,提供返回值
    Supplier<String> supplier = () -> "supplier"; -> 重写get()
    System.out.println(supplier.get());
    
    • Consumer 消费者,接口方法接受参数,不提供返回值
    Consumer<String> println = (s) -> System.out.println(s); -> 重写accept()
    println.accept("consumer");
    
    • Function 函数,接受参数,提供返回值
    Function<Integer, Integer> function = (i) -> i * i; -> 重写apply()
    Function<Integer, Integer> function = square(i); -> 调用方法
    Function<Integer, Integer> function = Math::square; -> 引用方法
    System.out.println(function.apply(5));
    
    • Predicate 函数,接受参数,提供Boolean类型的返回值
    Predicate<Integer> predicate = (i) -> i % 2 == 0; -> 重写test()
    System.out.println(predicate.test(5));
    
    四、时间日期
    • LocalDateTime、LocalDate、LocalTime
    LocalDateTime localDateTime = LocalDateTime.now(); -> 日期时间
    LocalDate localDate = LocalDate.now(); -> 日期
    LocalTime localTime = LocalTime.now(); -> 时间
    
    long mills = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
    LocalDateTime time = LocalDateTime.parse("2020-01-01 00:00:00.1",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"));
    
    localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); -> 格式化
    
    .with*:替代
    例:localDateTime.withDayOfYear(1); -> 当前日期替换为一年的第一天(一月一日)
    .plus*:加法
    例:localDateTime.plusDays(1); -> 当前日期加一日(明天)
    .minus*:减法
    例:localDateTime.minusDays(1); -> 当前日期减一日(昨天)
    
    boolean before = x.isBefore(y); -> 日期x小于日期y
    boolean equal = x.isEqual(y); -> 日期x等于日期y
    boolean after = x.isAfter(y); -> 日期x大于日期y
    
    • Period 日期周期
    LocalDate localDate1 = LocalDate.of(2020,1,1);
    LocalDate localDate2 = LocalDate.of(2020,1,2);
    System.out.println(localDate1.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
    System.out.println(localDate2.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
    
    Period period = Period.between(localDate1,localDate2); -> 获取两个日期间的周期
    long year = period.getYears(); -> 获取年之间的周期(0)
    long month = period.getMonths(); -> 获取月之间的周期(0)
    long day = period.getDays(); -> 获取日之间的周期(1)
    boolean negative = period.isNegative(); -> 周期是否为负数(false)
    
    • Duration 时间周期
    LocalDateTime localDateTime1 = LocalDateTime.of(2020, 1, 1, 0, 0);
    LocalDateTime localDateTime2 = LocalDateTime.of(2020, 1, 1, 0, 1);
    System.out.println(localDateTime1.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
    System.out.println(localDateTime2.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
    
    Duration duration = Duration.between(localDateTime1, localDateTime2);
    long day = duration.toDays(); -> 获取日之间的周期(0)
    long hour = duration.toHours(); -> 获取时之间的周期(0)
    long minute = duration.toMinutes(); -> 获取分之间的周期(1)
    long second = duration.getSeconds(); -> 获取秒之间的周期(60)
    long millis = duration.toMillis(); -> 获取毫秒之间的周期(60000)
    boolean negative = duration.isNegative(); -> 周期是否为负数(false)
    
    • 传统日期获取与运算
    Calendar calendar = Calendar.getInstance(); -> 获取单例
    
    Calendar calendar = new GregorianCalendar();
    calendar.setTime(new Date(System.currentTimeMillis())); -> 获取当前毫秒时间戳
    calendar.add(Calendar.DATE, 2); -> 大于零追加,小于零回退
    
    public static String dateToStamp(String date) throws Exception { -> 日期转时间戳
      SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      Date date = format .parse(date);
      long time = date.getTime();
      return String.valueOf(time);
    }
    
    public static String stampToDate(String stamp) throws Exception { -> 时间戳转日期
      SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      long lt = new Long(s);
      Date date = new Date(lt);
      return format.format(date);
    }
    
    private boolean compare(String date1,String date2) { -> 日期比较大小
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date actual = format.parse(date1);
            Date current = format.parse(date2);
            current.after(actual) | current.before(actual); -> 缺点是无法比较同一日
            return current.compareTo(actual) >= 0; -> 大于1、等于0、小于-1
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return false;
    }
    
    • 长日期转为短日期
    Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+8"));
    calendar.setTime(new Date());
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    Long millis = calendar.getTimeInMillis(); -> 获取长整型
    Date time = calendar.getTime(); -> 获取日期
    
    • 输出年中的每一日
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    Calendar calendar = Calendar.getInstance();
    for (int i = 0; i < 12; i++) {
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, i);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        int count = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        for (int j = 0; j < count; j++) {
            System.out.println(format.format(calendar.getTime()));
            int day = calendar.get(Calendar.DAY_OF_WEEK);
            if (day == Calendar.SUNDAY || day == Calendar.SATURDAY) {
                System.out.println("周末");
            }
            calendar.add(Calendar.DAY_OF_MONTH, 1);
        }
    }
    
    field 描述
    YEAR
    MONTH
    DATE
    HOUR_OF_DAY
    MINUTE
    SECOND
    MILLISECOND 毫秒
    DAY_OF_YEAR 一年中的第几日
    DAY_OF_MONTH 一月中的第几日
    DAY_OF_WEEK 一周中的第几日
    DAY_OF_WEEK_IN_MONTH 一月中的第几周
    WEEK_OF_YEAR 一年中的第几周
    WEEK_OF_MONTH 一月中的第几周

    相关文章

      网友评论

          本文标题:Java8 新特征

          本文链接:https://www.haomeiwen.com/subject/qgbsjctx.html