java 集合框架

亲自手绘的UML类图:

 

一、遍历Map的四种方法:

public static void main(String[] args) {

  Map<String, String> map = new HashMap<String, String>();
  map.put("1", "value1");
  map.put("2", "value2");
  map.put("3", "value3");
  
  //第一种:广泛使用,二次取值
  System.out.println("经过Map.keySet遍历key和value:");
  for (String key : map.keySet()) {
   System.out.println("key= "+ key + " and value= " + map.get(key));
  }
  
  //第二种
  System.out.println("经过Map.entrySet使用iterator遍历key和value:");
  Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
  while (it.hasNext()) {
   Map.Entry<String, String> entry = it.next();
   System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
  }
  
  //第三种:推荐,尤为是容量大时
  System.out.println("经过Map.entrySet遍历key和value");
  for (Map.Entry<String, String> entry : map.entrySet()) {
   System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
  }

  //第四种
  System.out.println("经过Map.values()遍历全部的value,但不能遍历key");
  for (String v : map.values()) {
   System.out.println("value= " + v);
  }
 }

二、遍历set的两种方法:

1.迭代遍历:  

Set<String> set = new HashSet<String>();  

Iterator<String> it = set.iterator();  

while (it.hasNext()) {  

  String str = it.next();  

  System.out.println(str);  

}  
  

2.for循环遍历:  

for (String str : set) {  

   System.out.println(str);  

}  

三、数组与链表的区别:

数组是将元素在内存中连续存放,因为每一个元素占用内存相同,能够经过下标迅速访问数组中任何元素。可是若是要在数组中增长一个元素,须要移动大量元素,在内存中空出一个元素的空间,而后将要增长的元素放在其中。一样的道理,若是想删除一个元素,一样须要移动大量元素去填掉被移动的元素。若是应用须要快速访问数据,不多或不插入和删除元素,就应该用数组。java

链表刚好相反,链表中的元素在内存中不是顺序存储的,而是经过存在元素中的指针联系到一块儿。好比:上一个元素有个指针指到下一个元素,以此类推,直到最后一个元素。若是要访问链表中一个元素,须要从第一个元素开始,一直找到须要的元素位置。可是增长和删除一个元素对于链表数据结构就很是简单了,只要修改元素中的指针就能够了。若是应用须要常常插入和删除元素你就须要用链表数据结构了。程序员

(1) 从逻辑结构角度来看
  a, 数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的状况。当数据增长时,可能超出原先定义的元素个数;当数据减小时,形成内存浪费。
  b,链表动态地进行存储分配,能够适应数据动态地增减的状况,且能够方便地插入、删除数据项。数组中插入、删除数据项时,须要移动其它数据项)
(2)从内存存储角度来看
  a,(静态)数组从栈中分配空间, 对于程序员方便快速,但自由度小。
  b, 链表从堆中分配空间, 自由度大但申请管理比较麻烦.数组

四、ArrayList、Vector、LinkedList区别:

  1. ArrayList是最经常使用的List实现类,内部是经过数组实现的,它容许对元素进行快速随机访问。数组的缺点是每一个元素之间不能有间隔,当数组大小不知足时须要增长存储能力,就要讲已经有数组的数据复制到新的存储空间中。当从ArrayList的中间位置插入或者删除元素时,须要对数组进行复制、移动、代价比较高。所以,它适合随机查找和遍历,不适合插入和删除。
  2. Vector与ArrayList同样,也是经过数组实现的,不一样的是它支持线程的同步,即某一时刻只有一个线程可以写Vector,避免多线程同时写而引发的不一致性,但实现同步须要很高的花费,所以,访问它比访问ArrayList慢。
  3. LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了List接口中没有定义的方法,专门用于操做表头和表尾元素,能够看成堆栈、队列和双向队列使用。

五、HashSet、TreeSet、LinkedHashSet区别:

Set接口
Set不容许包含相同的元素,若是试图把两个相同元素加入同一个集合中,add方法返回false。
Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不 会接受这两个对象。数据结构

HashSet
HashSet有如下特色
 不能保证元素的排列顺序,顺序有可能发生变化
 不是同步的
 集合元素能够是null,但只能放入一个null
当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来获得该对象的hashCode值,而后根据 hashCode值来决定该对象在HashSet中存储位置。
简单的说,HashSet集合判断两个元素相等的标准是两个对象经过equals方法比较相等,而且两个对象的hashCode()方法返回值相 等
注意,若是要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是若是两个对 象经过equals方法比较返回true时,其hashCode也应该相同。另外,对象中用做equals比较标准的属性,都应该用来计算 hashCode的值。多线程

LinkedHashSet
LinkedHashSet集合一样是根据元素的hashCode值来决定元素的存储位置,可是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
LinkedHashSet在迭代访问Set中的所有元素时,性能比HashSet好,可是插入时性能稍微逊色于HashSet。性能

TreeSet类
TreeSet是SortedSet接口的惟一实现类,TreeSet能够确保集合元素处于排序状态。TreeSet支持两种排序方式,天然排序 和定制排序,其中天然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。
TreeSet判断两个对象不相等的方式是两个对象经过equals方法返回false,或者经过CompareTo方法比较没有返回0
天然排序
天然排序使用要排序元素的CompareTo(Object obj)方法来比较元素之间大小关系,而后将元素按照升序排列。
Java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现了该接口的对象就能够比较大小。
obj1.compareTo(obj2)方法若是返回0,则说明被比较的两个对象相等,若是返回一个正数,则代表obj1大于obj2,若是是 负数,则代表obj1小于obj2。
若是咱们将两个对象的equals方法老是返回true,则这两个对象的compareTo方法返回应该返回0
定制排序
天然排序是根据集合元素的大小,以升序排列,若是要定制排序,应该使用Comparator接口,实现 int compare(T o1,T o2)方法spa