Java 常用方法

目录

List常用方法

判断List集合中是否存在相同元素

判空

集合流方法使用

TryCatch基本使用

导入导出Excel

Json字符串转换为对应类型

后台post请求接口

@Value注解读取配置属性值

正则匹配

反射机制

测试类

多线程ThreadPoolExecutor

设计模式之单例模式

不可变map

ObjectMapper

Java生成唯一id

File工具类

时间工具类


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反射机制为程序员提供了更大的灵活性和编程能力,通常用于以下几个方面:

  1. 动态加载类:Java反射机制可以在程序运行时根据类名称加载相应的类,实现类的动态加载。
  2. 动态创建对象:Java反射机制可以通过调用Class对象的newInstance()方法动态地创建对象,有利于代码的扩展性和复用性。
  3. 动态调用方法:Java反射机制可以在运行时动态调用方法,不需要事先知道方法名,极大地拓展了程序的功能性。
  4. 访问私有属性和方法:Java反射机制可以通过设置setAccessible()方法来访问类的私有属性和方法,而不受访问修饰符的限制。
  5. 实现泛型数组:Java反射机制可以实现泛型数组的创建和访问,提高了程序的可读性和可维护性。

总之,Java反射机制是Java语言中的一个重要机制,通过反射技术,程序员可以在运行时获取并操作类的结构信息,提高程序的灵活性和可扩展性。

1 获得Class:主要有三种方法:

  1. Object–>getClass
  2. 任何数据类型(包括基本的数据类型)都有一个“静态”的class属性
  3. 通过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;
    }
    
    
}    

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值