Java调用LinkedList的size()报cannot find symbol错误排查
问题排查:Java调用List的size()方法提示cannot find symbol编译错误
错误根因
代码中使用了无泛型声明的原始类型HashMap,编译器默认从原始类型HashMap中取出的value是Object类型,而Object类没有定义size()、get()方法,因此触发编译错误。
具体出错位置
你在三个位置使用了未指定泛型的原始HashMap声明:
cloneGraph方法中:HashMap adjList = MakeAdjList(node);未声明键值对的具体类型MakeAdjList方法的返回值:public HashMap MakeAdjList(Node node)未指定返回Map的泛型参数reconstruct方法的入参:public Node reconstruct(HashMap adjList)入参未指定泛型参数
即使你在MakeAdjList内部实际创建的是HashMap<Integer, List<Integer>>类型,只要方法签名、变量声明用的是原始类型,编译器就不会自动推断内部存储的value类型,只会按Object处理。
额外逻辑bug
除了编译错误,你的代码还有三处运行时逻辑问题:
- 边界判断错误:当输入是单个无邻居的节点时,
node.neighbors.isEmpty()为true,你直接返回null,正确逻辑应该返回该节点的克隆体 - 重建图时索引错误:填充邻居列表时你写的是
nodes[i].neighbors.add(...),这里i是邻居列表的循环下标,应该给当前遍历到的节点nodes[j]添加邻居,否则会出现数组越界、邻居挂载错误的问题 - 节点数组初始化循环越界:
for(int i = 1; i<nodes.length+1; i++)数组最大下标是nodes.length-1,循环条件写i<nodes.length即可
修复后完整代码
class Solution { public Node cloneGraph(Node node) { if(node == null){ return null; } // 补全泛型声明 HashMap<Integer, List<Integer>> adjList = MakeAdjList(node); return reconstruct(adjList); } // 补全返回值泛型 public HashMap<Integer, List<Integer>> MakeAdjList(Node node){ HashMap<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>(); HashSet<Integer> visited = new HashSet<Integer>(); LinkedList<Node> q = new LinkedList<Node>(); q.offer(node); while(!q.isEmpty()){ Node currentNode = q.poll(); visited.add(currentNode.val); map.put(currentNode.val, new LinkedList<Integer>()); for(Node neighbor : currentNode.neighbors){ if(!visited.contains(neighbor.val)){ q.offer(neighbor); visited.add(neighbor.val); } map.get(currentNode.val).add(neighbor.val); } } return map; } // 补全入参泛型 public Node reconstruct(HashMap<Integer, List<Integer>> adjList){ Node[] nodes = new Node[adjList.size() + 1]; // 修正循环边界 for(int i = 1; i<nodes.length; i++){ nodes[i] = new Node(i); } for(int j = 1; j< nodes.length; j++){ int l = adjList.get(j).size(); for(int i = 0; i< l; i++){ int neighborVal = adjList.get(j).get(i); // 修正挂载邻居的节点索引 nodes[j].neighbors.add(nodes[neighborVal]); } } return nodes[1]; } }
注:Java泛型仅在编译期生效,使用原始类型会丢失泛型类型检查,所有Java业务代码、算法代码中都应该避免使用原始类型集合,声明集合时必须明确指定泛型参数。
内容的提问来源于stack exchange,提问作者user19327144
相关产品推荐
相关产品推荐

