Java_集合

定义:html

  是一种工具,就像是容器,能存储任意数量的具备共同属性的对象。java

与数组比较优势:算法

  (1)数组定义后长度不可变,集合长度可变;数组

  (2)数组只能经过下标访问,且下标类型只能是数字型,而有的集合(map)能够经过任意类型查找所映射的具体对象。安全

集合框架体系结构:数据结构

  

List的重要实现:ArrayList,LinkedList多线程

  ArrayList:并发

  优势:ArrayList以相似数组的形式进行存储,故随机访问速度极快;框架

  缺点:不适用进行频繁的插入或删除操做,由于每次插入或删除操做都会移动数组中的元素。工具

ArrayList就是基于数组的一个线性表,只不过长度能够动态改变。

关于ArrayList的几点注意:

(1)初始化ArrayList的时候若是没有指定初始化长度,默认长度为10

(2)ArrayList在增长新元素的时候若是超过了原始容量,会进行扩容,为 原始容量*3/2 +1;

(3)ArrayList是线程不安全的,在多线程的状况下不要使用。

但可使用Vector,由于Vector和ArrayList基本一致,区别在于Vector中的绝大部分方法都使用了同步关键字修饰,这样在多线程的状况下不会出现并发的错误。

Vector的扩容为原始容量*2;

Vector是ArrayList多线程的替代品。

(4)ArrayList实现遍历的几种方法:

public class Test7 { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("hello"); list.add("world"); list.add("!!!"); //一、for循环遍历 for(String str:list){ System.out.println(str); } for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } //二、把链表变成数组相关的内容进行遍历 String[] stringArr = new String[list.size()]; list.toArray(stringArr); for(int j=0;j<stringArr.length;j++){ System.out.println(stringArr[j]); } //三、迭代器遍历 Iterator<String> it = list.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }

LinkedList:

  优势:适合于在链表中间进行频繁的进行插入和删除操做;

  缺点:随机访问速度较慢,查找元素须要从头开始一个一个的找。

  LinkedList就是一种双向循环链表的链式线性表,只不过存储的结构使用的是链式表而已。

LinkedList的内部实现:【推荐看jdk源码】

  LinkedList的内部是基于双向循环链表的结构来实现的。在LinkedList中有一个相似于C语言中结构体的Entry内部类。

