异步API
以前我们用 Thread 或者 Runnable 来实现异步,这是Oracle官方做法,不过缺点很明显:对于复杂业务场景需要配置线程池,代码繁杂;对于新手容易造成不必要的Bug;如果涉及到线程锁或线程通讯就棘手了。
现在,Java 8 为我们提供了 CompletableFuture 类,可以完全解决以上问题。
runAsync() 异步无参返回
@Test
public void asyncThread() throws Exception {
CompletableFuture async1 = CompletableFuture.runAsync(() -> {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
System.out.println("none return Async");
} catch (Exception e) {
e.printStackTrace();
}
});
// 调用get()将等待异步逻辑处理完成
async1.get();
}
supplyAsync() 异步有参返回
@Test
public void asyncThread2() throws Exception {
CompletableFuture<String> async2 = CompletableFuture.supplyAsync(() -> {
return "hello";
});
String result = async2.get();
// String result2 = async2.get(5L, TimeUnit.SECONDS);
System.out.println(result);
}
allOf() 多个异步处理(针对有参返回)
@Test
public void asyncThread3() throws Exception {
CompletableFuture<String> a = CompletableFuture.supplyAsync(() -> "hello");
CompletableFuture<String> b = CompletableFuture.supplyAsync(() -> "youth");
CompletableFuture<String> c = CompletableFuture.supplyAsync(() -> "!");
CompletableFuture all = CompletableFuture.allOf(a, b, c);
all.get();
String result = Stream.of(a, b, c)
.map(CompletableFuture::join)
.collect(Collectors.joining(" "));
System.out.println(result);
}
anyOf() 多个异步随机处理(针对有参返回)
@Test
public void asyncThread4() throws Exception {
CompletableFuture<String> a = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(20);
return "hello";
} catch (Exception e) {
e.printStackTrace();
return "none~";
}
});
CompletableFuture<String> b = CompletableFuture.supplyAsync(() -> "youth");
CompletableFuture<String> c = CompletableFuture.supplyAsync(() -> "!");
CompletableFuture<Object> any = CompletableFuture.anyOf(a, b, c);
String result = (String) any.get();
System.out.println(result);
}
循环ForEach
和 for 循环不同的是,forEach 循环是建立在 Stream 之上的。而且比 for 或 iterator 方便的是,它可以循环 Map 对象,如果您尝试配合 filter 处理就更赞了~
forEach对List的循环
@Test
public void listForeach() {
List<String> lst = new ArrayList<String>(5) {{
add("A");
add("B");
add("H");
add("O");
add("M");
}};
lst.forEach(System.out::println);
lst.forEach((item) -> System.out.println(item.concat("_")));
}
forEach对数组的循环
@Test
public void arrForeach() {
String[] strArr = new String[]{"A", "B", "C", "D"};
Arrays.stream(strArr).forEach(System.out::println);
}
forEach对int范围的循环
@Test
public void numericForeach() {
IntStream.range(0, 10).forEach(System.out::println);
}
forEach对Map的循环
@Test
public void mapForeach() {
Map<String, Object> mps = new HashMap<String, Object>(5) {{
put("a", 1);
put("b", true);
put("c", 23.44F);
put("d", "hello");
put("e", 11L);
}};
mps.forEach((k, v) -> System.out.println(k.concat(":").concat(String.valueOf(v))));
String str = "hello";
}
时间类
Java 8 之前我们处理时间大多会涉及到这几个类:Date、SimpleDateFormat、Calendar。这种处理方式复杂、存在线程隐患、国际化困难、日期加减等处理麻烦等等。
现在有了 LocalDate、LocalDateTime、DateTimeFormatter,生活就变得简单了。
常量定义
/**设置格式化模板**/
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSS");
/**设置日期时区常量**/
public static final ZoneId CHINA_ZONE_ID = ZoneId.systemDefault();
Date转DateTime
/**Date格式化为DateTime**/
@Test
public void dateToDateTime() {
Date date = new Date();
LocalDateTime dateTime = date.toInstant().atZone(CHINA_ZONE_ID).toLocalDateTime();
System.out.println(dateTime);
}
LocalDate/LocalDateTime转Date
/**LocalDate/LocalDateTime转Date**/
@Test
public void toDate() {
// LocalDate
LocalDate localDate = LocalDate.now();
Date d1 = Date.from(localDate.atStartOfDay(CHINA_ZONE_ID).toInstant());
System.out.println(d1);
// LocalDateTime
LocalDateTime localDateTime = LocalDateTime.now();
Date d2 = Date.from(localDateTime.atZone(CHINA_ZONE_ID).toInstant());
System.out.println(d2);
}
日期格式化
/**日期格式化**/
@Test
public void formatDate() {
System.out.println(LocalDateTime.now().format(DATE_TIME_FORMATTER));
}
日期加减
/**日期加减**/
@Test
public void plusDay() {
LocalDateTime dateTime = LocalDateTime.now(CHINA_ZONE_ID);
//天
dateTime = dateTime.plusDays(1);
//时
dateTime = dateTime.plusHours(-1);
//分钟
dateTime = dateTime.plusMinutes(30);
System.out.println(dateTime.format(DATE_TIME_FORMATTER));
}
日期时间间隔
/**日期时间间隔**/
@Test
public void betweenDay() {
// LocalDateTime
LocalDateTime startDate = LocalDateTime.of(2019, 07, 01, 12, 12, 22);
LocalDateTime endDate = LocalDateTime.of(2019, 07, 03, 12, 12, 22);
Long withSecond = endDate.atZone(CHINA_ZONE_ID).toEpochSecond() - startDate.atZone(CHINA_ZONE_ID).toEpochSecond();
System.out.println(withSecond / 60 / 60 / 24);
// LocalDate
LocalDate startDate2 = LocalDate.of(2019, 07, 01);
LocalDate endDate2 = LocalDate.of(2019, 07, 03);
Long withSecond2 = endDate2.toEpochDay() - startDate2.toEpochDay();
System.out.println(withSecond2);
}
第一天和最后一天
/**第一天and最后一天**/
@Test
public void theLastDay() {
// 当月第一天
LocalDateTime dateTime = LocalDateTime.of(2019, 07, 03, 12, 12, 22);
dateTime = dateTime.with(TemporalAdjusters.firstDayOfMonth());
System.out.println(dateTime);
// 当月最后一天
dateTime = dateTime.with(TemporalAdjusters.lastDayOfMonth());
System.out.println(dateTime);
//当月的第几天
dateTime = LocalDateTime.now();
int dayOfMonth = dateTime.getDayOfMonth();
System.out.println(dayOfMonth);
// 当前周的第几天
int dayOfWeek = dateTime.getDayOfWeek().getValue();
System.out.println(dayOfWeek);
}