Java课程作业疑问:HashMap存储用户输入数据的原理及实现
嘿,我来帮你理清HashMap的工作机制,顺便结合你的Java作业场景说说怎么用它来存储用户输入的信息~
针对你的Java作业:用HashMap存储用户输入的节点信息
先搞懂HashMap的核心工作机制
HashMap是Java里非常常用的键值对存储容器,核心逻辑可以拆解成这几点:
- 键值对存储逻辑:它以
Key-Value的形式存数据,比如你可以用节点名称(nodeName)作为Key,把包含所有节点信息的对象作为Value。 - 哈希定位原理:存入数据时,会先调用Key的
hashCode()方法生成哈希值,再通过内部算法算出数据在数组里的存储位置,所以查询、插入的效率通常很高(理想情况O(1))。 - 冲突处理:如果两个不同的Key算出了相同的存储位置(哈希冲突),HashMap会在这个位置用链表(JDK8后链表长度超过8会转红黑树)来存多个数据,查询时会用
equals()方法匹配正确的Key。 - 扩容机制:当存储的元素数量超过「负载因子(默认0.75)×数组容量」时,数组会扩容成原来的2倍,重新计算所有数据的存储位置,避免链表太长导致效率下降。
结合你的作业场景优化代码
从你给出的代码片段来看,你需要存储用户输入的节点详细信息,最合理的做法是先把这些信息封装成一个实体类,再用HashMap来管理。这里给你一套可参考的实现:
1. 定义节点信息实体类
先把typeMessage、nodeName、ip这些字段封装成一个NodeDetail类,方便统一管理:
public class NodeDetail { private String typeMessage; private String nodeName; private String ip; private int nPort; private int rCapacity; private String resources; // 构造方法,用于初始化节点信息 public NodeDetail(String typeMessage, String nodeName, String ip, int nPort, int rCapacity, String resources) { this.typeMessage = typeMessage; this.nodeName = nodeName; this.ip = ip; this.nPort = nPort; this.rCapacity = rCapacity; this.resources = resources; } // 生成Getter方法,方便获取各个属性 public String getTypeMessage() { return typeMessage; } public String getNodeName() { return nodeName; } public String getIp() { return ip; } public int getnPort() { return nPort; } public int getrCapacity() { return rCapacity; } public String getResources() { return resources; } // 重写toString(),打印时能直接看到节点的详细信息 @Override public String toString() { return "节点信息:" + "类型='" + typeMessage + '\'' + ", 名称='" + nodeName + '\'' + ", IP='" + ip + '\'' + ", 端口=" + nPort + ", 容量=" + rCapacity + ", 资源='" + resources + '\''; } }
2. 修改SortNodeDetails类,用HashMap存储
把原来的类改成用HashMap来管理节点信息,同时保留你需要的排序、打印功能:
import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; public class SortNodeDetails { // 用HashMap存储节点,Key选nodeName(假设每个节点名称唯一) private Map<String, NodeDetail> nodeMap = new HashMap<>(); public static boolean ASC = true; // 添加节点信息的方法 public void AddNodeDetails(String typeMessage, String nodeName, String ip, int nPort, int rCapacity, String resources) { NodeDetail newNode = new NodeDetail(typeMessage, nodeName, ip, nPort, rCapacity, resources); // 存入HashMap,如果nodeName重复会覆盖旧节点,你可以根据需求加判断提示 nodeMap.put(nodeName, newNode); } // 打印未排序的节点信息 public void printUnsorted() { System.out.println("未排序的节点信息:"); nodeMap.values().forEach(System.out::println); } // 打印排序后的节点信息(按nodeName排序,ASC控制升序/降序) public void printSorted() { System.out.println(ASC ? "升序排序的节点信息:" : "降序排序的节点信息:"); nodeMap.entrySet() .stream() .sorted((entry1, entry2) -> ASC ? entry1.getKey().compareTo(entry2.getKey()) : entry2.getKey().compareTo(entry1.getKey())) .map(Map.Entry::getValue) .forEach(System.out::println); } }
3. 主程序调用示例
你的主程序调用逻辑基本不用改,还可以新增排序打印的调用:
public class Main { public static void main(String[] args) { SortNodeDetails sort = new SortNodeDetails(); // 模拟用户输入的节点信息 sort.AddNodeDetails("Server", "NodeB", "192.168.0.2", 8081, 200, "Memory"); sort.AddNodeDetails("Client", "NodeA", "192.168.0.1", 8080, 100, "CPU"); sort.printUnsorted(); // 切换降序再打印 SortNodeDetails.ASC = false; sort.printSorted(); } }
额外提示
- 如果你的nodeName可能重复,在AddNodeDetails方法里可以先判断
nodeMap.containsKey(nodeName),如果存在就提示用户,避免覆盖旧数据。 - 如果需要保持插入顺序,可以把HashMap换成
LinkedHashMap,它会记住元素的插入顺序。 - 如果需要默认就按Key排序,直接用
TreeMap代替HashMap,它会自动按Key的自然顺序排序。
内容的提问来源于stack exchange,提问作者LOSQ
相关产品推荐
相关产品推荐

