java及周边技术栈代码常用片段记录

文章介绍了Java中的事务管理、流(Stream)操作、数据映射、树结构组装、Collections工具使用、EasyExcel表头校验以及处理null值的方法,展示了在实际开发中处理数据处理和Excel导入的技巧。
摘要由CSDN通过智能技术生成

1.提交事务再执行其他方法。

使用场景:有时候事务比较大,当前事务允许先提交的情况下再执行后续动作,那么就可以使用此方式进行处理

@Transactional
public void add() {
    //插入数据逻辑
	TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
	        @Override
	        public void afterCommit() {
	           //发送消息
	        }
	});
   
}

2.stream使用

Map<Long, List<Brand>> collect = brandService.listByIds(brandIdList).stream().collect(Collectors.groupingBy(Brand::getId));

#将list的实体的某字段用英文逗号拼接
 String systemChineseName = systemList.stream().map(SystemListVO::getfChineseName).collect(Collectors.joining(","));


list转map
 写法1:
 Map<Long, Supplier> supplierMap = supplierService.listByIds(new ArrayList<>(supplierIdSet)).stream().collect(Collectors.toMap(Supplier::getId, a -> a, (k1, k2) -> k1));
 写法2:
 Map<String, Product> productMap = productList.stream().collect(Collectors.toMap(Product::getSku, v -> v));
 Map<String, MultiDimensionalAvailableInventoryResponse> collect = inventoryResponses.stream().collect(Collectors.toMap(x -> x.getSku() + "_" + x.getWhId(), v -> v));


取出某个字段作为list
//1.提取出list对象中的一个属性
List<String> stIdList1 = stuList.stream().map(Student::getId).collect(Collectors.toList());

分组
Map<String, List<PurchaseDetailVO>> purchaseMaps = purchaseAndDetailByNo.getData().stream().collect(Collectors.groupingBy(p -> p.getSku() + StrUtil.DASHED + p.getSkuType()));
Map<String, Product> productMap = RemoteObjectMapper.getProductRst(remoteProductService, details.stream().map(InboundDetail::getSku).collect(Collectors.toSet()).stream().collect(Collectors.toList()));
        
List<SupplierContacts>supplierContacts = ConvertUtils.convertList(processProductListTemp, OutSourceProcessAndDetailResponse.ProcessProduct.class);

求和:
list.stream().map(Tea::getSalory).filter(ObjectUtil::isNotNull).reduce(BigDecimal.ZERO, BigDecimal::add);


汇总数量返回
Map<String, IntSummaryStatistics> skuQtyMap = outboundQtyVOS.stream().collect(Collectors.groupingBy(ProcessOutboundQtyVO::getSku,
                Collectors.summarizingInt(ProcessOutboundQtyVO::getOutboundQty)));
设置显示百分比
NumberFormat format = NumberFormat.getPercentInstance();
        format.setMaximumFractionDigits(2);
// 设置百分比字符串
                detailVO.setDiscountRateStr(format.format(detailVOItem.getDiscountRate()));


比较:(按照部门ID倒序,StoryAnalysisListVO::getDepartmentId为null时,报NPE异常)
voList=voList.stream().sorted(Comparator.comparing(StoryAnalysisListVO::getDepartmentId).reversed()).collect(Collectors.toList());

2.1 注意事项

2.1.1 Collectors.toMap的value如果为null,会报异常,使用时需要注意

2.2 list按实体某个字段去重

import java.util.*;
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        List<Employee> employees = Arrays.asList(
            new Employee("001"),
            new Employee("002"),
            new Employee("001"),
            new Employee("003"),
            new Employee("002")
        );

        // 使用Stream API去除employeeNumber重复的实体
        List<Employee> uniqueEmployees = employees.stream()
            .collect(Collectors.groupingBy(Employee::getEmployeeNumber,
                    Collectors.collectingAndThen(Collectors.toList(),
                            list -> list.stream().findFirst().orElse(null))))
            .values()
            .stream()
            .filter(Objects::nonNull)
            .collect(Collectors.toList());

        System.out.println("Unique Employees: " + uniqueEmployees);
    }

    static class Employee {
        private String employeeNumber;

        public Employee(String employeeNumber) {
            this.employeeNumber = employeeNumber;
        }

        public String getEmployeeNumber() {
            return employeeNumber;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Employee employee = (Employee) o;
            return Objects.equals(employeeNumber, employee.employeeNumber);
        }

        @Override
        public int hashCode() {
            return Objects.hash(employeeNumber);
        }

        @Override
        public String toString() {
            return "Employee{" +
                    "employeeNumber='" + employeeNumber + '\'' +
                    '}';
        }
    }
}

2.3 list按某个字段统计出现次数

 Map<String, Long> duplicateMap = list.stream().collect(Collectors.groupingBy(FbpEmployee::getEmployeeNumber, Collectors.counting())).entrySet().
                stream().filter(e -> e.getValue() > 1).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

        if (duplicateMap != null && duplicateMap.size() > 0) {
            log.error("UIC员工信息同步,有重复数据,请检查UIC数据,重复数据有:{}条,入参:{}", duplicateMap.size(), JSONUtil.toJsonStr(duplicateMap));
            return;
        }

