常熟java培训短期班_常熟JAVA培训
预约试听
发布时间:2018-08-23编辑:佚名
黄 凯高级讲师
多年移动互联网开发经验,精通Android与iOS开发,对JavaEE等后台技术也
有所研究。尤其精通Android平台的开发,对Android平台下的性能优化有极其丰富的经验。 曾就职于酷狗音乐担任高级Android软件工程师与Team
Leader一职,带领超过20人的开发团队,有丰富的开发与管理经验。参与开发了<酷狗音乐>,<繁星网>,<中国电信移动办公>,
<智慧天河>,<翼健康>,<创饷无限>,<外修管家>等20多款互联网热门应用。其不但开发经验丰富,教学幽默风趣,而且对
学生要求严格,坚持授人与鱼不如授人与渔的理念,注重培养学生的解决问题与自我思考的能力。
Java工程师就业前景
Java工程师就业前景
2015年,在美国、加拿大、澳大利亚、新加坡等发达国家和中等发达国家,
JAVA软件工程师年薪均在4—15万美金,而在国内,JAVA软件工程师也有极好的工作机会和很高的薪水。
在未来5年内,合格软件人才的需求将远大于供给。JAVA软件工程师是目前
国际高端计算机领域就业薪资非常高的一类软件工程师。
一般情况下的JAVA软件工程师是分四个等级,从软件技术员到助理软件工程
师,再到软件工程师,**后成为高级软件工程师。
根据IDC的统计数字,在所有软件开发类人才的需求中,对JAVA工程师的需
求达到全部需求量的60%—70%。同时,JAVA软件工程师的工资待遇相对较高。
通常来说,具有3—5年开发经验的工程师,拥有年薪15万元是很正常的一个
薪酬水平。80%的学生毕业后年薪都超过了8万元。
根据专业数据分析,由于我国经济发展不均衡因素,JAVA软件工程师工资待
遇在城市之间的差异也较大,一级城市(如北京、上海等),初级软件工程师的待遇大概在4000-6000之间,中级软件工程师的待遇在6000—8000之间,
而高级软件工程师的待遇基本破万。
一阶段 java基础,我们将学习变量,基本数据类型,进制,转义字符,运
算符,分支语句和循环语句等,以达到训练基础语法和逻辑能力的目的。还有对数组、面向对象和异常处理等。
二阶段 javaWeb,主要是学习Web前端开发基础和框架、Servlet和JSP在Web
后端的应用、Web后端开发相关专题、MVC和分层架构以及项目开发流程及CASE工具的使用等。
三阶段 java框架,像框架整合开发(SSH/SSS)、RESTful架构和移动端接口
设计、第三方接口和在线支付功能、网站安全和Spring Security应用实战、复杂用户交互处理和Spring Web Flow的应用、MyBatis的应用和SSM整合等
技术点都是需要你掌握的。
四阶段 java 云数据,亿级并发架构演进、Linux基础、搭建tomcat环境以
及大数据开发云计算等高级Java教程,是Java技术的高端知识。其中穿插项目实战演练,企业真实项目供学员应用学习,进行知识体系的“二次学习”
。
Java HashSet和HashMap源码剖析
>
原文地址:http://www.cnblogs.com/CarpenterLee/p/5440428.html
总体介绍
之所以把HashSet和HashMap放在一起讲解,是因为二者在java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说HashSet里面有一个HashMap(适配器模式)。因此本文将重点分析HashMap。
HashMap实现了Map接口,允许放入null
元素,除该类未实现同步外,其余跟Hashtable
大致相同,跟TreeMap不同,该容器不保证元素顺序,根据需要该容器可能会对元素重新哈希,元素的顺序也会被重新打散,因此不同时间迭代同一个HashMap的顺序可能会不同。
根据对冲突的处理方式不同,哈希表有两种实现方式,一种开放地址方式(Open addressing),另一种是冲突链表方式(Separate chaining with linked lists)。Java HashMap采用的是冲突链表方式。
从上图容易看出,如果选择合适的哈希函数,put()
和get()
方法可以在常数时间内完成。但在对HashMap进行迭代时,需要遍历整个table以及后面跟的冲突链表。因此对于迭代比较频繁的场景,不宜将HashMap的初始大小设的过大。
有两个参数可以影响HashMap的性能:初始容量(inital capacity)和负载系数(load factor)。初始容量指定了初始table
的大小,负载系数用来指定自动扩容的临界值。当entry
的数量超过capacity*load_factor
时,容器将自动扩容并重新哈希。对于插入元素较多的场景,将初始容量设大可以减少重新哈希的次数。
将对向放入到HashMap或HashSet中时,有两个方法需要特别关心:hashCode()
和equals()
。hashCode()
方法决定了对象会被放到哪个bucket
里,当多个对象的哈希值冲突时,equals()
方法决定了这些对象是否是“同一个对象”。所以,如果要将自定义的对象放入到HashMap
或HashSet
中,需要@Override hashCode()
和equals()
方法。
方法剖析
get()
get(Object
key)
方法根据指定的key
值返回对应的value
,该方法调用了getEntry(Object
key)
得到相应的entry
,然后返回entry.getValue()
。因此getEntry()
是算法的核心。
算法思想是首先**hash()
函数得到对应bucket
的下标,然后依次遍历冲突链表,**key.equals(k)
方法来判断是否是要找的那个entry
。
上图中hash(k)&(table.length-1)
等价于hash(k)%table.length
,原因是HashMap要求table.length
必须是2的指数,因此table.length-1
就是二进制低位全是1,跟hash(k)
相与会将哈希值的高位全抹掉,剩下的就是余数了。
//getEntry()方法
final Entry<K,V> getEntry(Object key) {
......
int hash = (key == null) ? 0 : hash(key);
for (Entry<K,V> e = table[hash&(table.length-1)];//得到冲突链表
e != null; e = e.next) {//依次遍历冲突链表中的每个entry
Object k;
//依据equals()方法判断是否相等
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
put()
put(K
key, V value)
方法是将指定的key,
value
对添加到map
里。该方法首先会对map
做一次查找,看是否包含该元组,如果已经包含则直接返回,查找过程类似于getEntry()
方法;如果没有找到,则会**addEntry(int
hash, K key, V value, int bucketIndex)
方法插入新的entry
,插入方式为头插法。
//addEntry()
void addEntry(int hash, K key, V value, int bucketIndex) {
if ((size >= threshold) && (null != table[bucketIndex])) {
resize(2 * table.length);//自动扩容,并重新哈希
hash = (null != key) ? hash(key) : 0;
bucketIndex = hash & (table.length-1);//hash%table.length
}
//在冲突链表头部插入新的entry
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<>(hash, key, value, e);
size ;
}
remove()
remove(Object
key)
的作用是删除key
值对应的entry
,该方法的具体逻辑是在removeEntryForKey(Object
key)
里实现的。removeEntryForKey()
方法会首先找到key
值对应的entry
,然后删除该entry
(修改链表的相应指针)。查找过程跟getEntry()
过程类似。
//removeEntryForKey()
final Entry<K,V> removeEntryForKey(Object key) {
......
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);//hash&(table.length-1)
Entry<K,V> PRev = table[i];//得到冲突链表
Entry<K,V> e = prev;
while (e != null) {//遍历冲突链表
Entry<K,V> next = e.next;
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k)))) {//找到要删除的entry
modCount ; size--;
if (prev == e) table[i] = next;//删除的是冲突链表的**个entry
else prev.next = next;
return e;
}
prev = e; e = next;
}
return e;
}
HashSet
前面已经说过HashSet是对HashMap的简单包装,对HashSet的函数调用都会转换成合适的HashMap方法,因此HashSet的实现非常简单,只有不到300行代码。这里不再赘述。
//HashSet是对HashMap的简单包装
public class HashSet<E>
{
......
private transient HashMap<E,Object> map;//HashSet里面有一个HashMap
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<>();
}
......
public boolean add(E e) {//简单的方法转换
return map.put(e, PRESENT)==null;
}
......
}
相关推荐:
苏州JAVA培训 苏州JAVA培训班 苏州JAVA培训机构