java8 異步api、循環、日期
轉載請注明出處:https://www.cnblogs.com/funnyzpc/p/10801470.html
異步api
對於多任務耗時的業務場景,一般我們會用到線程異步處理,在以前我們用 Thread 或者 Runnable 來實現異步,這是oracle官方做法,不過缺點很明顯
- 對於復雜業務場景需要配置線程池
- 代碼繁雜,對於新手容易造成不必要的bug
- 如果涉及到線程鎖或線程通訊就棘手了
現在,java8為我們提供了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
java8 在原有for
或iterator
循環下又提供了 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";
}
新的時間類(LocalDate、LocalDateTime
)
java8 之前我們處理時間 大多會涉及到這幾個類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最后一天
/**第一天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);
}
OK,本次分享就到這里,如有謬誤懇請指正~