3.java工具类Collections使用

3.1 比较

正序:

Collections.sort(userDTOS, Comparator.comparing(UserDTO::getAge));

倒叙:

Collections.sort(userDTOS, Comparator.comparing(UserDTO::getAge).reversed());

需要注意的是,如果UserDTO::getAge结果为null,会抛空指针异常。所以比较的时候看实际情况,null给默认值或者过滤出非null的进行比较。

4.树结构组装

树结构实体

//树结构类demo
@Data
@ApiModel(value = "DeptInfo对象", description = "部门信息表")
public class DeptInfoVo {
    /**
     * 主键id
     */
    private Long id;

    @ApiModelProperty("部门名称")
    private String deptName;

    @ApiModelProperty("部门ID")
    private String deptId;

    @ApiModelProperty("父级部门ID")
    private String parentId;

    @ApiModelProperty("子节点")
    private List<DeptInfoVo> children = new ArrayList<>();

}

4.1 不指定父节点构建树结构-返回list结构


/**
     * 构建树结构(找不到父id则放在根节点)
     * @param nodeList
     * @return
     */
private List<DeptInfoVo> buildTree(List<DeptInfoVo> nodeList) {
        // 创建一个Map来存储每个节点,键为部门ID,值为节点对象
        Map<String, DeptInfoVo> nodeMap = new HashMap<>();
        for (DeptInfoVo node : nodeList) {
            nodeMap.put(node.getDeptId(), node);
        }
        // 初始化一个根节点集合
        List<DeptInfoVo> roots = new ArrayList<>();
        // 遍历节点列表,构建树结构
        for (DeptInfoVo node : nodeList) {
            String parentId = node.getParentId();
            if(ObjectUtil.isNull(nodeMap.get(parentId))){
                // 如果当前节点的pId不存在,则把它当做根节点
                roots.add(node);
            }else {
                DeptInfoVo parentNode = nodeMap.get(parentId);
                if (parentNode != null) {
                    // 若父节点存在,则将当前节点添加到其子节点列表中
                    parentNode.getChildren().add(node);
                }
            }
        }
        return roots;
    }

4.2 指定父节点(返回指定父节点)

/**
     * 组装树结构
     *
     * @param dtoList 所有数据
     * @param pid     父主键
     * @return 树形结构
     */
    private DeptInfoVo buildTree(List<DeptInfoVo> dtoList, String pid) {

        //先选出非顶级的节点
        List<DeptInfoVo> list = dtoList.parallelStream().filter(item -> (!StrUtil.equals(item.getParentId(),pid))).collect(Collectors.toList());

        //将这些非顶级节点的数据按pid进行分组
        Map<String, List<DeptInfoVo>> sub = list.parallelStream().collect(Collectors.groupingBy(DeptInfoVo::getParentId));

        //循环设置对应的子节点(根据id = pid)
        dtoList.parallelStream().forEach(node -> node.setChildren(sub.get(node.getDeptId())));

        //过滤掉父节点数据
        DeptInfoVo deptInfoVo = dtoList.parallelStream().filter(node -> StrUtil.equals(node.getParentId(), pid))
                .collect(Collectors.toList()).stream().findFirst().orElse(new DeptInfoVo());

        return deptInfoVo;
    }

5.easyExcel校验表头

5.1 前提准备

(1)使用@ExcelProperty注解配置模板表头字段
(2)创建监听类并继承AnalysisEventListener类,重写invokeHeadMap方法,在该方法中判断是否符合模板




import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.math.BigDecimal;

/**
 * KPI导入
 *
 *
 */
@Data
@ColumnWidth(20)
public class OrgKpiImportVo {

    @ApiModelProperty("年度*")
    @ExcelProperty(index = 0, value = {"年度*"})
    private Integer yearly;

    @ApiModelProperty("ID")
    @ExcelIgnore
    private Long id;

    @ApiModelProperty("上级ID")
    @ExcelIgnore
    private Long pId;

    @ApiModelProperty("上级编号")
    @ExcelProperty(index = 1, value = {"上级编号"})
    private String pCode;

    @ApiModelProperty("上级考核指标")
    @ExcelProperty(index = 2, value = {"上级考核指标"})
    private String pName;

    @ApiModelProperty("编号*")
    @ExcelProperty(index = 3, value = {"编号*"})
    private String code;

    @ApiModelProperty("考核指标*")
    @ExcelProperty(index = 4, value = {"考核指标*"})
    private String name;

    @ApiModelProperty("集团战略权重")
    @ExcelProperty(index = 5, value = {"集团战略权重%"})
    private BigDecimal groupWeight;

    @ApiModelProperty("DC权重")
    @ExcelProperty(index = 6, value = {"DC权重%"})
    private BigDecimal weight;

    @ApiModelProperty("部门权重*")
    @ExcelProperty(index = 7, value = {"部门权重% *"})
    private BigDecimal deptWeight;

