1、获取用户的某种类型的行为数据列表(某一时间段内发生的),行为记录时间需要精确到分钟数取整,丢弃掉秒、毫秒的数据
实现方案①:
// 查询出这批数据集合,然后遍历数据集合,分别对每个日期进行精度处理
List<ActionData> actionList ---》 查询数据库获取
for(int i = 0; i < actionList.size(); i++) {
actionList.get(i).setStartTime(this.process(actionList.get(i).getStartTime().getTime()));
}
/**
* 时间戳 移除秒、豪秒部分(忽略掉秒的精度,只保留整分钟数的精度)
*
* @param timestamp
* @return
*/
public Long process(long timestamp) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timestamp);
calendar.set(Calendar.SECOND, 0);
long value = calendar.getTimeInMillis() / 1000;
return value * 1000;
}
实现方案②:
// 因为查询的数据是通过跨服务查询的,所以可以利用在跨服务传输时,返回结果的参数进行json序列化时,自动忽略掉,秒、毫秒部分的精度
实现过程图解:
public class QueryResponsePO {
/** 主键id */
@JsonSerialize(using = ToStringSerializer.class)
@ApiModelProperty(value = "主键ID")
private Long id;
/**
* 科室名称
*/
@ApiModelProperty(value = "科室名称")
private String deptName;
/** 创建时间 */
@ApiModelProperty(value = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
private Date createTime;
// 省略getter、setter
}
实现效果:最后Feign调用完成后,响应的List集合数据里面的每个PO的时间格式参数已经自动忽略了秒、豪秒的数据了
2、下载excel导出模板,打包之后上开发环境时报错,路径找到不文件
错误日志如下:
cannot be resolved to absolute file path because it does not reside in the file system
原来的代码:
String path = "classpath:template.xlsx";
File file = ResourceUtils.getFile(path);
InputStream inputStream = new FileInputStream(file);
......
解决方案:服务打成Jar包后,文件的实际路径是存在于服务器上的,还是通过文件路径的方式去访问文件,会报错,抛出FileNotFoundException的异常,应该按照Jar里面的文件读取方式,进行文件流的操作
String path = "template.xlsx";
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(path);
......
重新打包上开发环境后,经验证可以正常下载模板excel文件
3、正则表达式支持英文、数字和特殊字符(仅支持英文键盘下的特殊字符)
@Pattern(regexp = "^([a-zA-Z0-9\\\\W_!@#$%^&*`~()-+=\\.\\,\\?\\-\\/\\:\\;\\{\\}\\(\\)\\|\\'\"\\[\\]\\>\\<]){8,20}$", message = "密码需为8至20位,包含数字、字母和特殊符号")
4、2个List集合数据,大的集合数据有3000条,小的集合数据大概有300条左右(几百条的范围,反正比大的数据集合少,正常使用场景下),需要遍历2个集合进行比较里面的数据,若相同,则将小集合的数据对应的值设置到大集合对应的值中,尽量使查询的时间复杂度降低
正常的比较方式,遍历2个集合,然后一个一个元素的去比较,时间复杂度为: O(N) * O(n) --> 3000 * 300
比较实体类:
package com.opencv.domain.po;
public class CompareMessagePO {
private Long compareNum;
private String message;
public Long getCompareNum() {
return compareNum;
}
public void setCompareNum(Long compareNum) {
this.compareNum = compareNum;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
方式一的比较测试类设计:
package com.opencv.controller;
import com.opencv.domain.po.CompareMessagePO;
import java.util.ArrayList;
import java.util.List;
public class ListCompareTests {
public static List<CompareMessagePO> COMPARE_HIGH_LIST = new ArrayList<>();
public static List<CompareMessagePO> COMPARE_LOW_LIST = new ArrayList<>();
static {
for(int i = 0; i < 3000; i ++) {
CompareMessagePO compareMessagePO = new CompareMessagePO();
compareMessagePO.setCompareNum(Long.valueOf(i));
COMPARE_HIGH_LIST.add(compareMessagePO);
}
for (int i = 100; i < 300; i ++) {
CompareMessagePO compareMessagePO = new CompareMessagePO();
compareMessagePO.setCompareNum(Long.valueOf(i));
compareMessagePO.setMessage("test message : " + i);
COMPARE_LOW_LIST.add(compareMessagePO);
}
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < COMPARE_LOW_LIST.size(); i ++) {
for(int j = 0; j < COMPARE_HIGH_LIST.size(); j ++) {
if(COMPARE_LOW_LIST.get(i).getCompareNum().longValue() == COMPARE_HIGH_LIST.get(j).getCompareNum().longValue()) {
COMPARE_HIGH_LIST.get(j).setMessage(COMPARE_LOW_LIST.get(i).getMessage());
}
}
}
long endTime = System.currentTimeMillis();
long costTime = endTime - startTime;
long secondTime = costTime / 1000;
System.out.println("耗时:" + secondTime + "秒 , " + costTime + "毫秒");
System.out.println("-----------------------");
for (int i = 100; i < 300; i ++) {
String message = COMPARE_HIGH_LIST.get(i).getMessage();
System.out.println(message);
}
System.out.println("------------------------");
}
}
方式二的比较测试类设计:
package com.opencv.controller;
import com.opencv.domain.po.CompareMessagePO;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ListCompareNextTests {
public static List<CompareMessagePO> COMPARE_HIGH_LIST = new ArrayList<>();
public static Map<Long, String> COMPARE_LOW_MAP = new HashMap<>();
static {
for(int i = 0; i < 3000; i ++) {
CompareMessagePO compareMessagePO = new CompareMessagePO();
compareMessagePO.setCompareNum(Long.valueOf(i));
COMPARE_HIGH_LIST.add(compareMessagePO);
}
for (int i = 100; i < 300; i ++) {
COMPARE_LOW_MAP.put(Long.valueOf(i), "test message : " + i);
}
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
for(int j = 0; j < COMPARE_HIGH_LIST.size(); j ++) {
if(COMPARE_LOW_MAP.containsKey(COMPARE_HIGH_LIST.get(j).getCompareNum())) {
COMPARE_HIGH_LIST.get(j).setMessage(COMPARE_LOW_MAP.get(COMPARE_HIGH_LIST.get(j).getCompareNum()));
}
}
long endTime = System.currentTimeMillis();
long costTime = endTime - startTime;
long secondTime = costTime / 1000;
System.out.println("耗时:" + secondTime + "秒 , " + costTime + "毫秒");
System.out.println("-----------------------");
for (int i = 100; i < 300; i ++) {
String message = COMPARE_HIGH_LIST.get(i).getMessage();
System.out.println(message);
}
System.out.println("------------------------");
}
}
测试结果
方式①:
方式②:
2种方式的性能比较相差了18倍,若集合的数据量很大的情况下,估计性能相差更明显,倍数更大,方式②是以空间换时间,对空间的消耗上比方式①大