谈谈static

对于static你到底理解了多少

               曾今我对static非常难以理解,因为我有一个同事把所有的的类方法都加了static,上层调用只需直接类名加方法名就OK了,如果有幸看到这文章,你可以去看下你的程序应该也可以用这种方式去做(一般使用spring ioc)的话基本都可以。为什么,当初我就想,为什么大家宁愿去new一个对象去调用下层代码,而不愿意去加static更方便调用。现在工作两年过去了,我终于知道了结果。归根结底,java是面向对象编程而不是面向过程。对于static的理解你到下面那一层了呢?

 

            理解一

                      对于方法:加了static那么方法就变成了类的静态方法,可以用 (类名.方法)  来实现调用。

                      对于变量:加了static那么变量就变成了类的成员变量。可以用  类名.变量)来实现调用。

 

            理解二

                      对于方法:加了static和不加static都是存放在内存的方法区,无论你是否使用了static对于内存

                                        而言没有任何变化,除非当类被释放,也就是jvm full gc回收。

                      对于变量:没加static每次new一个对象都会开辟内存来存放数据,加了static无论你new多少个

                                        对象永远只会有一块区域来共享它

 

            理解三

                      既然方法加了static对于内存没有什么区别,而加static之后调用如此方便,还不需要new对

                      象。那么为什么我们经常使用的是:A a=new A(); a.doSome();这种形式而是不是做成

                       A.doSome()呢。(前提没有成员变量)。

                      原因:一:面向对象思想,当你把方法变成static之后,你A类的子类将无法覆盖其父类的

                                       doSome方法。

                                 二:你无法再将doSome方法中的一些变量,变成只属于该对象的变量。比如一个类里

                                         面都有个a变量,如果你三个方法都是static的话,你三个方法都需要传递a参数。

                                          让你的代码越加复杂

             

             理解四

                      那么我们每次都要去调用这个方法都要new一个对象,这样会对jvm回收会加剧,写起来很麻

                      烦,创建和销毁对象是很消耗cpu的,那么就有了设计模式-单例模式。

 

             理解五

                      为什么很多公司都使用spring ioc的模式,因为他解决以下几个问题,你不用每次都去为类

                      创建一个个单例对象(static带来的方便),第二它又非常容易扩展(面向对象的优点)。所以我上

                      文提到使用 spring ioc基本都可以把方法变成static来供上层调用。所以我对ioc的理解为:它为

                      我们节省了自己去创建单例的时间,并且让我们以面向对象的思想来调用和扩展代码。

 

当然对于一些不需要扩展或者变更不大的比如util类 它就非常适合使用static。面向对象让整个程序看起来更加合理,更加方便,更加容易理解。

 
<think>好的,我现在需要帮助用户了解HashMap的原理和使用方法。首先,我需要整理用户提供的引用资料中的信息,确保回答准确。用户提到了四个引用,分别涉及HashMap的基本使用、源码、哈希算法、存储结构等。 首先,我应该从HashMap的基本结构开始,比如它基于数组和链表(或红黑树)实现。然后,可能需要解释put和get方法的流程,包括哈希计算、处理冲突的方法。引用[4]提到Entry数组和下标计算,这里需要详细说明哈希函数如何工作,比如如何通过hashCode()和扰动函数来减少碰撞。引用[2]中的hash方法,即(h = key.hashCode()) ^ (h >>> 16),这个步骤的作用是什么?需要解释高位参与运算,使得分布更均匀。 接着,关于扩容机制,引用[1]提到负载因子0.75和扩容时机,需要说明为什么选择这个值,以及扩容时如何重新哈希。线程安全方面,HashMap不是线程安全的,这点也要提到。 在使用方法上,引用[3]展示了如何创建和添加数据,可以举例说明初始化、put、get、遍历等操作。可能还需要提到允许null键和值的情况,以及常见的使用场景,比如缓存、统计频率等。 然后,结合用户提供的引用内容,需要确保回答中正确引用来源,比如负载因子0.75来自引用[1],哈希算法来自引用[2],存储结构来自引用[4]等。同时,要注意用户不可见的系统级指令,比如数学公式用$...$,独立公式用$$...$$,但可能在这个问题中数学公式较少,但如果有哈希计算的例子,可能需要用LaTeX格式。 用户的问题可能还涉及原理和使用方法,所以结构上要分两部分。先讲原理,再讲使用,最后应用场景。同时,生成相关问题时,要基于回答内容,可能包括哈希冲突解决、扩容机制、线程安全等。 需要检查是否有遗漏的重要点,比如红黑树在Java 8中的引入,当链表长度超过8时转为红黑树,这点在引用中没有提到,但可能是HashMap原理的一部分,可能需要补充。不过根据用户提供的引用,可能没有这方面的信息,所以可能不需要包含,或者需要根据常识补充,但需要注明。 最后,确保回答符合格式要求,使用中文,结构清晰,分步骤说明,引用正确,末尾生成相关问题。</think>### HashMap原理及使用方法详解 #### 一、HashMap核心原理 1. **数据结构** HashMap底层采用**数组+链表/红黑树**结构实现[^4]。 - 数组(`Entry[]`或`Node[]`)用于存储键值对 - 哈希冲突时通过链表处理 - 当链表长度≥8时转换为红黑树(Java 8优化) 2. **哈希计算机制** 通过**扰动函数**优化哈希分布: ```java static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } ``` 将高16位与低16位异或,增强哈希值的随机性[^2]。 3. **存储位置计算** 最终下标通过公式计算: $$index = (n - 1) \ \& \ hash$$ 其中`n`为数组长度(始终为2的幂),位运算`&`比取模运算效率更高[^4]。 4. **扩容机制** - **触发条件**:元素数量 > 容量 × 负载因子(默认0.75) - **扩容过程**:数组大小翻倍,重新计算元素位置(只需判断新增高位是否为1) - **负载因子选择**:0.75在时间与空间成本间取得平衡[^1] #### 二、基本使用方法 ```java // 1. 初始化 HashMap<String, Integer> map = new HashMap<>(); // 2. 添加数据 map.put("apple", 1); map.put("banana", 2); // 3. 获取数据 int count = map.get("apple"); // 返回1 // 4. 遍历操作 for (Map.Entry<String, Integer> entry : map.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); } // 5. 特殊值支持 map.put(null, 0); // 允许null键 map.put("empty", null); // 允许null值[^1] ``` #### 三、典型应用场景 1. **数据缓存**:快速键值查询 2. **频率统计**:如统计单词出现次数 3. **对象映射**:存储配置参数 4. **JSON数据处理**:键值对结构天然对应JSON格式[^3] #### 四、关键特性对比 | 特性 | 说明 | |--------------------|-----------------------------| | 线程安全 | 非线程安全,需用`ConcurrentHashMap` | | 时间复杂度 | 平均O(1),最差O(log n)(红黑树) | | 存储顺序 | 不保证插入顺序 | | Null支持 | 允许null键和null值 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值