- BeanUtils.copyProperties(packedDTOS.get(0), docContent)
Bean拷贝实体类的属性可以避免很多赋值,但是注意在dest元素有值的时候,不要覆盖。 - likeBOs != null && !likeBOs.isEmpty() 。List判空缩写
等价于 !CollectionUtils.isEmpty(likeBOs)。Strings.isBlank()类似。 - 常识: 空指针异常在很多语言中,都是运行时异常,注意判空。要不后面测试或者上线的时候就是灾难。
在哪一层判空,在Controller中判空这是普遍要做的,但是Service里面传的参数要不要第二次判空,取决于别人调用你这个方法多吗。[有很多时候同事直接调用你写的方法并传不合法值,注意健壮性] - 返回List的方法 不要返回空而要返回空集合。
如果性能要求高返回Collections.emptyList(),否则new ArrayList()。
Collections.emptyList()这个方法返回一个空集合,并不会新建对象,而是返回public static final List EMPTY_LIST = new EmptyList<>(); . - 判断两个值相等。Objects.equals
Integer a= 1;
Long b= 1L;
System.out.println(150000==150000L);
System.out.println(a.equals(b));
- List item
map返回默认值。
getOrDefault。程序里面要尽可能避免返回空值。
- 前端Long类型会截断。15位以上都会截断。
- lombok是真的好用, 实体类里面可以定义静态类,对于只用转换一次的实体类,不需要在定义出来。
@Data
@Accessors(chain = true) // 填充属性方便
@Builder
public class DocContentVO {
@JsonProperty("id")
private Integer id;
@JsonProperty("comment_list")
private List<Comment> commentList;
@JsonProperty("comment_count")
private Integer commentCount;
@JsonProperty("action")
private ActionDTO action;
@Data
public static class ActionDTO {
@JsonProperty("path")
private String path;
@JsonProperty("action")
private String action;
@JsonProperty("parameters")
private ParametersDTO parameters;
@JsonProperty("options")
private Boolean options;
@Data
public static class ParametersDTO {
@JsonProperty("collection_id")
private String collectionId;
@JsonProperty("docid")
private String docid;
}
}
}
- 调用其他系统的地方,跟其他系统、或者数据库交互的地方记得添加日志并捕获异常。请求的地址,入参,出参。
- 只有一个元素想变成一个集合。
Collections.singletonList(docId) - 将List通过stream转化为Map的时候注意过滤。Key值相同的时候,选择第一个。
Map<String, Doc> docsMap = docService.getByDocidList(unCachedDocIds).stream()
.collect(Collectors.toMap(Doc::getDocid, Function.identity(), (k1, k2) -> k1));
- stream错误示范
filter执行了三遍。map或者filter里面不要有过于复杂的逻辑,会导致debug困难。写起来一时爽,排查起来很麻烦。复杂的逻辑可以封装一个方法在map里面调用方法。
Map<String, DocDetail> uncachedDts = details.stream()
.filter(dt -> !dt.getRemoved())
.filter(dt -> !((dt.getRemovedImages() != null) && !dt.getRemovedImages().isEmpty()))
.filter(dt -> !(dt.getImgScoresJson() == null || dt.getImgScoresJson().isEmpty()))
.map(docDetail -> dts.put(docDetail.getId(), docDetail))
.filter(Objects::nonNull)
.collect(Collectors.toMap(DocDetail::getId, a->a));
//正确de:
Map<String, DocDetail> uncachedDts = details.stream()
.filter(dt -> !dt.getRemoved()||
(!((dt.getRemovedImages() != null) && !dt.getRemovedImages().isEmpty()))||
!(dt.getImgScoresJson() == null || dt.getImgScoresJson().isEmpty()))
.map(docDetail -> dts.put(docDetail.getId(), docDetail))
.filter(Objects::nonNull)
.collect(Collectors.toMap(DocDetail::getId, a->a));
- 常量Map生成。
public static final Map<Integer, List<Integer>> AUDIT_STAGE_MAP
= ImmutableMap.<Integer, List<Integer>>builder()
.put(1, Arrays.asList(1, 2, 8))
.put(2, Arrays.asList(4, 5, 9))
.build();
- 求两个Collection的并、交集。
CollUtil.intersection(stagesList, statesList)
- 常用Lombok注解
@Slf4j
@Data
@Accessors(chain = true)
@Builder
- 时间格式化输出json
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonProperty("create_time")
- 参数校验与全局异常 todo
@GetMapping("/GetDocDetail")
public Response<DocContentVO> getDocDetail(
@RequestParam("doc_id")@Pattern(regexp = "^[VT]_.*$",message = "doc_id参数不合法") String docId,
@RequestParam("userid")@NotNull(message = "userid参数为空") Long userid) {
Assert.notEmpty(docInfoList, String.format("docid: %s 文章不存在", docId));
- 全局jackson序列化配置过滤空字段为默认字段 todo
- 调用第三方接口,怎么接合适。。后续再补充 todo
- 包装类型判断
注意可能出现空指针
if (Boolean.FALSE.equals(userWrapper.getIsFriend(docInfo.getUserid(), curUserId))) {
- jackson序列化时,boolean基本类型默认是 isXXX,vo对象中最好用包装类型对象。但是包装类型可能为null,输出的时候想法输出默认值。
- jackson序列化时实体类输出为默认值,或者过滤
解决方案:
objectMapper
webConfig