  在Entry的内部类中包含了前一个元素的地址引用和后一个元素的地址引用,相似于C语言中的指针。

LinkedList是线程不安全的,若是在多线程下面访问能够本身重写LinkedList,而后在须要同步的方法上面加上同步关键字synchronized。

LinkedList的遍历方法:

package javaEE; import java.util.Iterator; import java.util.LinkedList; import java.util.List; /** * @author 047493 * @version 2018年8月30日 * LinkedList遍历 */ public class Test8 { public static void main(String[] args) { List<String> list = new LinkedList<String>(); list.add("hello"); list.add("world"); list.add("我是一颗铜豌豆!"); for(String str:list){ System.out.println(str); } /*for(int i=0;i<list.size();i++){ System.out.println(list); }*/ String[] strArr = new String[list.size()]; list.toArray(strArr); for(int j=0;j<strArr.length;j++){ System.out.println(strArr[j]); } Iterator<String> it = list.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }


因为LinkedList实现了接口Dueue,因此LinkedList能够被当作堆栈来使用。

 

Set接口:

Set接口与List接口的区别在于,Set中的元素实现了不重复,有点像集合的概念,无序,不容许有重复的元素,最多容许有一个null元素对象。

须要注意的是:虽然Set中的元素没有顺序,可是元素在Set中的位置是由该元素的hashCode决定的,其具体位置实际上是很固定的。

举个例子:

对象A和对象B原本是两个不一样的对象,正常状况下它们是能够同时放到Set集合中去的,可是,若是对象A和对象B都重写了hashcode和equals方法,而且重写后的hashcode和equals值相同的话,

那么A和B就不能同时放到Set集合中去了,也就是说Set集合中的去重和hashcode与equals方法相关。

package javaEE; import java.util.HashSet; import java.util.Set; /** * @author 047493 * @version 2018年8月30日 * 类说明 */ public class Test9 { public static void main(String[] args) { Set<String> set = new HashSet<String>(); set.add("hello"); set.add("world"); set.add("hello"); set.add(null); set.add(null); System.out.println("set的大小为"+set.size()); System.out.println("set中的元素有"+set.toString()); } }

运行结果以下:

set的大小为3 set中的元素有[null, hello, world]

因为String类重写了hashcode和equals方法,因此第二个hello和null是加不进去的。
遍历HashSet的几种方法:

package javaEE; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /** * @author 047493 * @version 2018年8月30日 * 类说明 */ public class Test9 { public static void main(String[] args) { Set<String> set = new HashSet<String>(); set.add("hello"); set.add("world"); set.add("hello"); set.add("我是一颗铜豌豆"); set.add(null); for(String str:set){ System.out.println(str); } String[] arrSet = new String[set.size()]; set.toArray(arrSet); for(int i=0;i<arrSet.length;i++){ System.out.println(arrSet[i]); } Iterator<String> it = set.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }

LinkedHashSet:
LinkedHashSet不只是Set的子接口,仍是HashSet的子接口。

LinkedHashSet与HashSet的主要区别在于,LinkedHashSet中存储的元素是在哈希算法的基础上增长了链式表的结构。

TreeSet:

TreeSet是一种排序二叉树。存入Set集合中的值,会按照值的大小进行相关的排序操做。底层算法是基于红黑树实现的;

TreeSet和HashSet的主要区别在于TreeSet中的元素会按照相关的值进行排序;

 

关于HashSet和TreeSet的区别和联系:

  1. HashSet是经过HashMap实现的,TreeSet是经过TreeMap实现的,只不过Set用的是Map中的key;
  2. Map的key和Set都有一个共同的特性就是集合的惟一性,TreeMap更是多了一个排序的功能;
  3. hashCde和equals()是hashMap用的,由于无需排序,因此只需关注定位和惟一性便可;

    hashCode是用来计算hash值的,hash值是用来肯定hash表索引的;

    hash表中的一个索引处存放的是一张链表,因此还要经过equals()循环比较链上的每个对象才能够真正定位到键值对应的Entry;

    put时若是hash表中没有定位到,就在链表前加一个Entry,若是定位到了,则更换Entry中的value,并返回旧的value。

  4.  因为TreeMap须要排序,因此须要一个Comparator为键值进行大小比较,固然也是用Comparator进行定位的;

    Comparator能够在建立TreeMap时指定;

    若是建立时没有指定,那么就会使用key.compareTo()方法,这就要求key必须实现Comparable接口;

    TreeMap是使用Tree数据结构实现的,因此使用compare接口就能够完成定位了。

package javaEE; import java.util.Iterator; import java.util.TreeSet; /** * @author 047493 * @version 2018年8月30日 * 类说明 */ public class Test10 { public static void main(String[] args) { TreeSet<String> treeSet = new TreeSet<String>(); treeSet.add("a"); treeSet.add("c"); treeSet.add("d"); treeSet.add("b"); Iterator<String> it = treeSet.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }

运行结果:

a b c d


Map:

  • Map提供了一种映射关系,其中元素是以键值对(key-value)的形式存储的,可以实现根据key快速查找value;
  • Map中的键值对以Entry类型的对象实例形式存在;
  • key不可重复,value值可重复,每一个键最多只能映射到一个值;
  • Map支持泛型,形如:Map<K,V>;
  • Map中使用put<key,value>方法添加。

HashMap:

  • HashMap是Map的一个重要实现类,基于哈希表实现;
  • HashMap中的Entry对象是无序排列的;
  • key值和value值均可觉得null,但一个hashMap只能有一个key值为null的映射

https://www.cnblogs.com/jpwz/p/5680494.html

 

 

Hash算法:http://www.cnblogs.com/xiohao/p/4389672.html

 

map的几种遍历方法:

package javaEE; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; /** * @author 047493 * @version 2018年8月30日 * Map的遍历 */ public class Test11 { public static void main(String[] args) { String[] str = {"i love xiaomei","xiaomei love me","zhaoxin love xiaoli","xiaoli love zhaoxin"}; Map<Integer,String> map = new HashMap<>(); for(int i=0;i<str.length;i++){ map.put(i, str[i]); } //迭代 经过Map.entrySet使用迭代器遍历key和value Iterator<Entry<Integer, String>> it = map.entrySet().iterator(); while(it.hasNext()){ Map.Entry<Integer, String> entry = (Entry<Integer, String>) it.next(); Integer key = entry.getKey(); String value = entry.getValue(); System.out.println("key:"+key+",value:"+value); } //推荐使用,尤为容量大时 经过map.entrySet遍历key和value for(Map.Entry<Integer, String> entry:map.entrySet()){ int key = entry.getKey(); String value = entry.getValue(); System.out.println("key:"+key+",value:"+value); } //只能遍历出value的值,没法遍历key的值 for(String strVal:map.values()){ System.out.println("value:"+strVal); } //广泛使用,二次取值 经过Map.KeySet遍历key和value for(int keys:map.keySet()){ System.out.println("key:"+keys+",value"+map.get(keys)); } } }

 

 参考:https://www.cnblogs.com/xiohao/p/4309462.html

相关文章
相关标签/搜索