1、初始化一個對象的簡便方式
Student stu = new Student(){{
setName("張三");
}};
2、重新組合後去重
List<String> names = list.stream().map(Student::getName).distinct().collect(Collectors.toList());
3、根據某一屬性對集合去重
list = list.stream()
.collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
new TreeSet<>(Comparator.comparing(e -> e.getName()))), ArrayList::new));
4、集合排序
// 正序
list = list.stream().sorted((a, b) -> a.getName().compareTo(b.getName())).collect(Collectors.toList());
list = list.stream().sorted(Comparator.comparing(Student::getName)).collect(Collectors.toList());
// 倒序
list = list.stream().sorted((a, b) -> -(a.getName().compareTo(b.getName()))).collect(Collectors.toList());
list = list.stream().sorted(Comparator.comparing(Student::getName).reversed()).collect(Collectors.toList());
5、獲取Sum
BigDecimal sum1 = list.stream().map(Student::getScore).reduce((a,b) -> a.add(b)).orElse(BigDecimal.ZERO);
BigDecimal sum2 = list.stream().map(Student::getScore).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
6、過濾
boolean exists = list.stream().anyMatch(e -> e.getAmount() == null || e.getAmount().compareTo(BigDecimal.ZERO) <= 0);
7、集合轉換爲數組
Long[] ids = list.toArray(new Long[]{});
Long[] ocrFileIds = rows.stream().toArray(Long[] :: new);
8、使用CountDownLatch同時跑多個任務,一起返回
List<File> countFileList = new ArrayList<>();
if (CollectionUtils.isEmpty(countFileList)) {
return;
}
// 定義線程安全的結果集
List<File> files = Collections.synchronizedList(new ArrayList<>());
// 定義CountDownLatch線程數,有多少個請求,我們就定義多少個
CountDownLatch runningThreadNum = new CountDownLatch(countFileList.size());
for (File file : countFileList) {
countDownLatchTaskService.getFileBytes(runningThreadNum, file, files);
}
try {
// 調用CountDownLatch的await方法則當前主線程會等待,直到CountDownLatch類型的runningThreadNum清0
// 每個任務處理完成會對runningThreadNum減1
// 如果等待?分鐘後當前主線程都等不到runningThreadNum清0,則認爲超時,直接中斷,拋出中斷異常InterruptedException
runningThreadNum.await(wait, timeUnit);
} catch (InterruptedException e) {
// 非正常中斷應該拋出異常或返回錯誤結果
logger.error("CountDownLatch識別線程超時", e);
throw new ApplicationException(ResponseCode.OVERTIME_FILE_ERROR);
}
// CountDownLatchTaskService.java 核心代碼
/**
* 獲取文件數據
* @param runningThreadNum 正在運行的線程
* @param file 識別文件
* @param resultList 識別結果列表
*/
@Async("fileBytesExecutor")
public void getFileBytes(CountDownLatch runningThreadNum, File file, List<File> resultList) {
try{
// 如果Bytes爲空,就自己去取
CommonService.getFileBytes(file);
if (file.getSize() <= 0 || ArrayUtils.isEmpty(file.getBytes()) || StringUtils.isEmpty(file.getUrl())) {
logger.info("文件不存在或文件大小爲空或文件Url爲空, fileId:::{}, url:::{}, fileSize:::{}", file.getId(), file.getUrl(), file.getSize());
return;
}
resultList.add(file);
} catch(Exception e) {
logger.error("獲取文件數據出錯", e);
} finally {
// 當前線程處理完成,runningThreadNum線程數減1,此操作必須在finally中完成,避免處理異常後造成runningThreadNum線程數無法清0
runningThreadNum.countDown();
}
}
9、異步任務等待當前事務提交後再執行
// 等待當前事務提交後再處理異步業務,防止數據還未提交導致數據有誤
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
// 異步任務執行
doAsyncWork();
}
});