美文网首页
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