1.Hashtableï¼HashMapåTreeMapçåºå«
2.å¦ä½è®¾è®¡å¹¶å®ç°ä¸ä¸ªçº¿ç¨å®å
¨ç Map
3.map和字典的区别
4.ConcurrentHashMap确实很复杂,这样学源码才简单
5.Java常用框架组合(java框架)
Hashtableï¼HashMapåTreeMapçåºå«
Java为æ°æ®ç»æä¸çæ å°å®ä¹äºä¸ä¸ªæ¥å£java.util.Mapï¼å®æå个å®ç°ç±»ï¼åå«æ¯HashMapãHashTableãLinkedHashMapåTreeMapã
è¿éä»ç»è¿4ä¸å®ä¾çç¨æ³ååºå«ã
å ³é®ææ¯åæï¼
Mapç¨äºåå¨é®å¼å¯¹ï¼æ ¹æ®é®å¾å°å¼ï¼å æ¤ä¸å 许é®éå¤ï¼å¼å¯ä»¥éå¤ã
l ï¼1ï¼HashMapæ¯ä¸ä¸ªæ常ç¨çMapï¼å®æ ¹æ®é®çhashCodeå¼åå¨æ°æ®ï¼æ ¹æ®é®å¯ä»¥ç´æ¥è·åå®çå¼ï¼å ·æå¾å¿«ç访é®é度ãHashMapæå¤åªå 许ä¸æ¡è®°å½çé®ä¸ºnullï¼ä¸å 许å¤æ¡è®°å½çå¼ä¸ºnullãHashMapä¸æ¯æ线ç¨çåæ¥ï¼å³ä»»ä¸æ¶å»å¯ä»¥æå¤ä¸ªçº¿ç¨åæ¶åHashMapï¼å¯è½ä¼å¯¼è´æ°æ®çä¸ä¸è´ãå¦æéè¦åæ¥ï¼å¯ä»¥ç¨Collections.synchronizedMap(HashMap map)æ¹æ³ä½¿HashMapå ·æåæ¥çè½åã
l ï¼2ï¼Hashtableä¸HashMap类似ï¼ä¸åçæ¯ï¼å®ä¸å 许记å½çé®æè å¼ä¸ºç©ºï¼å®æ¯æ线ç¨çåæ¥ï¼å³ä»»ä¸æ¶å»åªæä¸ä¸ªçº¿ç¨è½åHashtableï¼ç¶èï¼è¿ä¹å¯¼è´äºHashtableå¨åå ¥æ¶ä¼æ¯è¾æ ¢ã
l ï¼3ï¼LinkedHashMapä¿åäºè®°å½çæå ¥é¡ºåºï¼å¨ç¨IteraoréåLinkedHashMapæ¶ï¼å å¾å°çè®°å½è¯å®æ¯å æå ¥çãå¨éåçæ¶åä¼æ¯HashMapæ ¢ãæHashMapçå ¨é¨ç¹æ§ã
l ï¼4ï¼TreeMapè½å¤æå®ä¿åçè®°å½æ ¹æ®é®æåºï¼é»è®¤æ¯æååºæåºï¼ä¹å¯ä»¥æå®æåºçæ¯è¾å¨ãå½ç¨IteraoréåTreeMapæ¶ï¼å¾å°çè®°å½æ¯æè¿åºçãTreeMapçé®åå¼é½ä¸è½ä¸ºç©ºã
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
public class TestMap {
public static void init(Map map){
if (map != null){
String key = null;
for (int i=5; i>0; i--){
key = new Integer(i).toString() + ".0";
map.put(key, key.toString());
//Mapä¸çé®æ¯ä¸éå¤çï¼å¦ææå ¥ä¸¤ä¸ªé®å¼ä¸æ ·çè®°å½ï¼
//é£ä¹åæå ¥çè®°å½ä¼è¦çå æå ¥çè®°å½
map.put(key, key.toString() + "0"); }
}
}
public static void output(Map map){
if (map != null){
Object key = null;
Object value = null;
//使ç¨è¿ä»£å¨éåMapçé®ï¼æ ¹æ®é®åå¼
Iterator it = map.keySet().iterator();
while (it.hasNext()){
key = it.next();
value = map.get(key);
System.out.println("key: " + key + "; value: " + value );
}
//æè 使ç¨è¿ä»£å¨éåMapçè®°å½Map.Entry
Map.Entry entry = null;
it = map.entrySet().iterator();
while (it.hasNext()){
//ä¸ä¸ªMap.Entry代表ä¸æ¡è®°å½
entry = (Map.Entry)it.next();
//éè¿entryå¯ä»¥è·å¾è®°å½çé®åå¼
//System.out.println("key: " + entry.getKey() + "; value: " + entry.getValue());
}
}
}
public static boolean containsKey(Map map, Object key){
if (map != null){
return map.containsKey(key);
}
return false;
}
public static boolean containsValue(Map map, Object value){
if (map != null){
return map.containsValue(value);
}
return false;
}
public static void testHashMap(){
Map myMap = new HashMap();
init(myMap);
//HashMapçé®å¯ä»¥ä¸ºnull
myMap.put(null,"ddd");
//HashMapçå¼å¯ä»¥ä¸ºnull
myMap.put("aaa", null);
output(myMap);
}
public static void testHashtable(){
Map myMap = new Hashtable();
init(myMap);
//Hashtableçé®ä¸è½ä¸ºnull
//myMap.put(null,"ddd");
//Hashtableçå¼ä¸è½ä¸ºnull
//myMap.put("aaa", null);
output(myMap);
}
public static void testLinkedHashMap(){
Map myMap = new LinkedHashMap();
init(myMap);
//LinkedHashMapçé®å¯ä»¥ä¸ºnull
myMap.put(null,"ddd");
myMap.put(null,"aaa");
//LinkedHashMapçå¼å¯ä»¥ä¸ºnull
myMap.put("aaa", null);
output(myMap);
}
public static void testTreeMap(){
Map myMap = new TreeMap();
init(myMap);
//TreeMapçé®ä¸è½ä¸ºnull
//myMap.put(null,"ddd");
//TreeMapçå¼ä¸è½ä¸ºnull
//myMap.put("aaa", null);
output(myMap);
}
public static void main(String[] args) {
System.out.println("éç¨HashMap");
TestMap.testHashMap();
System.out.println("éç¨Hashtable");
TestMap.testHashtable();
System.out.println("éç¨LinkedHashMap");
TestMap.testLinkedHashMap();
System.out.println("éç¨TreeMap");
TestMap.testTreeMap();
Map myMap = new HashMap();
TestMap.init(myMap);
System.out.println("æ°åå§åä¸ä¸ªMap: myMap");
TestMap.output(myMap);
//æ¸ ç©ºMap
myMap.clear();
System.out.println("å°myMap clearåï¼myMap空äºä¹? " + myMap.isEmpty());
TestMap.output(myMap);
myMap.put("aaa", "aaaa");
myMap.put("bbb", "bbbb");
//å¤æMapæ¯å¦å å«æé®æè æå¼
System.out.println("myMapå å«é®aaa? "+ TestMap.containsKey(myMap, "aaa"));
System.out.println("myMapå å«å¼aaaa? "+ TestMap.containsValue(myMap, "aaaa"));
//æ ¹æ®é®å é¤Mapä¸çè®°å½
myMap.remove("aaa");
System.out.println("å é¤é®aaaåï¼myMapå å«é®aaa? "+ TestMap.containsKey(myMap, "aaa"));
//è·åMapçè®°å½æ°
System.out.println("myMapå å«çè®°å½æ°: " + myMap.size());
}
}
è¾åºç»æï¼
éç¨HashMap
key: null; value: ddd
key: 3.0; value: 3.
key: aaa; value: null
key: 4.0; value: 4.
key: 1.0; value: 1.
key: 5.0; value: 5.
key: 2.0; value: 2.
éç¨Hashtable
key: 4.0; value: 4.
key: 1.0; value: 1.
key: 3.0; value: 3.
key: 5.0; value: 5.
key: 2.0; value: 2.
éç¨LinkedHashMap
key: 5.0; value: 5.
key: 4.0; value: 4.
key: 3.0; value: 3.
key: 2.0; value: 2.
key: 1.0; value: 1.
key: null; value: aaa
key: aaa; value: null
éç¨TreeMap
key: 1.0; value: 1.
key: 2.0; value: 2.
key: 3.0; value: 3.
key: 4.0; value: 4.
key: 5.0; value: 5.
æ°åå§åä¸ä¸ªMap: myMap
key: 3.0; value: 3.
key: 4.0; value: 4.
key: 1.0; value: 1.
key: 5.0; value: 5.
key: 2.0; value: 2.
å°myMap clearåï¼myMap空äºä¹? true
myMapå å«é®aaa? true
myMapå å«å¼aaaa? true
å é¤é®aaaåï¼myMapå å«é®aaa? false
myMapå å«çè®°å½æ°: 1
æºç åæï¼
éåMapæ两ç§æ¹æ³ï¼
ï¼1ï¼mapçkeySet()æ¹æ³è·å¾é®çéåï¼åè°ç¨é®éåçiteratoræ¹æ³è·å¾é®çè¿ä»£å¨ï¼ä»¥æ¤è¿ä»£å°ååºMapä¸çé®ï¼ç¨getæ¹æ³è·å¾é®å¯¹åºçå¼ï¼ä¾¿å®æäºMapçéåã代ç å¦ä¸æ示ï¼
//使ç¨è¿ä»£å¨éåMapçé®ï¼æ ¹æ®é®åå¼
Iterator it = map.keySet().iterator();
while (it.hasNext()){
key = it.next();
value = map.get(key);
System.out.println("key: " + key + "; value: " + value );
}
ï¼2ï¼ä½¿ç¨MapçentrySetæ¹æ³è·å¾Mapä¸è®°å½çéåï¼æ¯æ¡å¯¹è±¡é½æ¯ä¸ä¸ªMap.Entry对象ï¼ä½¿ç¨å ¶getKeyæ¹æ³è·å¾è®°å½çé®ï¼ä½¿ç¨å ¶getValueæ¹æ³è·å¾è®°å½çå¼ã代ç å¦ä¸æ示ï¼
//æè 使ç¨è¿ä»£å¨éåMapçè®°å½Map.Entry
Map.Entry entry = null;
it = map.entrySet().iterator();
while (it.hasNext()){
//ä¸ä¸ªMap.Entry代表ä¸æ¡è®°å½
entry = (Map.Entry)it.next();
//éè¿entryå¯ä»¥è·å¾è®°å½çé®åå¼
//System.out.println("key: " + entry.getKey() + "; value: " + entry.getValue());
å¦ä½è®¾è®¡å¹¶å®ç°ä¸ä¸ªçº¿ç¨å®å ¨ç Map
Map æ¯ä¸ä¸ªé常常ç¨çæ°æ®ç»æï¼ä¸ä¸ªæ åºç key/value 对çéåï¼å ¶ä¸ Map ææç key é½æ¯ä¸åçï¼ç¶åéè¿ç»å®ç key å¯ä»¥å¨å¸¸æ°æ¶é´ O(1) å¤æ度å æ¥æ¾ãæ´æ°æå é¤å¯¹åºç valueã
è¦æ³å®ç°å¸¸æ°çº§çæ¥æ¾ï¼åºè¯¥ç¨ä»ä¹æ¥å®ç°å¢ï¼è¯»è åºè¯¥å¾å¿«ä¼æ³å°åå¸è¡¨ãç¡®å®ï¼Map åºå±ä¸è¬é½æ¯ä½¿ç¨æ°ç»æ¥å®ç°ï¼ä¼åç¨åå¸ç®æ³è¾ å©ã对äºç»å®ç keyï¼ä¸è¬å è¿è¡ hash æä½ï¼ç¶åç¸å¯¹åå¸è¡¨çé¿åº¦å模ï¼å° key æ å°å°æå®çå°æ¹ã
åå¸ç®æ³æå¾å¤ç§ï¼éåªä¸ç§æ´å é«æå¢ï¼
1. åå¸å½æ°
MD5 å SHA1 å¯ä»¥è¯´æ¯ç®ååºç¨æ广æ³ç Hash ç®æ³ï¼èå®ä»¬é½æ¯ä»¥ MD4 为åºç¡è®¾è®¡çã
MD4(RFC ) æ¯ MIT çRonald L. Rivest å¨ å¹´è®¾è®¡çï¼MD æ¯ Message Digestï¼æ¶æ¯æè¦ï¼ ç缩åãå®éç¨å¨ä½åé¿çå¤çå¨ä¸ç¨é«é软件å®ç°ââå®æ¯åºäº ä½æä½æ°çä½æä½æ¥å®ç°çã
MD5(RFC ) æ¯ Rivest äºå¹´å¯¹ MD4 çæ¹è¿çæ¬ãå®å¯¹è¾å ¥ä»ä»¥ä½åç»ï¼å ¶è¾åºæ¯4个ä½åç级èï¼ä¸ MD4 ç¸åãMD5 æ¯ MD4 æ¥å¾å¤æï¼å¹¶ä¸é度è¾ä¹è¦æ ¢ä¸ç¹ï¼ä½æ´å®å ¨ï¼å¨æåæåæå·®åæ¹é¢è¡¨ç°æ´å¥½ã
SHA1 æ¯ç± NIST NSA 设计为å DSA ä¸èµ·ä½¿ç¨çï¼å®å¯¹é¿åº¦å°äºçè¾å ¥ï¼äº§çé¿åº¦ä¸ºbit çæ£åå¼ï¼å æ¤æ穷举 (brute-force)
æ§æ´å¥½ãSHA-1 设计æ¶åºäºå MD4 ç¸ååç,并ä¸æ¨¡ä»¿äºè¯¥ç®æ³ã
常ç¨ç hash å½æ°æ SHA-1ï¼SHA-ï¼SHA-ï¼MD5 ãè¿äºé½æ¯ç»å ¸ç hash ç®æ³ãå¨ç°ä»£åç产ä¸ï¼è¿ä¼ç¨å°ç°ä»£ç hash ç®æ³ãä¸é¢å举å 个ï¼è¿è¡æ§è½å¯¹æ¯ï¼æååéå ¶ä¸ä¸ä¸ªæºç åæä¸ä¸å®ç°è¿ç¨ã
ï¼1ï¼ Jenkins Hash å SpookyHash
å¹´ Bob Jenkins å¨ã Dr. Dobbs Journalãæå¿ä¸å表äºä¸çå ³äºæ£åå½æ°çæç« ãA hash function for hash Table lookupããè¿ç¯æç« ä¸ï¼Bob 广æ³æ¶å½äºå¾å¤å·²æçæ£åå½æ°ï¼è¿å ¶ä¸ä¹å æ¬äºä»èªå·±æè°çâlookup2âãéåå¨å¹´ï¼Bob åå¸äº lookup3ãlookup3 å³ä¸º Jenkins Hashãæ´å¤æå ³ Bobâs æ£åå½æ°çå 容请åé ç»´åºç¾ç§ï¼Jenkins hash functionãmemcachedç hash ç®æ³ï¼æ¯æ两ç§ç®æ³ï¼jenkins, murmur3ï¼é»è®¤æ¯ jenkinsã
å¹´ Bob Jenkins åå¸äºä»èªå·±çä¸ä¸ªæ°æ£åå½æ°
SpookyHashï¼è¿æ ·å½åæ¯å 为å®æ¯å¨ä¸å£èåå¸çï¼ãå®ä»¬é½æ¥æ2åäº MurmurHash çé度ï¼ä½ä»ä»¬é½åªä½¿ç¨äºä½æ°å¦å½æ°è没æä½çæ¬ï¼SpookyHash ç»åºä½è¾åºã
ï¼2ï¼ MurmurHash
MurmurHash æ¯ä¸ç§éå å¯ååå¸å½æ°ï¼éç¨äºä¸è¬çåå¸æ£ç´¢æä½ã
Austin Appleby å¨å¹´åå¸äºä¸ä¸ªæ°çæ£åå½æ°ââMurmurHashãå ¶ææ°çæ¬å¤§çº¦æ¯ lookup3 é度ç2åï¼å¤§çº¦ä¸º1 byte/cycleï¼ï¼å®æä½åä½ä¸¤ä¸ªçæ¬ãä½çæ¬åªä½¿ç¨ä½æ°å¦å½æ°å¹¶ç»åºä¸ä¸ªä½çåå¸å¼ï¼èä½çæ¬ä½¿ç¨äºä½çæ°å¦å½æ°ï¼å¹¶ç»åºä½åå¸å¼ãæ ¹æ®Austinçåæï¼MurmurHashå ·æä¼å¼çæ§è½ï¼è½ç¶ Bob Jenkins å¨ãDr. Dobbs articleãæå¿ä¸å£°ç§°âæé¢æµ MurmurHash æ¯èµ·lookup3è¦å¼±ï¼ä½æ¯æä¸ç¥éå ·ä½å¼ï¼å 为æè¿æ²¡æµè¯è¿å®âãMurmurHashè½å¤è¿ é走红å¾çäºå ¶åºè²çé度åç»è®¡ç¹æ§ãå½åççæ¬æ¯MurmurHash3ï¼RedisãMemcachedãCassandraãHBaseãLuceneé½å¨ä½¿ç¨å®ã
ä½è ï¼ä¸ç¼æ®æµåéåè¾¹å°é
map和字典的区别
第一个区别就先来说说继承关系吧
如果你baidu一下,会发现网上的大致说法与“由于Java发展的历史原因。Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。”相同。vc 游戏源码
这种说法没有错,但是不够准确,特别是对于我们这种大众菜鸟来说,如果不去深究的话,可能就会造成一些理解上的差异。简单的认为Hashtable没有继承Map接口。
我们可以参考一下最新的JDK1.6的源码,看看这两个类的定义:
public class Hashtable<K,V>extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable { …}
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { …}
可以看到hashtable也是继承了Map接口。
它们的不同是Hashtable(since JDK1.0)就继承了Dictionary这个抽象类,
而HashMap(since JDK1.2)继承的则是AbstractMap这个抽象类。
第二个区别我们从同步和并发性上来说说它们两个的不同。
可以通过这两个类得源码来分析,Hashtable中的主要方法都做了同步处理,而HashMap则没有。
可以说Hashtable在默认情况支持同步,而HashMap在默认情况下是不支持的。
我们在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。
对HashMap的同步处理可以使用Collections类提供的synchronizedMap静态方法;
或者直接使用JDK5.0之后提供的java.util.concurrent包里的ConcurrentHashMap类。
ConcurrentHashMap确实很复杂,这样学源码才简单
ConcurrentHashMap相较于HashMap在实现上更为复杂,主要涉及多线程环境下的并发安全、同步和锁的概念。虽然HashMap的分页源码mybatis原理主要围绕数组、链表、哈希碰撞和扩容,但在多线程场景下,这些知识还不够,需要对并发和同步有深入理解。
在实际编程中,HashMap经常被使用,而ConcurrentHashMap的使用频率却相对较低,这使得学习它的门槛变高。学习ConcurrentHashMap之前,关键在于理解HashMap的基本实现,特别是它在非线程安全情况下的操作,如数组初始化和putVal()方法。
HashMap的线程不安全问题主要表现在数组的懒加载和带if判断的put操作上,这可能导致数据一致性问题。为了解决这些问题,像HashTable和Collections.synchronizedMap()通过synchronized关键字加锁,但会导致性能下降。ConcurrentHashMap引入了CAS(Compare And Swap)技术,比如在initTable()方法中,通过volatile修饰的成员变量保证了数组初始化的线程安全。
ConcurrentHashMap在数组初始化、下标为空时使用CAS,而在有冲突时切换到synchronized,降低了锁的粒度,以提高效率。扩容是ConcurrentHashMap的难点,需要处理新旧数组的同步迁移问题,通过helpTransfer()方法和transfer()方法来确保线程安全。
总结来说,天池大赛源码学习ConcurrentHashMap不仅是对HashMap知识的扩展,更是进入并发编程世界的重要一步。面试时,如果只问基本数据结构,那可能只需要了解HashMap;但若深入到ConcurrentHashMap,就涉及到了并发编程的核心技术,如CAS、同步和锁的管理。
Java常用框架组合(java框架)
java常用的框架有哪些?
web层框架:SpringMVC、Struts2、Struts1、GoogleWebToolkit(GWT)、扰皮简JQWEB
服务层框握迹架缓裤:Spring、EJB
持久层框架:Hibernate、MyBatis、JPA、TopLink
Java中最常用的集合类框架?
一、HashMap的概述
HashMap可以说是Java中最常用的集合类框架之一,是Java语言中非常典型的数据结构。
HashMap是基于哈希表的Map接口实现的,此实现提供所有可选的映射操作。天通苑电脑培训发现存储的是对的映射,允许多个null值和一个null键。但此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
除了HashMap是非同步以及允许使用null外,HashMap类与Hashtable大致相同。
此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get和put)提供稳定的性能。迭代collection视图所需的时间与HashMap实例的“容量”(桶的数量)及其大小(键-值映射关系数)成比例。所以,如果迭代性能很重要,源码安装地址则不要将初始容量设置得太高(或将加载因子设置得太低)。
HashMap的实冲行培例有两个参数影响其性能:初始容量和加载因子。容量是哈希表中桶的数量,初始容量只是哈希表在创建时的容量。加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行rehash操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。
通常,默认加载因子(0.)在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数HashMap类的操作中,包括get和put操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少rehash操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生rehash操作。
注意,此实现不是同步的。如果多个线程同时访问一个HashMap实例,而其中至少一个线程从结构上修改了列表,那么它必须保持外部同步。这通常是通过同步那些用来封装列表的对象来实现的。但如果没有这样的对象存在,则应该使用{ @linkCollections#synchronizedMapCollections.synchronizedMap}来进行“包装”,该方法最好是在创建时完成,为了避免对映射进行意外的非同步操作。
Mapm=Collections.synchronizedMap(newHashMap(...));
二、构造函数
HashMap提供了三个构造函数:
HashMap():带念构造一个具有默认初始容量()和默认加载因子(0.)的头像剪切源码空HashMap。
HashMap(intinitialCapacity):构造一个带指定初始容量和默认加载因子(0.)的空HashMap。
HashMap(intinitialCapacity,floatloadFactor):构造一个带指定初始容量和加载因子的空HashMap。
这里提到了两个散唯参数:初始容量,加载因子。这两个参数是影响HashMap性能的重要参数,其中容量表示哈希表中桶的数量,初始容量是创建哈希表时的容量,加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度,它衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小。对于使用链表法的散列表来说,查找一个元素的平均时间是O(1+a),因此如果负载因子越大,对空间的利用更充分,然而后果是查找效率的降低;如果负载因子太小,那么散列表的数据将过于稀疏,对空间造成严重浪费。系统默认负载因子为0.,一般情况下我们是无需修改的。
HashMap是一种支持快速存取的数据结构,要了解它的性能必须要了解它的数据结构。
Java的三大框架是什么?java三大框架是:
1、Struts
为了解决这些问题,出现了Struts框架,它是一个完美的MVC实现,它有一个中央控制类(一个Servlet),针对不同的业务,我们需要一个Action类负责页面跳转和后台逻辑运算,一个或几个JSP页面负责数据的输入和输团肢出显示,还有一个Form类负责传递Action和JSP中间的数据。JSP中可以使用Struts框架提供的一组标签,就像使用HTML标签一样简单,但是可以完成非常复杂的逻辑。从此JSP页面中不需要出现一行包围的Java代码了。
可是所有的运算逻辑都放在Struts的Action里将使得Action类复用度低和逻辑混乱,所以通常人们会把整个Web应用程序分为三层,Struts负责显示层,它调用业务层完成运算逻辑,业务层再调用持久层完成数据库的读写。
使用JDBC连接来读写数据库,我们最常见的就是打开数据库连接、使用复杂的SQL语句进行读写、关闭连接,获得的数据又需要转换或封装后往外传,这是一个非常烦琐的过程。
2、Hibernate
这时出现了Hibernate框架,它需要你创建一系列的持久化类,每个类的属性都可以简单的看做和一张数据库表的属性一一对应,当然也可以实现关系数据库的各种表件关联的对应。当我们需要相关操作是,不用再关注数据库表。我们不用再去一行行的查询数据库,只需要持久化类就可以完成增删改查的功能。使我们的软件开发真正面向对象,而不是面向混乱的代码。我的感受是,使用Hibernate比JDBC方式减少了%的编程量。
现在我们有三个层了,可是每层之间的调用是怎样的呢?比如显示层的Struts需要调用一个业务类,就需要new一个业塌空世务类出来,然后使用;业务层需要调用持久层的类,也需要new一个持久层类出来用。通过这种new的方式互相调用就是软件开发中最糟糕设计的体现。简单的说,就是调用者依赖被调用者,它们之间形成了强耦合,如果我想在其他地方复用某个类,则这个类依赖的其他类也需要包含。程序就变得亏悔很混乱,每个类互相依赖互相调用,复用度极低。如果一个类做了修改,则依赖它的很多类都会受到牵连。为此,出现Spring框架。
3、Spring
Spring的作用就是完全解耦类之间的依赖关系,一个类如果要依赖什么,那就是一个接口。至于如何实现这个接口,这都不重要了。只要拿到一个实现了这个接口的类,就可以轻松的通过xml配置文件把实现类注射到调用接口的那个类里。所有类之间的这种依赖关系就完全通过配置文件的方式替代了。所以Spring框架最核心的就是所谓的依赖注射和控制反转。
现在的结构是,Struts负责显示层,Hibernate负责持久层,Spring负责中间的业务层,这个结构是目前国内最流行的JavaWeb应用程序架构了。另外,由于Spring使用的依赖注射以及AOP(面向方面编程),所以它的这种内部模式非常优秀,以至于Spring自己也实现了一个使用依赖注射的MVC框架,叫做SpringMVC,同时为了很好的处理事物,Spring集成了Hibernate,使事物管理从Hibernate的持久层提升到了业务层,使用更加方便和强大。
Struts框架是年就开始起步了,技术相当成熟,目前全球Java开发中Struts框架是显示层技术中当之无愧的王者。它拥有大量的用户群和很好的开发团队。这也是国内大部分Java软件公司对新进员工的基本要求。
java的框架有哪些?Java框架可以简化开发难度,更便于我们开发程序。所以学好Java框架还是比较重要的。
Java的框架主要有:SpringMVC、Spring、Mybatis、Dubbo、Maven、RabbitMQ、Log4j、Ehcache、Redis、Shiro。
不过这十个我们不需要都学会,只要学会其中四五个比较常用的就腊饥逗可以。
第一个,SpringMVC。SpringMVC是一种基于Java地实现了WebMVC设计模肢哗式的请求驱动类型的轻量级Web框架,主要是帮助我们简化日常的Web开发;
第二个,Mybatis。MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架;
第三个,Spring。Spring深得企业的青睐;
第四个,Maven。越来越多的开发人员开始使用maven。
掌握轮卖以上四种框架,你在找工作的时候就会比较吃香。
java有什么常用开源的框架?java常用开源框架如下:\x0d\1.SpringFrameworkJava开源JEE框架\x0d\\x0d\Spring是一个解决了许多在J2EE开发中常见的问题的强大框架。Spring提供了管理业务对象的一致方法并且鼓励了注入对接口编程而不是对类编程的良好习惯。Spring的架构基础是基于使用JavaBean属性的InversionofControl容器。然而,这仅仅是完整图景中的一部分:Spring在使用IoC容器作为构建完关注所有架构层的完整解决方案方面是独一无二的。\x0d\\x0d\2.WebWorkJava开源Web开发框架\x0d\\x0d\WebWork是由OpenSymphony组织开发的,致力于组件化和代码重用的拉出式MVC模式J2EEWeb框架。\x0d\\x0d\3.StrutsJava开源Web开发框架\x0d\\x0d\Struts是一个基于SunJ2EE平台的MVC框架,主要是采用Servlet和JSP技术谨祥罩来实现的。由于Struts能充分满足应用开发的需求,简单易用,敏捷迅速,在过去的一年中颇受关注。Struts把Servlet、JSP、自定义标签和信息资源(messageresources)整合到一个统一的框架中\x0d\\x0d\4.HibernateJava开源持久层框架\x0d\\x0d\Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。Hibernate可以应用在任何使用JDBC的场合\x0d\\x0d\5.QuartzJava开源调度框架\x0d\\x0d\Quartz是OpenSymphony开源组织在Jobscheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。\x0d\\x0d\6.VelocityJava开源模板引擎\x0d\\x0d\Velocity是一个基于java的模板引擎(templateengine)。它允许任何人仅仅简单的使用模板语言(templatelanguage)来引用由java代码定义的对象。当Velocity应用于web开发时,界面设计人员可以和java程序开发人员同步开发一个遵循MVC架构的web站点,也就是说,页面设计人员可以只关注页面的显示效果,而由java程序开发人员关注业务逻辑编码。Velocity将java代码从web页面中分离出来,这样为web站点的长期维护祥闹提供了便利,同时也为我们在JSP和PHP之外又提供了一种可选的方案。\x0d\\x0d\7.IBATISJava开源持久层框架\x0d\\x0d\使用ibatis提供的ORM机制,对业务逻辑实现人员而言,面对的是纯粹的Java对象,这一层与通过Hibernate实现ORM而言基本一致,而对于具体的数据操作,Hibernate会自动生成SQL语句,而ibatis则要求开发者宴或编写具体的SQL语句。相对Hibernate等“全自动”ORM机制而言,ibatis以SQL开发的工作量和数据库移植性上的让步,为系统设计提供了更大的自由空间。作为“全自动”ORM实现的一种有益补充,ibatis的出现显得别具意义。