    @ApiModelProperty("指标定义*")
    @ExcelProperty(index = 8, value = {"指标定义*"})
    private String definition;

    @ApiModelProperty("部门ID*")
    @ExcelProperty(index = 9, value = {"部门ID*"})
    private String deptCode;

    @ApiModelProperty("部门名称")
    @ExcelProperty(index = 10, value = {"部门名称"})
    private String deptName;

    @ApiModelProperty("负责人工号*")
    @ExcelProperty(index = 11, value = {"负责人工号*"})
    private String chargePerson;

    @ApiModelProperty("负责人")
    @ExcelProperty(index = 12, value = {"负责人"})
    private String chargePersonName;

    @ApiModelProperty("代理人工号")
    @ExcelProperty(index = 13, value = {"代理人工号"})
    private String followBy;

    @ApiModelProperty("代理人")
    @ExcelProperty(index = 14, value = {"代理人"})
    private String followByName;

    @ApiModelProperty("认定/审定/数据来源部门")
    @ExcelProperty(index = 15, value = {"认定/审定/数据来源部门"})
    private String sources;

    @ApiModelProperty("计量单位*")
    @ExcelProperty(index = 16, value = {"计量单位*"})
    private String unit;

    @ApiModelProperty("评分制度*")
    @ExcelProperty(index = 17, value = {"评分制度*"})
    private String scoreSystem;

    @ApiModelProperty("保底值*")
    @ExcelProperty(index = 18, value = {"保底值*"})
    private BigDecimal minimumValue;

    @ApiModelProperty("目标值*")
    @ExcelProperty(index = 19, value = {"目标值*"})
    private BigDecimal targetValue;

    @ApiModelProperty("挑战值*")
    @ExcelProperty(index = 20, value = {"挑战值*"})
    private BigDecimal challengeValue;

    @ApiModelProperty("指标性质*")
    @ExcelProperty(index = 21, value = {"指标性质*"})
    private String indicatorPropertyName;

    @ApiModelProperty("指标性质")
    @ExcelIgnore
    private String indicatorProperty;

    @ApiModelProperty("创建人姓名")
    @ExcelIgnore
    private String createByName;

    @ApiModelProperty("创建人")
    @ExcelIgnore
    protected String createBy;


}

5.2 表头校验判断

/**
     * 在这里进行模板的判断
     * @param headMap 存放着导入表格的表头,键是索引,值是名称
     * @param context
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
         /*
        count 记录模板表头有几个,用以判断用户导入的表格是否和模板完全一致
        如果用户导入表格较模板的表头多,但其余符合模板,这样不影响则不需要
         */
        int count = 0;
        // 获取数据实体的字段列表
        Field[] fields = OrgKpiImportVo.class.getDeclaredFields();
        // 遍历字段进行判断
        for (Field field : fields) {
            // 获取当前字段上的ExcelProperty注解信息
            ExcelProperty fieldAnnotation = field.getAnnotation(ExcelProperty.class);
            // 判断当前字段上是否存在ExcelProperty注解
            if (fieldAnnotation != null) {
                ++count;
                // 存在ExcelProperty注解则根据注解的index索引到表头中获取对应的表头名
                String headName = headMap.get(fieldAnnotation.index());
                // 判断表头是否为空或是否和当前字段设置的表头名不相同
                if (StringUtils.isEmpty(headName) || !headName.equals(fieldAnnotation.value()[0])) {
                    // 如果为空或不相同,则抛出异常不再往下执行
                    throw new RuntimeException("模板错误,请检查导入模板");
                }
            }
        }

        // 判断用户导入表格的标题头是否完全符合模板
        if (count != headMap.size()) {
            throw new RuntimeException("请使用正确的导入模板!");
        }

    }

6. excel列索引取对应字母

// 自定义方法将列索引转换为列字母表示
    public static String convertToColumnLetter(int columnIndex) {
        StringBuilder columnLetter = new StringBuilder();
        while (columnIndex > 0) {
            int remainder = (columnIndex - 1) % 26;
            columnLetter.append((char) ('A' + remainder));
            columnIndex = (columnIndex - 1) / 26;
        }
        return columnLetter.reverse().toString();
    }

7. 控制台日志打印

例如mybatis-plus、tkMybatis或者mongodb的日志打印,配置

#mybatis-plus日志打印
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

#这是关键,打印查询语句就靠这个配置
logging.level.org.springframework.data.mongodb.core=DEBUG

#tkMybatis
#打印sql,logging.level后面是dao的包路径
logging.level.com.xxx.mapper.xx=debug
 

8.Mybatis使用

8.1 mybatis中的if标签的等号使用

mybatis映射文件,是使用的ognl表达式,所以在判断字符串变量是否相等时,有两种方式。
方式1:

<if test="sex=='Y'.toString()">

方式2:
<if test = 'sex== "Y"'>

不能使用:
<if test="sex=='Y'">
and 1=1
</if>
因为mybatis会把'Y'解析为字符char类型,而不是String类型,不能做到判断的效果,java是强类型语言,所以不能这样写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值