目录
List常用方法
List<Map<String, String>> 根据某个key排序
List<BusinessProjectVO> records = Optional.ofNullable(businessProjectPage).orElse(new Page<>()).getRecords().stream().peek(e -> {
R<Long> totalData = remoteSynchronizorService.getTotalData(e.getAppId());
e.setTotalDate(totalData.getData());
}).collect(Collectors.toList());
//根据totalDate字段排倒序
records = records.stream().sorted(Comparator.comparing(BusinessProjectVO::getTotalDate).reversed()).collect(Collectors.toList());
List过滤
List<Map<String, Object>> collectDataList = dataList.stream()
.filter(dataRow -> ("1".equals(String.valueOf(dataRow.get("group_bit")))))
.collect(Collectors.toList());
stream方法
//List<Object> 转为 Map<String,Integer>
Map<String,Integer> allBoardNameMap = allDataBoards.stream().collect(Collectors.toMap(dataBoard->dataBoard.getBoardName(), dataBoard -> 1, (existingValue, newValue) -> newValue));
//List<Object> 转为 List<Long>
List<Long> reportIds = boardReportRelations.stream().map(boardReportRelation -> boardReportRelation.getReportId()).collect(Collectors.toList());
List<String> sqlQueryChartIds = boardReports.stream().filter(boardReport -> StringUtils.isNotBlank(boardReport.getChartId())).map(boardReport -> boardReport.getChartId()).collect(Collectors.toList());
判断List集合中是否存在相同元素
//校验是否存在相同资产
List<String> assetNoList = Lists.newArrayList();
beforeMergeAssetList.forEach( asset->{
String assetNo = asset.getAssetInfo().getAssetNo();
if (StringUtils.isBlank(assetNo)){throw new JeecgBootException("合并前资产编号不能为空");}
assetNoList.add(assetNo);
});
Set assetNoSet=new HashSet<>(assetNoList);
if (assetNoList.size() != assetNoSet.size()) {throw new JeecgBootException("请选择不同的资产");}
判空
1 对象
if (Objects.isNull(assetMergeDTO)){ throw new JeecgBootException("请选择资产"); }
2 集合
CollectionUtils.isNotEmpty(records)
3 字符串
StringUtils.isBlank(assetMergeNo)
集合流方法使用
@AutoLog(value = "资产组合-组合日志查询")
@ApiOperation(value = "资产组合-组合日志查询", notes = "资产组合-组合日志查询")
@GetMapping("/getMergeLog")
public Result<?> getMergeLog(@RequestParam(name = "assetNo", required = true) String assetNo) {
List<AssetMerge> assetMergeList = iAssetMergeService.selectByAssetNo(assetNo);
Map<String, List<AssetMerge>> listMap = assetMergeList.stream().collect(Collectors.groupingBy(AssetMerge::getAssetMergeNo));
Set<Map.Entry<String, List<AssetMerge>>> entries = listMap.entrySet();
JSONArray JSONArray = new JSONArray();
for (Map.Entry<String, List<AssetMerge>> entry : entries) {
JSONObject jsonObject = new JSONObject();
String key = entry.getKey();
List<AssetMerge> value = entry.getValue();
List<JSONObject> list = value.stream()
.sorted((o1, o2) -> (int) (o1.getId() - o2.getId()))
.map(assetSplit -> {
JSONObject temp = new JSONObject();
temp.put("assetNo", assetSplit.getBeforeMergeAssetNo());
temp.put("assetName", assetSplit.getBeforeMergeAssetName());
return temp;
}).collect(Collectors.toList());
AssetMerge assetMerge = value.get(0);
String assetMergeNo = assetMerge.getAssetMergeNo();
String afterMergeAssetNo = assetMerge.getAfterMergeAssetNo();
String afterMergeAssetName = assetMerge.getAfterMergeAssetName();
jsonObject.put("assetMergeNo", assetMergeNo);
jsonObject.put("afterMergeAssetNo", afterMergeAssetNo);
jsonObject.put("afterMergeAssetName", afterMergeAssetName);
jsonObject.put("beforeMergeAssetList", list);
jsonObject.put("mergeTime", assetMerge.getCreateTime());
JSONArray.add(jsonObject);
}
return Result.ok(JSONArray);
}
TryCatch基本使用
//参数校验
try {
if (Objects.isNull(assetMergeDTO)){ throw new JeecgBootException("请选择资产"); }
List<AssetInfoDTO> beforeMergeAssetList = assetMergeDTO.getBeforeMergeAssetList();
if (Objects.isNull(beforeMergeAssetList) || beforeMergeAssetList.size() < 2){throw new JeecgBootException("请选择2个及2个以上资产");}
AssetInfoDTO afterMergeAsset = assetMergeDTO.getAfterMergeAsset();
if (Objects.isNull(afterMergeAsset)){throw new JeecgBootException("请输入合并后资产信息");}
} catch (JeecgBootException e) {
e.printStackTrace();
return Result.error(e.getMessage());
}
导入导出Excel
方法1
@Override
@Transactional(rollbackFor = Exception.class)
public Result<?> importBatchMaintainAssetExcel(HttpServletRequest request) throws IOException {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
if(loginUser==null){throw new JeecgBootException("登录失效,请重新登录");}
String username = loginUser.getUsername();
Date date = new Date();
// 错误信息
List<String> errorMessage = new ArrayList<>();
int successLines = 0, errorLines = 0;
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();// 获取上传文件对象
ImportParams params = new ImportParams();
params.setHeadRows(1);
params.setTitleRows(2);
params.setNeedSave(true);
try {
List<AssetMaintainExcelImportDTO> importAssetScraps = ExcelImportUtil.importExcel(file.getInputStream(), AssetMaintainExcelImportDTO.class, params);
List<AssetMaintainDTO> list = new ArrayList<>();
int i=2;
//先校验参数
if(CollectionUtils.isEmpty(importAssetScraps)){throw new JeecgBootException("维修信息为空");}
for (AssetMaintainExcelImportDTO importAssetScrap : importAssetScraps) {
try {
i = i + 1;
String assetNo = importAssetScrap.getAssetNo();
String remark = importAssetScrap.getRemark();
if(StringUtils.isBlank(assetNo)){throw new JeecgBootException("第"+i+"行 资产编号为空");}
AssetInfo assetInfo = iAssetInfoService.getByAssetNo(assetNo);
if(assetInfo==null){throw new JeecgBootException("第"+i+"行 资产编号错误【"+assetNo+"】");}
if(!AssetStatusEnum.INSTORE.getValue().equals(assetInfo.getAssetStatus())){throw new JeecgBootException("第"+i+"行 资产【"+assetNo+"】不是库存状态");}
assetInfo.setAssetStatus(AssetStatusEnum.MAINTENANCE.getValue());
AssetInfoDTO assetInfoDTO = new AssetInfoDTO();
assetInfoDTO.setAssetInfo(assetInfo);
iAssetInfoService.assetInfoCheck(assetInfoDTO);
AssetMaintainDTO assetScrapDTO = new AssetMaintainDTO();
assetScrapDTO.setAssetInfoDTO(assetInfoDTO);
assetScrapDTO.setCreateTime(date);
assetScrapDTO.setRemark(remark);
assetScrapDTO.setCreateBy(username);
list.add(assetScrapDTO);
}catch (JeecgBootException je){
throw new JeecgBootException("第"+i+"行数据错误,"+je.getMessage());
}
}
//没有任何问题,再开始保存
for (AssetMaintainDTO assetScrapDTO : list) {
try {
this.saveMaintainAssetInfo(assetScrapDTO);
} catch (JeecgBootException je) {
errorLines += 1;
errorMessage.add(je.getMessage());
}catch (Exception e) {
errorLines += 1;
errorMessage.add(e.getMessage());
}
}
successLines+=(importAssetScraps.size()-errorLines);
}catch (JeecgBootException je){
return Result.error("文件导入失败:" + je.getMessage());
} catch (Exception e) {
log.error(e.getMessage(), e);
return Result.error("文件导入失败:" + e.getMessage());
} finally {
try {
file.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return ImportExcelUtil.imporReturnRes(errorLines,successLines,errorMessage);
}
@AutoLog(value = "资产合并-导出")
@ApiOperation(value = "资产合并-导出", notes = "资产合并-导出")
@RequestMapping(value = "/exportAssetMergeXls")
public ModelAndView exportAssetMergeXls(AssetMergeReq req, HttpServletRequest request) {
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
List<AssetMergeVO> assetMergeVOList = iAssetMergeService.getAssetMergeList(req);
//导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME, "资产合并列表");
mv.addObject(NormalExcelConstants.CLASS, AssetMergeVO.class);
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("资产合并列表", "导出人:" + user.getRealname(), "导出信息"));
mv.addObject(NormalExcelConstants.DATA_LIST, assetMergeVOList);
return mv;
}
方法2
依赖
<!-- 阿里开源EXCEL -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.5</version>
</dependency>
代码实现
@PostMapping("/dailyData/export")
public void exportDailyData(@Valid @RequestBody CustomBoardDailyDataReq req, HttpServletResponse response) {
try {
checkDailyDataParams(req);
List<CustomBoardDailyDataVO> resultList = customBoardDailyDataService.dailyDataExport(req);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("日报-"+ DateUtils.getCurrentTimeNoUnderline(), "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".csv");
response.setHeader("file-name", fileName);
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
// WriteSheet writeSheet0 = EasyExcel.writerSheet(0, "日报").head(CustomBoardDailyDataVO.class).build();
//动态隐藏表头
List<String> columnsList = Lists.newArrayList();
String columns = req.getColumns();
if (StringUtils.isNotBlank(columns)){
columnsList = Arrays.asList(columns.split(","));
}
WriteSheet writeSheet0 = EasyExcel.writerSheet(0, "日报")
.excludeColumnFiledNames(columnsList).head(CustomBoardDailyDataVO.class).build();
excelWriter.write(resultList, writeSheet0);
excelWriter.finish();
}catch (CheckedException ce){
log.error("error-日报-导出接口:{}", ce);
} catch (Exception e) {
log.error("error-日报-导出接口:{}", e);
}
}
Json字符串转换为对应类型
//Map、List<String>等等:
//数组String转成List<String>
String s = ["SITE_SET_KANDIAN","SITE_SET_QQ_MUSIC_GAME"]
List<String> parse = (List<String>)JSONArray.parse(siteSet);
//Map的String转换为Map
String s = {"image":"66159322","description":"殿堂级卡牌震撼公测,安卓抢先","video":"157776020","label":[{"type":1,"content":"挂机"},{"type":1,"content":"Q萌卡通"},{"type":1,"content":"二次元"}],"title":"告别假放置!下载领取超多福利","brand":{"brand_name":"冒险世界","brand_img":"66160154"}}
Map map = JSONObject.parseObject(adcreativeElements,Map.class);
后台post请求接口
/**
* post请求
*
* @param url
* @param jsonObject object
* @return json object
*/
public static String doPost(String url, JSONObject jsonObject) throws IOException {
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
String result = null;
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(10000)
.setConnectionRequestTimeout(10000)
.setSocketTimeout(60000)
.build();
post.setConfig(requestConfig);
post.addHeader("Content-type","application/json; charset=utf-8");
post.setHeader("Accept", "application/json");
StringEntity s = new StringEntity(jsonObject.toString(),"UTF-8");
post.setEntity(s);
HttpResponse res = client.execute(post);
if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = res.getEntity();
result = EntityUtils.toString(entity);
}
return result;
}
/*
* 测试 用户标签创建方式为 首末次特征
* */
public static void main(String[] args) throws Exception{
String url = "http://localhost:9201/useranalysis/saveUserLabelMeta";
JSONObject json = new JSONObject();
json.put("appId",1386652408108683264L);
json.put("createMode",3);//首末次特征
json.put("dataUpdate",1);
json.put("conditionJson","{\"columnName\":\"#screen_width\",\"columnType\":\"DOUBLE\",\"eventName\":\"login\",\"filts\":[{\"columnName\":\"#account_id\",\"comparator\":\"notEqual\",\"ftv\":[\"444444\"],\"selectType\":\"STRING\",\"tableType\":\"user\"}],\"isFirstEvent\":true,\"isUserFilter\":true,\"recentDay\":\"0-7\",\"relation\":\"or\"}");
json.put("labelName","标签_20210429_1002");
json.put("labelNo","tag_20210429_2");
json.put("userId",101);
System.out.println(json.toString());
String s = HttpUtil.doPost(url, json);
System.out.println(s);
}
@Value注解读取配置属性值
assetInfo:
deviceTypeID: "1402108939024203778"
@Value("${assetInfo.deviceTypeID}")
private String DEVICE_TYPE_ID;
正则匹配
package org.jeecg.modules.base.util;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @description: 正则表达式工具类
* @author: nml
* @time: 2020/12/23 11:56
**/
public final class RegexUtils {
/**
* 获得匹配正则表达式的内容
* @param str 字符串
* @param reg 正则表达式
* @param isCaseInsensitive 是否忽略大小写,true忽略大小写,false大小写敏感
* @return 匹配正则表达式的字符串,组成的List
*/
public static List<String> getMatchList(final String str, final String reg, final boolean isCaseInsensitive) {
ArrayList<String> result = new ArrayList<String>();
Pattern pattern = null;
if (isCaseInsensitive) {
//编译正则表达式,忽略大小写
pattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);
} else {
//编译正则表达式,大小写敏感
pattern = Pattern.compile(reg);
}
Matcher matcher = pattern.matcher(str);// 指定要匹配的字符串
while (matcher.find()) { //此处find()每次被调用后,会偏移到下一个匹配
result.add(matcher.group());//获取当前匹配的值
}
result.trimToSize();
return result;
}
/**
* 获取第一个匹配正则表达式的子串
* @param str 完整字符串
* @param reg 正则表达式
* @param isCaseInsensitive 是否忽略大小写,true表示忽略,false表示大小写敏感。
* @return 第一个匹配正则表达式的子串。
*/
public static String getFirstMatch(final String str, final String reg, final boolean isCaseInsensitive) {
Pattern pattern = null;
if (isCaseInsensitive) {
//编译正则表达式,忽略大小写
pattern = Pattern.compile(reg, Pattern.CASE_INSENSITIVE);
} else {
//编译正则表达式,大小写敏感
pattern = Pattern.compile(reg);
}
Matcher matcher = pattern.matcher(str);// 指定要匹配的字符串
if (matcher.find()) {
return matcher.group();
}
return null;
}
//匹配:张三[101]。其中汉字2-4个,数字3-10个。
public static boolean checkNameAndWorkNo(String dataStr) {
String regFormat = "^[\\u4E00-\\u9FA5]{2,4}\\[\\d{3,10}\\]$";
boolean isMatch = Pattern.matches(regFormat , dataStr);
return isMatch;
}
}
反射机制
Java反射机制是Java语言的一个特性,它可以在运行时获取类的结构信息,如类名、方法名、属性名等,并且可以动态地创建对象、调用方法、访问属性等。Java反射机制为程序员提供了更大的灵活性和编程能力,通常用于以下几个方面:
- 动态加载类:Java反射机制可以在程序运行时根据类名称加载相应的类,实现类的动态加载。
- 动态创建对象:Java反射机制可以通过调用Class对象的newInstance()方法动态地创建对象,有利于代码的扩展性和复用性。
- 动态调用方法:Java反射机制可以在运行时动态调用方法,不需要事先知道方法名,极大地拓展了程序的功能性。
- 访问私有属性和方法:Java反射机制可以通过设置setAccessible()方法来访问类的私有属性和方法,而不受访问修饰符的限制。
- 实现泛型数组:Java反射机制可以实现泛型数组的创建和访问,提高了程序的可读性和可维护性。
总之,Java反射机制是Java语言中的一个重要机制,通过反射技术,程序员可以在运行时获取并操作类的结构信息,提高程序的灵活性和可扩展性。
1 获得Class:主要有三种方法:
- Object–>getClass
- 任何数据类型(包括基本的数据类型)都有一个“静态”的class属性
- 通过class类的静态方法:forName(String className)(最常用)
package fanshe;
public class Fanshe {
public static void main(String[] args) {
//第一种方式获取Class对象
Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
Class stuClass = stu1.getClass();//获取Class对象
System.out.println(stuClass.getName());
//第二种方式获取Class对象
Class stuClass2 = Student.class;
System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
//第三种方式获取Class对象
try {
Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
注意,在运行期间,一个类,只有一个Class对象产生,所以打印结果都是true;
三种方式中,常用第三种,第一种对象都有了还要反射干什么,第二种需要导入类包,依赖太强,不导包就抛编译错误。一般都使用第三种,一个字符串可以传入也可以写在配置文件中等多种方法。
测试类
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
package com.idongyou.dongxin.thirdparty;
import com.alibaba.fastjson.JSON;
import com.idongyou.dongxin.thirdparty.dao.doris.CustomerAccountRoleInfoDao;
import com.idongyou.dongxin.thirdparty.model.CustomerAccountRoleInfo;
import com.idongyou.dongxin.thirdparty.model.dto.CustomerAccountRoleInfoDTO;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
@SpringBootTest
public class CustomerTest {
@Autowired
private CustomerAccountRoleInfoDao customerAccountRoleInfoDao;
@Test
public void testQueryOneByRole(){
CustomerAccountRoleInfoDTO req = new CustomerAccountRoleInfoDTO();
req.setAppMain(16);
CustomerAccountRoleInfo customerAccountRoleInfo = customerAccountRoleInfoDao.queryOneByRole(req);
log.info(JSON.toJSONString(customerAccountRoleInfo));
}
}
多线程ThreadPoolExecutor
//初始化一个线程池
protected final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
Runtime.getRuntime().availableProcessors(),
0L,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(1024)
);
//查询时,多线程查询
public ListResult<GameRolePayDTO> gameRolePayResult(RealTimeReq req) {
//
ListResult<GameRolePayDTO> result = new ListResult<>();
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
// 列表
result.setList(gameRolePayList(req));
}, threadPoolExecutor).thenRunAsync(() -> {
// 汇总
result.setSummary(gameRolePaySummary(req));
}, threadPoolExecutor);
try {
future.get(30,TimeUnit.SECONDS);
} catch (Exception e) {
log.error("查询游戏角色付费失败..., {}",e);
}
return result;
}
设计模式之单例模式
Java中的单例模式是一种常用的设计模式,它保证一个类在整个应用程序中只有一个实例,并提供一个全局访问点。
Java实现单例模式的方式有多种,其中比较常用的方法如下:
1.懒汉式:在首次使用时创建实例。代码如下:
Copy Codepublic class Singleton {
private static Singleton instance = null;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2.饿汉式:在类加载时创建实例。代码如下:
Copy Codepublic class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
3.双重校验锁:在多线程环境中保证单例实例的线程安全创建。代码如下:
Copy Codepublic class Singleton {
private static volatile Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
4.静态内部类:利用类加载器机制实现线程安全的延迟初始化。代码如下:
Copy Codepublic class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
以上是常用的几种单例模式实现方式,开发人员可以根据具体场景选择适合自己的方式来实现单例模式,以保证系统的性能和安全性。
不可变map
Java中可以通过使Map的键和值都是不可变类型来实现不变Map。其中,可以使用Collections.unmodifiableMap()方法创建一个只读的Map视图,或者使用Guava中的ImmutableMap来创建一个完全不可变的Map。
以下是两种实现方式的示例代码:
1.使用Collections.unmodifiableMap()方法创建只读的Map视图
Copy CodeMap<String, String> originalMap = new HashMap<>();
// 添加元素到原始Map
originalMap.put("key1", "value1");
originalMap.put("key2", "value2");
// 创建只读Map视图
Map<String, String> immutableMap = Collections.unmodifiableMap(originalMap);
// 试图修改只读Map视图的内容会抛出UnsupportedOperationException异常
immutableMap.put("key3", "value3"); // UnsupportedOperationException
2.用Guava中的ImmutableMap创建完全不可变的Map
Copy Code// 创建一个不可变Map
Map<String, String> immutableMap = ImmutableMap.of(
"key1", "value1",
"key2", "value2"
);
// 试图修改不可变Map的内容会抛出UnsupportedOperationException异常
immutableMap.put("key3", "value3"); // UnsupportedOperationException
以上两种方式都可以用来创建不变Map,但它们有一些差异。使用Collections.unmodifiableMap()方法创建的只读Map仍然可以通过原始Map来修改,而使用Guava中的ImmutableMap创建的完全不可变Map则没有这个问题。
ObjectMapper
ObjectMapper 类提供了一系列方法用于实现 Java 对象与 JSON 数据之间的转换。以下是一些常用的 ObjectMapper 方法:
1.writeValueAsString(Object value):将指定的 Java 对象转换为 JSON 字符串。
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = objectMapper.writeValueAsString(myObject);
2.writeValue(File file, Object value):将指定的 Java 对象转换为 JSON,并写入到文件中。
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValue(new File("data.json"), myObject);
3.readValue(String content, Class<T> valueType):将 JSON 字符串转换为指定类型的 Java 对象。
ObjectMapper objectMapper = new ObjectMapper();
MyObject myObject = objectMapper.readValue(jsonString, MyObject.class);
4.readValue(File file, Class<T> valueType) :从文件中读取 JSON 数据,并将其转换为指定类型的 Java 对象。
ObjectMapper objectMapper = new ObjectMapper();
MyObject myObject = objectMapper.readValue(new File("data.json"), MyObject.class);
4.convertValue(Object fromValue, Class<T> toValueType):将一个对象转换为指定类型的对象。
ObjectMapper objectMapper = new ObjectMapper();
MyObject myObject = objectMapper.convertValue(map, MyObject.class);
5.setPropertyNamingStrategy(PropertyNamingStrategy naming):设置命名策略,用于在序列化和反序列化过程中控制属性命名的转换方式。
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
6.setSerializationInclusion(JsonInclude.Include include):设置对象属性的序列化包含规则,用于控制哪些属性会被包含在生成的 JSON 中。
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
这只是一小部分 ObjectMapper
提供的方法示例。ObjectMapper
还提供了许多其他方法,用于更高级的定制和操作。你可以根据具体需求查阅 ObjectMapper
类的官方文档以获取更详细的信息。
应用实例:
// 保存数据JSON文件到指定目录
public static void saveDataToFile(Object data,String fileStoragePath) throws Exception{
ObjectMapper objectMapper = new ObjectMapper();
// String dataJson = objectMapper.writeValueAsString(data);
File file = new File(fileStoragePath);
if (file.exists() && file.isFile()) {
// 文件存在
log.info("saveDataToFile:{}","文件存在,覆盖保存");
objectMapper.writeValue(file,data);
} else {
// 文件不存在
//直接保存
objectMapper.writeValue(file,data);
}
}
Java生成唯一id
在 Java 中,可以使用以下几种方式生成唯一ID:
1. UUID(Universally Unique Identifier):UUID 是一种由标准化的 128 位数字(32 个十六进制数)组成的唯一标识符。Java 提供了 java.util.UUID
类来生成 UUID。
import java.util.UUID;
// 生成随机的 UUID
UUID uuid = UUID.randomUUID();
String uniqueId = uuid.toString();
2. Snowflake 算法:Snowflake 是一种分布式唯一 ID 生成算法,通过结合时间戳、机器ID和序列号生成唯一的分布式ID。你可以借助一些第三方库或自行实现 Snowflake 算法。
3. 数据库自增列:在关系型数据库中,可以使用自增列来生成唯一的ID。在插入数据时,数据库会自动为该列生成一个唯一的递增值。
4. 第三方库:还有一些第三方库如 Twitter 的 Snowflake
、Pinterest 的 IdGenerator
等,它们提供了更灵活的唯一 ID 生成方案。
选择哪种方式取决于你的具体需求和应用场景。如果只需要生成唯一的标识符,UUID 是一个简单且常用的选择。如果需要生成全局唯一且趋势递增的 ID,并且要求高性能和可扩展性,则 Snowflake 算法可能更适合。
File工具类
Java中的File流是一种用于读取和写入文件数据的流。它提供了一种简单而灵活的方式来进行文件的输入和输出操作。
Java中的File类表示文件或目录的抽象路径名,在使用File流时通常与InputStream(输入流)和OutputStream(输出流)结合使用,来实现对文件的读取和写入操作。
下面是使用FileInputStream和FileOutputStream读写文件的简单示例:
1. 使用FileInputStream读取文件:
try {
File file = new File("path/to/file.txt");
FileInputStream fis = new FileInputStream(file);
int data;
while ((data = fis.read()) != -1) {
// 处理读取到的数据
System.out.print((char) data);
}
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
上述代码中,通过创建FileInputStream对象并传入要读取的文件路径,然后使用read()方法逐个字节地读取文件内容,直到读取结束。
2. 使用FileOutputStream写入文件:
try {
File file = new File("path/to/file.txt");
FileOutputStream fos = new FileOutputStream(file);
String content = "Hello, World!";
fos.write(content.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
上述代码中,通过创建FileOutputStream对象并传入要写入的文件路径,然后使用write()方法将字符串内容转换为字节数组并写入文件中。
需要注意的是,在使用File流进行文件读写操作时,需要适当处理异常并在操作完成后关闭流,以确保资源被正确释放。
除了FileInputStream和FileOutputStream,Java还提供了其他类型的File流,如BufferedInputStream、BufferedOutputStream,它们可以提供更高效的读写方式。
总结来说,Java的File流是一种用于读取和写入文件数据的功能强大的工具,在文件操作中起着重要的作用。通过File流,我们可以轻松地对文件进行读写,并根据需要进行处理和操作。
应用实例:
package com.idongyou.dongxin.system.util;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonParser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
@Slf4j
public class FileUtils {
public static boolean isJsonFile(MultipartFile file) {
try {
String content = new String(file.getBytes());
JsonParser parser = new JsonParser();
parser.parse(content); // 尝试解析文件内容
return true; // 格式正确
} catch (Exception e) {
log.error("error:",e);
return false; // 格式错误
}
}
// 保存文件到指定目录
public static void saveMultipartFile(MultipartFile file, String fileDir) throws IOException {
// 获取文件名
String fileName = file.getOriginalFilename();
// 在指定目录下创建一个空文件
Path filePath = Path.of(fileDir, fileName);
//如果文件不存在,就创建
if (!Files.exists(filePath)){
Files.createFile(filePath);
}
// 将上传的文件内容保存到指定目录下的文件中
Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);
}
// 保存数据JSON文件到指定目录
public static void saveDataToFile(Object data,String fileStoragePath) throws Exception{
ObjectMapper objectMapper = new ObjectMapper();
// String dataJson = objectMapper.writeValueAsString(data);
File file = new File(fileStoragePath);
if (file.exists() && file.isFile()) {
// 文件存在
log.info("saveDataToFile:{}","文件存在,覆盖保存");
objectMapper.writeValue(file,data);
} else {
// 文件不存在
//直接保存
objectMapper.writeValue(file,data);
}
}
}
时间工具类
在Java中,SimpleDateFormat是一个用于格式化和解析日期时间的类。它允许我们将日期时间对象转换为特定格式的字符串,以及将特定格式的字符串转换为日期时间对象。
下面是使用SimpleDateFormat进行日期时间格式化和解析的示例:
1. 将日期时间对象格式化为字符串:
import java.text.SimpleDateFormat;
import java.util.Date;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date now = new Date();
String formattedDate = sdf.format(now);
System.out.println(formattedDate); // 输出:2023-07-21 02:10:03
上述代码中,首先创建了一个SimpleDateFormat对象,并指定了日期时间的格式模式(“yyyy-MM-dd HH:mm:ss”)。然后,使用format()方法将当前的Date对象按照指定的格式模式转换为字符串。
2. 将字符串解析为日期时间对象:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = "2023-07-21 02:10:03";
try {
Date parsedDate = sdf.parse(dateString);
System.out.println(parsedDate); // 输出:Thu Jul 21 02:10:03 GMT 2023
} catch (ParseException e) {
e.printStackTrace();
}
上述代码中,首先创建了一个SimpleDateFormat对象,并指定了日期时间的格式模式(“yyyy-MM-dd HH:mm:ss”)。然后,使用parse()方法将字符串按照指定的格式模式解析为Date对象。
需要注意的是,在使用SimpleDateFormat进行日期时间格式化和解析时,格式模式的字符串必须与要处理的日期时间字符串保持一致,否则可能会抛出ParseException异常。
除了常见的日期时间格式模式(如"yyyy-MM-dd HH:mm:ss"),SimpleDateFormat还支持其他模式,如年份(“yyyy”)、月份(“MM”)、日(“dd”)、小时(“HH”)、分钟(“mm”)等,具体可参考Java文档中SimpleDateFormat的相关信息。
总结来说,SimpleDateFormat是Java中用于日期时间格式化和解析的类。通过它,我们可以将日期时间对象转换为特定格式的字符串,以及将特定格式的字符串转换为日期时间对象,非常方便实用。
应用实例:
package com.idongyou.dongxin.system.util;
import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import java.beans.PropertyEditorSupport;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.TimeZone;
/**
* DateUtils
*
* @author nml
* @date 2021/7/21 14:58
*/
@Slf4j
public class DateUtils extends PropertyEditorSupport {
public static ThreadLocal<SimpleDateFormat> date_sdf = new
ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};
public static ThreadLocal<SimpleDateFormat> datetimeFormat = new
ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
// 以毫秒表示的时间
private static final long DAY_IN_MILLIS = 24 * 3600 * 1000;
private static final long HOUR_IN_MILLIS = 3600 * 1000;
private static final long MINUTE_IN_MILLIS = 60 * 1000;
private static final long SECOND_IN_MILLIS = 1000;
public static final String YYYY_MM_DD = "yyyy-MM-dd";
public static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static final String YYYYMMDD = "yyyyMMdd";
public static final String YYMMDD = "yyMMdd";
public static final String YYMMDDHHMMSS = "yyMMddHHmmss";
public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static final String YYMMDDHHMMSSSSS = "yyMMddHHmmssSSS";
public static final String YYYYMMDD_HH_MM_SS = "yyyy_MM_dd_HH_mm_ss";
// 指定模式的时间格式
private static SimpleDateFormat getSDFormat(String pattern) {
return new SimpleDateFormat(pattern);
}
/**
* 当前日历,这里用中国时间表示
*
* @return 以当地时区表示的系统当前日历
*/
public static Calendar getCalendar() {
return Calendar.getInstance();
}
/**
* 获取时间字符串
*/
public static String getDataString(SimpleDateFormat formatstr) {
return formatstr.format(getCalendar().getTime());
}
/**
* 日期字符串 转为 Calendar
*/
public static Calendar dateStr2Calendar(String date, String pattern) {
SimpleDateFormat format = getSDFormat(pattern);
Calendar calendar = Calendar.getInstance();
try {
calendar.setTime(format.parse(date));
} catch (ParseException e) {
e.printStackTrace();
}
return calendar;
}
/**
* 指定毫秒数表示的日历
*
* @param millis 毫秒数
* @return 指定毫秒数表示的日历
*/
public static Calendar getCalendar(long millis) {
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(millis));
return cal;
}
public static DateFormat getDateFormat(String dateFormat) {
return new SimpleDateFormat(dateFormat);
}
/**
* 取得某天所在周的第一天
*
* @param date
* @return
*/
public static Date getFirstDayOfWeek(Date date) {
Calendar c = new GregorianCalendar();
c.setFirstDayOfWeek(Calendar.MONDAY);
c.setTime(date);
c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
return c.getTime();
}
/**
* 获取星期几
*
* @param date
* @return
*/
public static int getWeekDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
return dayOfWeek - 1;
}
/**
* 根据开始时间和结束时间返回时间段内的时间集合
*
* @param beginDateStr
* @param endDateStr
* @return List
*/
public static List<String> getDateStrsBetweenTwoDate(String beginDateStr, String endDateStr) {
List<String> lDate = new ArrayList<String>();
lDate.add(beginDateStr);// 把开始时间加入集合
Calendar cal = Calendar.getInstance();
// 使用给定的 Date 设置此 Calendar 的时间
Date beginDate = str2Date(beginDateStr, date_sdf.get());
Date endDate = str2Date(endDateStr, date_sdf.get());
cal.setTime(beginDate);
boolean bContinue = true;
while (bContinue) {
// 根据日历的规则,为给定的日历字段添加或减去指定的时间量
cal.add(Calendar.DAY_OF_MONTH, 1);
// 测试此日期是否在指定日期之后
if (endDate.after(cal.getTime())) {
lDate.add(date2Str(cal.getTime(), date_sdf.get()));
} else {
break;
}
}
lDate.add(endDateStr);// 把结束时间加入集合
return lDate;
}
/**
* 根据开始时间和结束时间返回时间段内的时间集合
*
* @param beginDate
* @param endDate
* @return List
*/
public static List<Date> getDatesBetweenTwoDate(Date beginDate, Date endDate) {
List<Date> lDate = new ArrayList<Date>();
lDate.add(beginDate);// 把开始时间加入集合
Calendar cal = Calendar.getInstance();
// 使用给定的 Date 设置此 Calendar 的时间
cal.setTime(beginDate);
boolean bContinue = true;
while (bContinue) {
// 根据日历的规则,为给定的日历字段添加或减去指定的时间量
cal.add(Calendar.DAY_OF_MONTH, 1);
// 测试此日期是否在指定日期之后
if (endDate.after(cal.getTime())) {
lDate.add(cal.getTime());
} else {
break;
}
}
lDate.add(endDate);// 把结束时间加入集合
return lDate;
}
}