Long类型的get/set 方法判断空的时候是指空指针异常

文章讨论了在Java实体类中,使用lambda的@Data注解定义Long类型id时,如果不显式赋值可能导致空指针异常。原因是get方法返回的是long而非包装类Long,解决办法是明确使用Long类型并修改相关方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当我们在实体类中定义了一个Long类型的id 并使用lambda的@Data注解

当不赋值为该id 并进行判断是否为null或者空的时候直接空指针异常

造成这个原因是因为这个自动生成的get方法返回的类型是long而不是包装类Long

class usertemp{
    public long getId() {
        return this.id;
    }

    public void setId(long id) {
        this.id = id;
    }

    Long id;
}

就会导致 usertemp.getId()空指针 因为是把null 赋值给了long类型导致的 需要自己修改

class usertemp{
    public Long getId() {
        return this.id;
    }

    public void setId(long id) {
        this.id = id;
    }

    Long id;


}
<think>好的,我现在需要帮用户写一个Java的递归方法,根据给定的实体类结构生成树形结构。首先,我得仔细看一下用户提供的类字段,理解每个属性的作用。 用户提供的类中有id、warehouseId、parentId、children等字段,特别是parentId和children,这表明这是一个典型的树形结构数据模型。递归方法通常用于处理这种父子层级关系的数据,比如构建树或者遍历树。 接下来,我需要确定递归方法的输入和输出。用户希望将平面的列表转换成树形结构,所以输入应该是一个包含所有节点的列表,输出则是根节点列表,每个根节点下包含其子节点。 首先,递归方法的大致思路是:找到所有父节点为当前节点id的子节点,然后将这些子节点添加到当前节点的children列表中,并对每个子节点递归调用该方法,继续查找它们的子节点。这样逐层构建起整个树。 需要注意的是,递归的终止条件是什么。当某个节点没有子节点时,递归就会自然停止,因为不会再进入下一层循环。 然后,我需要考虑如何高效地查找子节点。如果每次递归都遍历整个列表来查找子节点,时间复杂度可能会很高,尤其是数据量大时。因此,可能需要对列表进行一次预处理,比如使用一个Map来根据parentId分组,这样在查找子节点时可以直接从Map中获取,提高效率。 不过用户可能希望直接提供一个简单易懂的递归方法,可能暂时不考虑优化。那我可以先写出基础版本,再考虑是否需要优化。 接下来,编写方法的结构。方法应该接收一个当前节点的id和一个所有节点的列表,返回该节点的子节点列表。在方法内部,遍历所有节点,找到parentId等于当前id的节点,然后递归调用该方法为每个子节点设置children。 不过用户可能需要的是一个入口方法,比如从一个列表中构建整个树,这时候需要先找到所有根节点(parentId为null或0或其他特定值),然后为每个根节点递归构建子树。 用户提供的类中parentId是Long类型,可能根节点的parentId为null或者0,需要确认。假设根节点的parentId为null或者0,比如parentId为0时表示没有父节点。但根据字段注释,“父级区域编码”是Long类型,可能根节点的parentId为null或者特定的值,比如0。需要用户确认,但用户没有说明,可能需要假设根节点的parentId为null或者0。 假设根节点的parentId为null或者0,那么在构建树时,首先筛选出这些根节点,然后对每个根节点递归查找子节点。 现在,具体到代码: 1. 编写一个方法,接受一个节点列表,返回构建好的树形结构。 2. 找到所有根节点(parentId为null或特定值)。 3. 对每个根节点,递归查找其子节点。 可能的代码结构如下: public static List<WarehouseAreaVo> buildTree(List<WarehouseAreaVo> list) { List<WarehouseAreaVo> roots = new ArrayList<>(); for (WarehouseAreaVo node : list) { if (node.getParentId() == null || node.getParentId() == 0L) { // 假设根节点的parentId为null或0 roots.add(node); findChildren(node, list); } } return roots; } private static void findChildren(WarehouseAreaVo parent, List<WarehouseAreaVo> list) { List<WarehouseAreaVo> children = new ArrayList<>(); for (WarehouseAreaVo node : list) { if (node.getParentId() != null && node.getParentId().equals(parent.getId())) { children.add(node); findChildren(node, list); } } parent.setChildren(children); } 不过,这样的方法在每次递归时都会遍历整个列表,效率可能不高。对于数据量大的情况,可以考虑先将列表按parentId分组,存储到Map中,这样查找子节点时只需要从Map中取,不需要遍历整个列表。 优化后的版本: public static List<WarehouseAreaVo> buildTree(List<WarehouseAreaVo> list) { // 按parentId分组 Map<Long, List<WarehouseAreaVo>> parentIdMap = list.stream() .filter(node -> node.getParentId() != null) .collect(Collectors.groupingBy(WarehouseAreaVo::getParentId)); // 找到根节点 List<WarehouseAreaVo> roots = list.stream() .filter(node -> node.getParentId() == null || node.getParentId() == 0L) .collect(Collectors.toList()); // 递归构建树 for (WarehouseAreaVo root : roots) { populateChildren(root, parentIdMap); } return roots; } private static void populateChildren(WarehouseAreaVo parent, Map<Long, List<WarehouseAreaVo>> parentIdMap) { List<WarehouseAreaVo> children = parentIdMap.get(parent.getId()); if (children != null) { parent.setChildren(children); for (WarehouseAreaVo child : children) { populateChildren(child, parentIdMap); } } } 这样利用Map来存储每个parentId对应的子节点列表,减少遍历次数,提高效率。但用户可能只需要一个基础的递归方法,所以可能需要提供一个简单版本和一个优化版本。 不过用户要求的是递归方法,可能更倾向于基础的实现。但考虑到效率,使用Map分组会更优,因此可能在回答中提供两种方法,并解释优缺点。 另外,需要注意字段的正确性,比如parentId的类型是否为Long,是否有可能是null。在比较时,使用equals而不是==,因为Long是对象。比如,在基础的findChildren方法中,判断node.getParentId().equals(parent.getId())。 此外,在Java中,如果parentId可能为null,需要先检查是否为null,否则调用equals会导致空指针异常。例如,在基础版本中: if (node.getParentId() != null && node.getParentId().equals(parent.getId())) { 这样确保node.getParentId()不为null时才进行比较。 总结,用户需要的是一个递归构建树的方法,输入是列表,输出是树形结构的根节点列表。需要处理父子关系,递归查找子节点,并设置到children属性中。</think>以下是为您编写的Java递归方法实现,用于构建树形结构: ```java /** * 构建树形结构(入口方法) * @param list 平面结构数据列表 * @return 树形结构数据 */ public static List<WarehouseAreaVo> buildTree(List<WarehouseAreaVo> list) { // 创建结果集合和临时映射表 List<WarehouseAreaVo> result = new ArrayList<>(); Map<Long, WarehouseAreaVo> nodeMap = new HashMap<>(); // 第一次遍历:填充映射表 for (WarehouseAreaVo node : list) { nodeMap.put(node.getId(), node); node.setChildren(new ArrayList<>()); // 初始化子节点列表 } // 第二次遍历:构建树形结构 for (WarehouseAreaVo node : list) { Long parentId = node.getParentId(); if (parentId == null || parentId == 0L) { // 根节点条件 result.add(node); } else { // 子节点处理 WarehouseAreaVo parent = nodeMap.get(parentId); if (parent != null) { parent.getChildren().add(node); } } } // 按sortNo排序(可选) sortTree(result); return result; } /** * 递归排序树节点(按sortNo字段) */ private static void sortTree(List<WarehouseAreaVo> nodes) { if (nodes == null) return; nodes.sort(Comparator.comparingInt(WarehouseAreaVo::getSortNo)); for (WarehouseAreaVo node : nodes) { sortTree(node.getChildren()); } } ``` 方法特点说明: 1. **双遍历优化**(时间复杂度$O(n)$) - 第一次遍历使用HashMap存储所有节点,通过$O(1)$时间复杂度快速查找父节点 - 第二次遍历通过映射表直接建立父子关系 2. **递归排序实现** - 使用尾递归对每个层级的子节点按sortNo排序 - 排序后可以保持树形结构的顺序一致性 3. **树形结构特征处理** - 根节点条件:`parentId == null || parentId == 0L` - 自动初始化children列表,避免空指针异常 - 支持无限层级递归嵌套 使用示例: ```java List<WarehouseAreaVo> flatList = getFromDatabase(); // 获取平面数据 List<WarehouseAreaVo> tree = buildTree(flatList); // 构建树形结构 ``` 注意事项: 1. 确保`parentId`字段与`id`字段类型严格匹配(Long类型) 2. 若需要处理循环依赖,可增加环路检测逻辑 3. 根节点判断条件可根据实际情况调整(如parentId=0改为parentId=null)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值