日常开发中代码技巧
String,StringBuffer判断非空
-
String判断非空
参考:https://blog.csdn.net/Echo_width/article/details/79653704
首先,区分空串和null串
-
1 空串""是长度为0的字符串,它有自己的串长度(0)和内容(空),判断一个字符串为空的方法:
// if (str.length() == 0); //变式 if (str.equals(""));
-
2、 null串表示目前没有任何对象与该变量关联,检查一个字符串是否为null的方法:
if (str == null);
-
3、检查一个字符串既不是null串也不是空串,多用以下方法判断:
if (str != null && str.length() != 0);
注意:要先检查str不为null,否则在一个null值上调length()方法会出现错误。
-
4、使用StringUtils工具类,判断不为null也不是空,如下:
if (StringUtils.isNotBlank(str))
-
-
StringBuffer判断非空
很简单,一种是利用StringBuffer的length()判断,另一种事转换为String判断
//1. if(stringBuffer.length() > 0){ System.out.println("非空") } //2.
List转数组和数组转List
List转换为数组
很简单 一句话就解决了 主要有两种方法 这两种方法本质上是一样的 只不过是写法不同而已
-
使用Stream
String[] ss = list.stream().toArray(String[]::new);
-
使用List中的toArray()方法
String[] sss = list.toArray(new String[listStrings.size()]);
举个实例:
public void listTransArrayTest() {
//先初始化集合
List<Seckill> seckillList = new ArrayList<>(15);
Date time = new Date(System.currentTimeMillis());
long seckillId = 1001l;
System.out.println("=========集合转换为数组===========");
for (int i = 0; i <= 10; i++) {
Seckill seckill = new Seckill(seckillId, "秒杀" + i, i, time, time, time);
seckillList.add(seckill);
seckillId++;
}
//转换方式1
// Seckill[] result = seckillList.toArray(new Seckill[seckillList.size()]);
//转换方式2 使用jdk1.8的stream流
Seckill[] result = seckillList.stream().toArray(Seckill[]::new);
System.out.println("转换成功 开始显示转换后的数组");
for (Seckill seckill : result) {
System.out.println(seckill);
}
数组转换为List
这里有一个坑 等下再详细说
可能很多人都会直接想到下面这种方法
String[] arrays = new String[]{"a", "b", "c"};
List<String> listStrings = Arrays.asList(arrays);
但是这里有两个坑
-
一是asList转换的是基本类型的数组的话,如int[] 转换失败 转换后的集合只有一个元素;
-
二是asList转换后的集合不能add和remove的 因为asList转换后的集合类型并不是java.util.ArrayList,而是Arrays的一个内部类,这个内部类并没有add方法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
这个内部类的方法及属性如下。可以看到并没有add(),remove()。而set(int index,E element)修改方法但是有
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
如果你想转换后的list可以add或者remove,那就使用下面的方法:
/*方法一*/
ArrayList<Integer> copyArrays=new ArrayList<>(Arrays.asList(integerArray));
/*方法二*/
List<Integer> integerList = new ArrayList<>();
Collections.addAll(integerList, integerArray);
参考博客:https://blog.csdn.net/weixin_41835612/article/details/83611082
位运算的实用技巧
1. 求奇数偶数
(n&1) == 0 这个表示偶数
2. 交换两个数
a ^= b;
b ^= a;
a ^= b;
参考博客:https://blog.yangx.site/2016/07/06/bit-operation-skills/ 或者到印象笔记那找
位进制转换
-
16进制转10进制
Integer.parseInt("0xAA".substring(2));
-
10进制 转16进制
Integer.toHexString(56);
mybatis的时间类型数据转换问题
字符串常见操作
按照某些字符进行分割截取
比如按照空格进行分割,StringUtils中封装了很多截取操作
mysql相关操作
主要是将平时遇到的有用的sql语句记录下来
比较两个select结果集中不一样的数据
比如我现在有两个
使用instr和concat完成模糊查询
使用INSTR和concat可以完成模糊查询,主要的作用是用于查询那种字段中有特殊字符分隔开值的,比如username中多个名字之间用,分割开。当然使用like也可以,只不过这也是一种方式。
下面是这两个函数的定义
INSTR
INSTR()
函数返回字符串中子字符串第一次出现的位置。如果在str
中找不到子字符串,则INSTR()
函数返回零(0
)。
下面说明了INSTR
函数的语法。
INSTR(str,substr);
INSTR
函数接受两个参数:
str
是要搜索的字符串。substr
是要搜索的子字符串。
INSTR()
函数不区分大小写。这意味着如果通过小写,大写,标题大小写等,结果总是一样的。
CONCAT:
连接字符串的函数
使用方式
and INSTR(CONCAT(',',#{reqid},','),CONCAT(",",t1.linkreqid,","))
springboot下的文件下载功能
https://blog.csdn.net/qq_15329947/article/details/100894906#commentBox
这是原文:https://www.callicoder.com/spring-boot-file-upload-download-rest-api-example/(原文中除了下载功能还有上传功能)
List.sort(Compareable compa)
背景:
有时候有一些比较复杂的排序方法我们不好用stream流的方式 只好用
流
数据库操作
将查询结果的某一列作为条件
当你使用下面的语句时会报错
delete FROM sys_xm_role where xmroleid in (
select a.xmroleid from (
select xmroleid,username
from sys_xm_role
group by projid,roleid HAVING COUNT(projid) >1 and COUNT(roleid) > 1)a
)
报错信息:You can’t specify target table ‘sys_xm_role’ for update in FROM clause
正确的做法是:
delete FROM sys_xm_role where xmroleid in (
select a.xmroleid from (
select xmroleid
from sys_xm_role
group by projid,roleid HAVING COUNT(projid) >1 and COUNT(roleid) > 1)a
)
集合的相关操作
参考:https://blog.csdn.net/qq_41902662/article/details/113843735
集合倒序输出
最简单的是这个
Collections.reverse(vsImVos);
这个排序的依据是集合里对象本身
这个应该是需要对象实现compare接口,或者要么就实现.equal方法
HashMap的遍历
很多种方式 但是还是Entry.entry最快速并且安全
java 8 stream:去重,排序,筛选,分组,聚合计算
流是从支持数据处理操作的源生成的元素序列,源可以是数组、文件、集合、函数。流不是集合元素,它不是数据结构并不保存数据,它的主要目的在于计算
- 测试对象和数据
/**
* @Description : stream流测试对象
*/
//允许链式set
@Accessors(chain = true)
@Data
public class StreamDto {
private String name;
private String addr;
private Integer age;
private Date birthDay;
private BigDecimal money;
public StreamDto(String name, String addr, Integer age, Date birthDay, BigDecimal money) {
this.name = name;
this.addr = addr;
this.age = age;
this.birthDay = birthDay;
this.money = money;
}
public StreamDto() {
}
}
StreamDto d1 = new StreamDto();
d1.setName("a").setAddr("北京").setAge(20)
.setBirthDay(DateUtil.parse("2020-10-12")).setMoney(new BigDecimal(3));
StreamDto d2 = new StreamDto();
d2.setName("a").setAddr("南京").setAge(12)
.setBirthDay(DateUtil.parse("2020-10-13")).setMoney(new BigDecimal(1));
StreamDto d3 = new StreamDto();
d3.setName("b").setAddr("北京").setAge(23)
.setBirthDay(DateUtil.parse("2020-10-11")).setMoney(new BigDecimal(2));
List<StreamDto> list = CollUtil.toList(d1,d2,d3);
System.out.println("原始List=="+list.toString());
List排序
-
不用stream 排序
//age升序 list.sort(Comparator.comparing(StreamDto::getAge)); //age降序 list.sort(Comparator.comparing(StreamDto::getAge).reversed()); //正序排序,并将null放在最后(搭配reversed()就变成倒序):小->大->null list.sort(Comparator.comparing(StreamDto::getBirthday, Comparator.nullsLast(Date::compareTo))); //先正序排序,并将null放在最前,搭配reversed()翻转就变成倒序:大->小->null list.sort(Comparator.comparing(StreamDto::getBirthday, Comparator.nullsFirst(Date::compareTo)).reversed()); //先后排序 list.sort(Comparator.comparing(StreamDto::getAge).reversed() .thenComparing(Comparator.comparing(StreamDto::getName).reversed()) .thenComparing(Comparator.comparing(StreamDto::getAddr).reversed()));
-
使用stream
//age升序 List<StreamDto> l1 = list.stream().sorted(Comparator.comparing(StreamDto::getAge)) .collect(Collectors.toList()); //age降序 l1 = list.stream().sorted(Comparator.comparing(StreamDto::getAge).reversed()) .collect(Collectors.toList()); //正序排序,并将null放在最后(搭配reversed()就变成倒序):小->大->null l2 = list.stream().sorted(Comparator.comparing(StreamDto::getBirthday, Comparator.nullsLast(Date::compareTo))).collect(Collectors.toList()); //先正序排序,并将null放在最前,搭配reversed()翻转就变成倒序:大->小->null l3 = list.stream().sorted(Comparator.comparing(StreamDto::getBirthday, Comparator.nullsFirst(Date::compareTo)).reversed()).collect(Collectors.toList());
List 聚合计算
//包含了: 计数,最大,最小,求和,平均数, 每种方式都有单独的方式实现
DoubleSummaryStatistics statistics = list.stream()
.collect(Collectors.summarizingDouble(StreamDto::getAge));
System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",min=:" + statistics.getMin() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage());
//count:3,max:23.0,min=:12.0,sum:55.0,average:18.333333333333332
//计数:
long count = list.stream().count();//3
//最大/最小,两种方式:
//sorted: 先按年龄降序排列后取第一个,同理最小则升序取第一
Integer max = list.stream().sorted(Comparator.comparing(StreamDto::getAge).reversed()).map(StreamDto::getAge).findFirst().get();
System.out.println("max = " + max);
//min/max
Integer min = list.stream().min(Comparator.comparing(StreamDto::getAge)).get().getAge();
System.out.println("min = " + min);
//求和
Integer sum1 = list.stream().collect(Collectors.summingInt(StreamDto::getAge));
Integer sum2 = list.stream().map(StreamDto::getAge).reduce(Integer::sum).get();
//平均数
Double collect2 = list.stream().collect(Collectors.averagingInt(StreamDto::getAge));
double asDouble = list.stream().mapToLong(StreamDto::getAge).average().getAsDouble();
double asDouble1 = list.stream().mapToInt(StreamDto::getAge).average().getAsDouble();
//...
List条件筛选
List<StreamDto> l1 = null;
//条件筛选
l1 = list.stream().filter(b -> b.getAge() > 15).collect(Collectors.toList());
//多条件
l1 = list.stream()
.filter(b -> DateUtil.compare(new Date(),b.getBirthDay()) > 0
&& b.getAge() < 15 )
.collect(Collectors.toList());
l1 = list.stream()
.filter(b -> b.getMoney().compareTo(new BigDecimal(2)) > -1).collect(Collectors.toList());
List 分组
//name分组
Map<String,List<StreamDto>> map = list.stream().collect(Collectors.groupingBy(StreamDto::getName));
//二级分组
Map<String,Map<Integer,List<StreamDto>>> map1 = list.stream().collect(Collectors.groupingBy(StreamDto::getName,Collectors.groupingBy(StreamDto::getAge)));
//二级分组,统计数量
Map<String,Map<Integer,Long>> map2 = list.stream().collect(Collectors.groupingBy(StreamDto::getName,Collectors.groupingBy(StreamDto::getAge,Collectors.counting())));
//多条件分组
map = list.stream().collect(Collectors.groupingBy(b -> b.getName() + "-" + b.getAge()));
//分组后又对集合进行处理,方式1
Map<String,List<String>> map3 = list.stream().collect(Collectors.groupingBy(StreamDto::getName,Collectors.groupingBy(StreamDto::getAge,Collectors.mapping(StreamDto::getAddr, Collectors.toList()))));
//方式2,只是拓展,不推荐
map3 = list.stream().collect(Collectors.groupingBy(StreamDto::getName)).entrySet().stream().collect(Collectors.toMap(b -> b.getKey(), b -> CollUtil.map(b.getValue(), StreamDto::getAddr, true)));
// 按照某列出现的次数分组
List去重
//根据Addr去重
List<StreamDto> list1 = list.stream()
.collect(Collectors.collectingAndThen(Collectors.toCollection(
() -> new TreeSet<>(Comparator.comparing(StreamDto::getAddr))
), ArrayList::new));
//简单去重
list1 = list.stream().distinct().collect(Collectors.toList());
List 转map
Map<String, Date> m = list.stream().collect(Collectors.toMap(b -> b.getName(), b -> b.getBirthDay()));
Map<String, StreamDto> collect3 = list.stream().collect(Collectors.toMap(b -> b.getName(), b -> b));
返回自封装的List实现类
//封装的List实现,用于链式添加:addObj()和addObjs()
ArrayListProxy<String> allPlatNames = new ArrayListProxy<>();
allPlatNames.addObjs(bidSecPlats).addObjs(projPlats);
//去重,这里要返回ArrayListProxy必须自己实现,collect(Collectors.toList())只能返回List,allPlatNames接收不了
allPlatNames = allPlatNames.stream().distinct().collect(ArrayListProxy::new, (r, x) -> {
r.addObj(x);
}, List::addAll);
集合合并返回新集合
List<String> list1 = CollUtil.toList("1");
List<String> list2 = CollUtil.toList("2");
List<List<String>> all = CollUtil.toList(list1, list2);
/**
* 第一种方式
*/
ArrayList<String> collect = all.stream().collect(ArrayList::new, (list, value) -> list.addAll(value), List::addAll);
//或者
//串行流:第一个元素时会通过ArrayList::new获得一个初始化容器a,容器a执行ArrayList::addAll方法操作流中的每一个元素,最后返回容器a,最后容器a就只有一个,所以不会用到List::addAll
ArrayList<String> collect = all.stream().collect(ArrayList::new, ArrayList::addAll, List::addAll);
//并行流:将all中的元素分片处理,每片中第一个元素时会通过ArrayList::new获得一个初始化容器a,
//容器a执行ArrayList::addAll方法操作流中的每一个元素,每片最后会返回容器a,最后多个容器a通过List::addAll方法合并后输出
ArrayList<String> collect = all.parallelStream().collect(ArrayList::new, ArrayList::addAll, List::addAll);
/**
* 第二种方式
* reduce
*/
//new ArrayList<>() 作为初始值加入计算
List<String> reduce = all.stream().reduce(CollUtil.toList("3"), (b, c) -> {
b.addAll(c);
return b;
});//返回["3","1","2"]
//不添加初始值计算
Optional<List<String>> reduce = all.stream().reduce((b, c) -> {
b.addAll(c);
return b;
});//返回["1","2"]
Map转换
//假设有数据
Map<String, List<StreamDto>> map = new HashMap<>();
//取出key和集合中第一个对象的时间参数
Map<String, Date> m = map.entrySet().stream()
.collect(Collectors.toMap(b -> b.getKey(), b -> b.getValue().get(0).getBirthDay()));
Map排序
//前5名
Map<String, Long> top5Names = new LinkedHashMap<>();
//假设有数据
List<String> mainQ = new ArrayList<>();
//分组后统计数量
Map<String, Long> countMap = mainQ.stream()
.collect(Collectors.groupingBy(b -> b, Collectors.counting()));
//value排序,然后取出前5名
countMap.entrySet().stream().sorted(Map.Entry.<String, Long>comparingByValue().reversed()).forEachOrdered(b -> {
if (top5Names.size() < 6) {
top5Names.put(b.getKey(), b.getValue());
}
});
//取出全部
Map<String, Long> allMap = countMap.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.collect(Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> newValue, LinkedHashMap::new
));
//key排序
countMap.entrySet().stream().sorted(Map.Entry.<String, Long>comparingByKey().reversed());
Map过滤
//假设有数据
List<String> mainQ = new ArrayList<>();
Map<String, Long> countMap = mainQ.stream()
.collect(Collectors.groupingBy(b -> b, Collectors.counting()));
//map过滤
countMap.entrySet().stream().filter(b -> b.getKey() != "").collect(HashMap::new, (m, e) -> m.put(e.getKey(), e.getValue()), HashMap::putAll);
Map合并
/**
* @Description: 合并两个map,如果key相同,那么选取时间靠后的value
*/
public static Map<String, Date> concatMap(Map<String, Date> map1, Map<String, Date> map2) {
Map<String, Date> result = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (value1, value2) -> {
if (DateUtil.compare(value1, value2) >= 0) {
return value1;
} else {
return value2;
}
}));
return result;
}
Map遍历
/**
* 遍历Map的方式
*/
Map<String,List<ResOrgUserDto>> map =new HashMap<>();
//1.通过Map.keySet遍历key和value
for (String key : map.keySet()) {
System.out.println(map.get(key));
}
//Java8
map.keySet().forEach(k -> {
System.out.println(map.get(k));
});
//2.通过Map.entrySet使用Iterator遍历key和value
while (map.entrySet().iterator().hasNext()){
Map.Entry<String,List<ResOrgUserDto>> entry = map.entrySet().iterator().next();
System.out.println(entry.getValue());
}
//Java8
map.entrySet().iterator().forEachRemaining(m -> System.out.println(m.getValue()));
//3.通过Map.entrySet遍历key和value,在大容量时推荐使用
for (Map.Entry<String, List<ResOrgUserDto>> entry : map.entrySet()) {
System.out.println(entry.getValue());
}
//Java8
map.entrySet().forEach(entry -> {
System.out.println(entry.getValue());
});
//4.通过Map.values()遍历所有的value,但不能遍历key
for (List<ResOrgUserDto> values : map.values()) {
System.out.println(values);
}
//Java8
map.values().forEach(v -> {
System.out.println(v);
});
//5.通过k,v遍历,Java8独有的
map.forEach((k,v) -> {
System.out.println(v);
});
List,Map综合
//前5名名称
List<String> names = top5Names.entrySet().stream().map(b -> b.getKey()).collect(Collectors.toList());
//获取各表前五名平台的最后数据接收时间
Map<String, Date> bidSecLasts = bidSecQ.stream().filter(b -> names.contains(b.getTradeplat()))//筛选出前5的数据
.sorted(Comparator.comparing(BusBidsection::getSubmittimestamp).reversed())//先排序
.collect(Collectors.groupingBy(BusBidsection::getTradeplat))//在分组
//最后取出key和最后数据接收时间
.entrySet().stream().collect(Collectors.toMap(b -> b.getKey(), b -> b.getValue().get(0).getSubmittimestamp()));