java8新特性(并行流、串行流、optional容器、接口中的默认方法、时间API、重复注解、类型注解)
public class ForkJoinCalculate extends RecursiveTask<Long>{ /** * */ private static final long serialVersionUID = 13475679780L; private long start; private long end; private static final long THRESHOLD = 10000L; //临界值 public ForkJoinCalculate(long start, long end) { this.start = start; this.end = end; } @Override protected Long compute() { long length = end - start; if(length <= THRESHOLD){ long sum = 0; for (long i = start; i <= end; i++) { sum += i; } return sum; }else{ long middle = (start + end) / 2; ForkJoinCalculate left = new ForkJoinCalculate(start, middle); left.fork(); //拆分,并将该子任务压入线程队列 ForkJoinCalculate right = new ForkJoinCalculate(middle+1, end); right.fork(); return left.join() + right.join(); } } }
@Test public void test1(){ long start = System.currentTimeMillis(); ForkJoinPool pool = new ForkJoinPool(); ForkJoinTask<Long> task = new ForkJoinCalculate(0L, 10000000000L); long sum = pool.invoke(task); System.out.println(sum); long end = System.currentTimeMillis(); System.out.println("耗费的时间为: " + (end - start)); //112-1953-1988-2654-2647-20663-113808 } @Test public void test2(){ long start = System.currentTimeMillis(); long sum = 0L; for (long i = 0L; i <= 10000000000L; i++) { sum += i; } System.out.println(sum); long end = System.currentTimeMillis(); System.out.println("耗费的时间为: " + (end - start)); //34-3174-3132-4227-4223-31583 } @Test public void test3(){ long start = System.currentTimeMillis(); Long sum = LongStream.rangeClosed(0L, 10000000000L) .parallel() .sum(); System.out.println(sum); long end = System.currentTimeMillis(); System.out.println("耗费的时间为: " + (end - start)); //2061-2053-2086-18926 }
一、Optional 容器类:用于尽量避免空指针异常
Optional.of(T t) : 创建一个 Optional 实例
Optional.empty() : 创建一个空的 Optional 实例
Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例
isPresent() : 判断是否包含值
orElse(T t) : 如果调用对象包含值,返回该值,否则返回t
orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值
map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()
flatMap(Function mapper):与 map 类似,要求返回值必须是Optional
@Test public void test4(){ Optional<Employee> op = Optional.of(new Employee(101, "张三", 18, 9999.99)); Optional<String> op2 = op.map(Employee::getName); System.out.println(op2.get()); Optional<String> op3 = op.flatMap((e) -> Optional.of(e.getName())); System.out.println(op3.get()); } @Test public void test3(){ Optional<Employee> op = Optional.ofNullable(new Employee()); if(op.isPresent()){ System.out.println(op.get()); } Employee emp = op.orElse(new Employee("张三")); System.out.println(emp); Employee emp2 = op.orElseGet(() -> new Employee()); System.out.println(emp2); }
//运用 Optional 的实体类 @Test public void test6(){ Optional<Godness> godness = Optional.ofNullable(new Godness("aaa")); Optional<NewMan> op = Optional.ofNullable(new NewMan(godness)); String name = getGodnessName2(op); System.out.println(name); } public String getGodnessName2(Optional<NewMan> man){ return man.orElse(new NewMan()) .getGodness() .orElse(new Godness("bbb")) .getName(); }
接口中的默认方法:
//传统的日期处理 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); Callable<Date> task = new Callable<Date>() { @Override public Date call() throws Exception { return sdf.parse("20161121"); } }; ExecutorService pool = Executors.newFixedThreadPool(10); List<Future<Date>> results = new ArrayList<>(); for (int i = 0; i < 10; i++) { results.add(pool.submit(task)); } for (Future<Date> future : results) { System.out.println(future.get()); } pool.shutdown();
public class DateFormatThreadLocal { private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>(){ protected DateFormat initialValue(){ return new SimpleDateFormat("yyyyMMdd"); } }; public static final Date convert(String source) throws ParseException{ return df.get().parse(source); } }
//解决多线程安全问题 Callable<Date> task = new Callable<Date>() { @Override public Date call() throws Exception { return DateFormatThreadLocal.convert("20161121"); } }; ExecutorService pool = Executors.newFixedThreadPool(10); List<Future<Date>> results = new ArrayList<>(); for (int i = 0; i < 10; i++) { results.add(pool.submit(task)); } for (Future<Date> future : results) { System.out.println(future.get()); } pool.shutdown();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd"); Callable<LocalDate> task = new Callable<LocalDate>() { @Override public LocalDate call() throws Exception { LocalDate ld = LocalDate.parse("20161121", dtf); return ld; } }; ExecutorService pool = Executors.newFixedThreadPool(10); List<Future<LocalDate>> results = new ArrayList<>(); for (int i = 0; i < 10; i++) { results.add(pool.submit(task)); } for (Future<LocalDate> future : results) { System.out.println(future.get()); } pool.shutdown(); }
//1. LocalDate、LocalTime、LocalDateTime @Test public void test1(){ LocalDateTime ldt = LocalDateTime.now(); System.out.println(ldt); LocalDateTime ld2 = LocalDateTime.of(2016, 11, 21, 10, 10, 10); System.out.println(ld2); LocalDateTime ldt3 = ld2.plusYears(20); System.out.println(ldt3); LocalDateTime ldt4 = ld2.minusMonths(2); System.out.println(ldt4); System.out.println(ldt.getYear()); System.out.println(ldt.getMonthValue()); System.out.println(ldt.getDayOfMonth()); System.out.println(ldt.getHour()); System.out.println(ldt.getMinute()); System.out.println(ldt.getSecond()); }
//2. Instant : 时间戳。 (使用 Unix 元年 1970年1月1日 00:00:00 所经历的毫秒值) @Test public void test2(){ Instant ins = Instant.now(); //默认使用 UTC 时区 System.out.println(ins); OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8)); System.out.println(odt); System.out.println(ins.getNano()); Instant ins2 = Instant.ofEpochSecond(5); System.out.println(ins2); }
//3. //Duration : 用于计算两个“时间”间隔 //Period : 用于计算两个“日期”间隔 @Test public void test3(){ Instant ins1 = Instant.now(); System.out.println("--------------------"); try { Thread.sleep(1000); } catch (InterruptedException e) { } Instant ins2 = Instant.now(); System.out.println("所耗费时间为:" + Duration.between(ins1, ins2)); System.out.println("----------------------------------"); LocalDate ld1 = LocalDate.now(); LocalDate ld2 = LocalDate.of(2011, 1, 1); Period pe = Period.between(ld2, ld1); System.out.println(pe.getYears()); System.out.println(pe.getMonths()); System.out.println(pe.getDays()); }
//4. TemporalAdjuster : 时间校正器 @Test public void test4(){ LocalDateTime ldt = LocalDateTime.now(); System.out.println(ldt); LocalDateTime ldt2 = ldt.withDayOfMonth(10); System.out.println(ldt2); LocalDateTime ldt3 = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)); System.out.println(ldt3); //自定义:下一个工作日 LocalDateTime ldt5 = ldt.with((l) -> { LocalDateTime ldt4 = (LocalDateTime) l; DayOfWeek dow = ldt4.getDayOfWeek(); if(dow.equals(DayOfWeek.FRIDAY)){ return ldt4.plusDays(3); }else if(dow.equals(DayOfWeek.SATURDAY)){ return ldt4.plusDays(2); }else{ return ldt4.plusDays(1); } }); System.out.println(ldt5); }
//5. DateTimeFormatter : 解析和格式化日期或时间 @Test public void test5(){ // DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE; DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"); LocalDateTime ldt = LocalDateTime.now(); String strDate = ldt.format(dtf); System.out.println(strDate); LocalDateTime newLdt = ldt.parse(strDate, dtf); System.out.println(newLdt); }
//6.ZonedDate、ZonedTime、ZonedDateTime : 带时区的时间或日期 @Test public void test7(){ LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Asia/Shanghai")); System.out.println(ldt); ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("US/Pacific")); System.out.println(zdt); } @Test public void test6(){ Set<String> set = ZoneId.getAvailableZoneIds(); set.forEach(System.out::println); }
重复注解