Map集合按value值排序、与javaBean互转以及jdk8的时间操作
1、Map集合按value值进行排序
最近遇到业务是es聚合查询后把返回的数据在前端按柱状图显示,这里就需要按map的value值排序。这里写一个能迅速给map<String,Integer>的数据进行按value排序的方法:
public static void main(String[] args) {
Map<String,Integer> m = new HashMap<>();
m.put("Pa001",3);
m.put("Pa002",33);
m.put("Pa003",8);
m.put("Pa004",56);
m.put("Pa005",2);
m.put("Pa006",189);
m.put("Pa007",999);
Map<String,Object> map = getArrAfterSort(m);
System.out.println(map);
}
public static Map<String,Object> getArrAfterSort(Map<String,Integer> m){
Map<String,Object> map = new HashMap<>();
map.clear();
List<Map.Entry<String,Integer>> list = new ArrayList<>(m.entrySet());
Collections.sort(list, (o1, o2) -> {
int flag = o1.getValue().compareTo(o2.getValue());
if(flag == 0){
return o1.getKey().compareTo(o2.getKey());
}
return flag;
});
Integer[] valueArr = new Integer[list.size()];
String[] keyStr = new String[list.size()];
int i=0;
for(Map.Entry<String,Integer> en:list){
valueArr[i]=en.getValue();
keyStr[i] = en.getKey();
i++;
}
map.put("xAis",keyStr);
map.put("yAis",valueArr);
return map;
}
结果: xAis 数组:
0 = “Pa005”
1 = “Pa001”
2 = “Pa003”
3 = “Pa002”
4 =“Pa004”
5 = “Pa006”
6 = “Pa007”
yAis数组:
0 = {Integer@684} 2
1 = {Integer@685} 3
2 = {Integer@686} 8
3 = {Integer@687} 33
4 = {Integer@688} 56
5 = {Integer@689} 189
6 = {Integer@690} 999
把这样的数据返回前端就能按高低显示柱状图了。
2、利用反射实现JavaBean与Map集合互转的通用方法
/**
* 把对象转为Map 通用方法,即使对象中有继承父类也适用的
*/
public static Map<String, Object> beenToMap(Object obj) throws IllegalAccessException {
Map<String, Object> map = new HashMap<>();
map.clear();
if (null == obj) {
return map;
}
Class<?> aClass = obj.getClass();
//遍历父类
while (null != aClass.getSuperclass()) {
Field[] declaredFields = aClass.getDeclaredFields();
for (Field field : declaredFields) {
String name = field.getName();
//获取原来的访问控制权限
boolean accessible = field.isAccessible();
//让我们在用反射时访问私有变量,true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查
field.setAccessible(true);
Object value = field.get(obj);
//恢复访问控制权限
field.setAccessible(accessible);
if (null != value && !StringUtils.isBlank(value.toString())) {
//如果是List,将List转为JSON
if (value instanceof List) {
value = JSON.toJSONString(value);
}
map.put(name, value);
}
}
//获取父类,继续遍历
aClass = aClass.getSuperclass();
}
return map;
}
/**
* Map转对象
*/
public static Object map2JavaBean(Class<?> clazz, Map<String, Object> map) {
try {
Object obj = clazz.newInstance();
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.getName().startsWith("set")) {
String field = method.getName();
field = field.substring(field.indexOf("set") + 3);
field = field.toLowerCase().charAt(0) + field.substring(1);
if (map.containsKey(field)) {
method.invoke(obj, map.get(field));
}
}
}
return obj;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
*测试方法:用于测试上面两个方法
**/
public static void main(String[] args) {
//IotpInvokeInfoDTO是一个继承了父类的类
IotpInvokeInfoDTO iotpInvokeInfoDTO = new IotpInvokeInfoDTO();
iotpInvokeInfoDTO.setClientCode("46");
iotpInvokeInfoDTO.setResult("234523");
iotpInvokeInfoDTO.setUserId("w3450");
iotpInvokeInfoDTO.setCompanyCode("324");
iotpInvokeInfoDTO.setEnv("345");
iotpInvokeInfoDTO.setInvokeDate("2345");
iotpInvokeInfoDTO.setLoginTimeMills(234243252L);
iotpInvokeInfoDTO.setSv("2345");
iotpInvokeInfoDTO.setUnitCode("2354");
try {
Map<String, Object> stringObjectMap = TimeOfjdk8Utils.beenToMap(iotpInvokeInfoDTO);
System.out.println(stringObjectMap);
Object obj = TimeOfjdk8Utils.map2JavaBean(IotpInvokeInfoDTO.class, stringObjectMap);
IotpInvokeInfoDTO iii = (IotpInvokeInfoDTO)obj;
System.out.println(iii);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
3、 jdk8的时间操作
最近遇到
SimpleDateFormat
出现线程不安全的情况,解决办法是枷锁,但是加锁不是最好的解决办法,毕竟影响速度,所以重新学习一下jdk对时间的操作。
1、获取当前时间和时间毫秒数
//获取当前日期
LocalDate localDate = LocalDate.now();
//获取当前时间
LocalTime localTime = LocalTime.now();
//获取当前日期时间
LocalDateTime localDateTime = LocalDateTime.now();
//获取当前时间毫秒(方法一)
Instant now = Instant.now();
long nowMills = now.toEpochMilli();
//获取当前时间毫秒(方法二)
Instant now = Instant.now();
//偏移量运算(把时区设为自己的)
OffsetDateTime offsetDateTime = now.atOffset(ZoneOffset.ofHours(8));
Instant instant = offsetDateTime.toInstant();
long offsetDateTimeMills = instant.toEpochMilli();
/**
*这里方法1、方法2获取到的时间毫秒是一样的,因为时间毫秒数与时区无关
**/
2、常用时间格式转换(LocalDateTime <==> String <==> Long
)
//LocalDateTime时间 转为字符串
LocalDateTime ldt1 = LocalDateTime.now();
DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String strDate2 = dtf2.format(ldt1);
//时间字符串 转为LocalDateTime格式
LocalDateTime localDateTime = LocalDateTime.parse(strDate2, dtf2);
//把LocalDateTime时间转为毫秒数
long localDateTimeMills = localDateTime.atZone(ZoneId.of("Asia/Shanghai")).toInstant().toEpochMilli();
//把时间毫秒数转为LocalDateTime类型
LocalDateTime ldt5 = Instant.ofEpochMilli(localDateTimeMills).atZone(ZoneId.of("Asia/Shanghai")).toLocalDateTime();
System.out.println("ldt1:"+ldt1);
System.out.println("strDate2:"+strDate2);
System.out.println("localDateTime:"+localDateTime);
System.out.println("localDateTimeMills:"+localDateTimeMills);
System.out.println("ldt5 :"+ldt5);
以上转换足够平时使用,其输出分别是:
ldt1:2021-08-06T22:53:35.455
strDate2:2021-08-06 22:53:35
localDateTime:2021-08-06T22:53:35
localDateTimeMills:1628261615000
ldt5:2021-08-06T22:53:35