java去除List集合中null元素
list.removeAll(Collections.singleton(null));
List nullList = new ArrayList();
nullList.add(null);
list.removeAll(nullList);
Iterator it = list.iterator();
while (it.hasNext()) {
if (it.next() == null) {
it.remove();
}
}
Date to LocalDateTime 与 LocalDateTime to Date
Date todayDate = new Date();
LocalDateTime ldt = todayDate.toInstant()
.atZone( ZoneId.systemDefault() )
.toLocalDateTime();
LocalDateTime localDateTime = LocalDateTime.now();
Date date = Date.from( localDateTime.atZone( ZoneId.systemDefault()).toInstant());
public class DateUtils {
public static Date asDate(LocalDate localDate) {
return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
}
public static Date asDate(LocalDateTime localDateTime) {
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
public static LocalDate asLocalDate(Date date) {
return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
}
public static LocalDateTime asLocalDateTime(Date date) {
return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
}
}
如何将一个大的list分片
public class BigList {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 10000000; i++) {
list.add(i);
}
long P = System.currentTimeMillis();
List<List<Integer>> subLists = getSubLists(list, 100000);
System.err.println(subLists.size());
long PP = System.currentTimeMillis();
long PPP = PP - P;
System.err.println(PPP);
}
public static List<List<Integer>> getSubLists(List<Integer> allData, int size) {
List<List<Integer>> result = new ArrayList();
for (int begin = 0; begin < allData.size(); begin = begin + size) {
int end = (begin + size > allData.size() ? allData.size() : begin + size);
result.add(allData.subList(begin, end));
}
return result;
}
排序 + 多字段排序 + 标志位
List<Student> stus = new ArrayList<Student>(){
{
add(new Student("张三", 30));
add(new Student("李四", 20));
add(new Student("王五", 60));
}
};
//对学生集合按年龄进行排序
Collections.sort(stus, (s1,s2)->(s1.getAge()-s2.getAge()));
List<Student> stus = new ArrayList<Student>(){
{
add(new Student("张三", 30, 1));
add(new Student("李四", 20, 2));
add(new Student("王五", 40, 3));
add(new Student("赵六", 30, 4));
add(new Student("陈七", 40, 5));
add(new Student("周八", 20, 6));
}
};
Collections.sort(stus,new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int flag;
// 首选按年龄升序排序
flag = s1.getAge()-s2.getAge();
if(flag==0){
// 再按学号升序排序
flag = s1.getNum()-s2.getNum();
}
return flag;
}
});
三范式与反三范式
表的设计要保持一种原子性
表与表之间要保持数据的完整性 有依赖也就是有外键 有外键增删改会变慢因为会检查外键
表字段的冗余
springBoot启动异常Consider defining a bean of type解决
Consider defining a bean of type ‘xxx’ in your configuration.
异常原因:未加@Component,导致未检测到
解决方法:往类上加上【@Component】注解
@MapperScan(“com.study.demo.mybatis.mapper”) 主要做了两件事情:
- 根据 “com.study.demo.mybatis.mapper” 配置进行mapper.java文件扫描.
此处扫描到的就是 SchoolMapper.java 和 UserMapper.java 两个文件 - 为扫描到的文件进行 BeanDefinition 注册 类似@Component
Maven 解决jar包冲突
maven导入jar包中的一些概念
直接依赖:项目中直接导入的jar包,就是该项目的直接依赖包
传递依赖:项目中没有直接导入的jar包,可以通过该项目直接依赖jar包传递到项目中取
解决jar包冲突的方式一
第一声明有限原则:哪个jar包的坐标在靠上的位置,这个jar包就是先声明的,先声明的jar包坐标下的依赖包,可以优先进入项目中
解决jar包冲突的方式二:
路径近者优先原则,直接依赖路径比传递依赖路径近,name最终项目进入的jar包会是路径近的
解决jar包冲突的方式三:
直接排除法
当我们要排除某个jar包下的依赖包,在配置exclusions标签的时候,内部可以不写版本号,因为此时依赖包使用的版本和默认和本地的jar包一直
spring事务失效场景
情况1:确认创建的mysql数据库表引擎是InnoDB,MyISAM不支持事务
情况2:注解到protected,private 方法上,事务不生效,它也不会报错,不过事务设置不会起作用。
情况3: 在业务层捕捉异常后未向上抛出,事务不生效。 原因:在业务层手工捕捉并处理了异常(try…catch)等于把异常“吃”掉了,Spring自然不知道这里有错, 更不会主动去回滚数据。推荐做法是在业务层统一抛出异常,然后在控制层统一处理。
情况4:遇到非检测异常时,事务不开启,也无法回滚。下方图片是异常体系 原因:因为Spring的默认的事务规则是遇到运行异常(RuntimeException)和程序错误(Error)才会回滚。如果 想针对非检测异常进行事务回滚,可以在@Transactional 注解里使用rollbackFor 属性明确指定异常。
情况5:不要写到接口上,spring 采用 aop 针对具体实现类做的代理实现。
情况6:Spring的事务传播策略在!!!(同一个类)内部方法调用时将不起作用,事务注解加到要调用方法上。
springcloud feign
代码解释2:如何正确的从延迟任务系统返回的ResponseMessage对象中获取任务对象Task ?
// ResponseMessage定义
@Data
public class ResponseMessage {
private boolean flag;
private Integer code;
private String message;
private Object data;
private String url;
}
//获取方式1:
Task task = (Task)responseMessage.getData();
如果这么获取会报如下错误:
java.lang.ClassCastException:java.util.LinkedHashMap cannot be cast to com.chongba.entity.Task
原因是feign帮我们在类型封装的时候把Object类型的封装成了LinkedHashMap,所以我们可以通过转成json字符串然后再反转成对象的方式来规避这个问题。
//获取方式2:
String task_json = JSON.toJSONString(responseMessage.getData());
Task task = JSON.parseObject(task_json, Task.class);
springcloud feign 多线程
主线程里创建子线程调用feign接口,通过header消息头带token信息方式,在子线程header里获取不到Authorization信息,以至于子线程用户校验出现问题。以下代码块放到feignconfig文件里可以解决子线程继承主线程的header信息以避免该问题。
@Autowired
RequestContextFilter requestContextFilter;
@Autowired
DispatcherServlet dispatcherServlet;
@PostConstruct
public void init() {
// 设置线程继承属性为true,便于子线程获取到父线程的request,两个都设置为了保险。
requestContextFilter.setThreadContextInheritable(true);
dispatcherServlet.setThreadContextInheritable(true);
}
使用 lombok 注解没有达到预期该怎么办
一款PO VO DTO转换神器 mapstruct
Java获取List中重复的元素
public <E> List<E> getDuplicateElements(List<E> list) {
return list.stream()
.collect(Collectors.toMap(e -> e, e -> 1, (a, b) -> a + b))
.entrySet().stream()
.filter(entry -> entry.getValue() > 1)
.map(entry -> entry.getKey())
.collect(Collectors.toList());
}
Java8 Collectors.toMap的坑
按照常规思维,往一个map里put一个已经存在的key,会把原有的key对应的value值覆盖,然而通过一次线上问题,发现Java8中的Collectors.toMap反其道而行之,它默认给抛异常,抛异常…
线上业务代码出现Duplicate Key的异常,影响了业务逻辑,查看抛出异常部分的代码,类似以下写法:
Map<Integer, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName));
然后list里面有id相同的对象,结果转map的时候居然直接抛异常了。。查源码发现toMap方法默认使用了个throwingMerger
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}
private static <T> BinaryOperator<T> throwingMerger() {
return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
}
如果不想抛异常的话,自己传进去一个方法即可,上述代码可以改成:
Map<Integer, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName,(oldValue, newValue) -> newValue));