浅谈Java集合

来源:互联网 发布:南风知我意1免费阅读 编辑:程序博客网 时间:2024/06/07 04:02

浅谈Java集合(个人学习时总结)

Java集合描述:
Collection和Map是Java集合框架的根接口。
Collection的子接口有:Set、Queue、List
Set的子类、接口都是线程不安全的,如果想要解决这个问题应作如下处理:
SortedSet s = Collection.synchronizedSortedSet(new TreeSet(…));
实现Map的类有:HashMap、Hashtable。EnumMap、IdentityHashMap、SortedMap、WeakHashMap
常用的有:HashSet、TreeSet、ArrayList、ArrayDeque、LinkedList、HashMap、TreeMap
HashMap和Hashtable比较:前者线程不安全,因为key和Value允许为空,后者线程安全,key和value不允许为空
Set中的值不能重复,因为他是无序的,如果add两个相同的元素,那么第二次的返回值为false,相当于数学中的集合。
接口Collection继承了Iterable接口,Iterable中定义了Interator
Iterator接口中的方法:hasNext(),next(),remove()


Set集合:
HashSet:
有很好的存取和查找性能。
特点:
1.不能保证元素的顺序;
2.HashSet不是同步的,如果多个线程同时访问一个HashSet,必须通过代码来保证其同步;
3.集合元素可以是null
HashSet存入元素值时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值然后根据此值决定在HashSet中的位置。
HashSet判断两个对象相等的标准是通过equals()比较相等,并且所对应的hashCode值也相等。
为防止出现hashCode相同equals不同,我们要重写hashCode(),要求如下:
在程序运行过程中,同一个对象多次调用hashCode()方法应该返回相同的值;
当两个对象通过equals()方法比较返回true时,这两个对象的hashCode()应该返回相等的值
对象中用作equals()方法比较标准的实例变量,都应该用于计算hashCode值
LinkedHashSet:
能够不改变输入的次序,对里面的值进行输出。
这样做降低了性能。
TreeSet:是SortedSet的子类
自然排序:根据Unicode码或者数值大小,true大于false
定制排序:o1>o2返回+ o1

TreeSet例子

import java.util.*;public class Main {    public static void main(String[] args) {        TreeSet ts = new TreeSet(new Comparator() {            @Override            public int compare(Object o1, Object o2) {                Integer a = (Integer)o1;                Integer b = (Integer)o2;                return a>b?-1:a<b?1:0;            }        });        ts.add(13);        ts.add(15);        ts.add(19);        ts.add(11);        ts.add(10);        System.out.println(ts);    }}

List集合:

  • List集合代表一个元素有序,可重复访问的集合,在集合中每个元素都有其对应的顺序索引。
  • List新增的方法:
    • void add(int index,Object element):将元素element插入到LIist集合的index处;
    • boolean add(index,Collection c):将集合c插入到list的index索引位置 [a,[1,2,3],b]
    • Object get(int index):得到索引处的值
    • int indexOf(Object o): 返回对象o第一次出现的索引值
    • int lastIndexOf(Object o):返回对象o最后一次出现的索引值
    • remove(int index)删除 set(int index,Object o) 替换
  • Java8中新加removeAl(UnaryOperator operator) 根据operator指定的计算规则重新设置所有元素
    sort(Comparator c) 根据c重新排序
  • List中提供了一个特殊的listIterator()方法,此方法返回一个ListIterator,此接口下还有
    hasPrevious();pervious();add(E e);三个新增方法
  • Iterator和ListIterator的区别就在于后者多出的方法,Iterator不允许在遍历时修改Set中的值,而List则允许。
    并且List和调用hasPrevious();pervious()操作上一个元素
  • ArrayList和Vector实现类:
    这两个类都实现了List接口,实现了List中的方法。
    Vector是一个比较老的类,里面有一些很古老的方法,方法与ArrayList的相似,只是名字不同。
    还有就是,Vector中的方法都是线程安全的,ArraysList都是线程不安全的,
    最后一点就是,Stack(栈)继承了Vector。Stack也是一个很古老的类。性能太差。后边一般用ArrayDeque代替

Queue集合

  • Queue集合:用于模拟队列这样的数据结构,先进先出。
  • Queue定义了以下几个方法:
    void add(Object e)添加指定元素到队尾
    Object element()获取队头元素,但是不删除
    boolean offer(Object e)将指定元素插入到队尾,使用有容量限制的队列时,性能比add好
    Object peek()获取对头元素,不删除,如果为空队列,返回null
    Object poll()获取队头元素并删除,若为空队列,返回hull
    Object remove()获取对头元素,并删除
  • Queue接口有一个PriorityQueue(优先队列)实现类,还有Deque(双端队列)的接口,可以当做栈,此接口下有两个实现类(ArrayDeque和LinkedList)
  • PriorityQueue实现类:
    这个类保存队列元素并不是按照进入队列的先后顺序,
    而是自行排序,不能保证保存时是顺序的,但是能保证弹出队列时是顺序的。违反了队列的“先进先出”原则
    PriorityQueue不允许元素为null,因为要对元素进行排序。
    PriorityQueue有两种排序方式:自然排序和定制排序

例子:自然排序

PriorityQueue中元素必须实现Comparable接口,并重写compareTo方法。否则可能出现ClassCastException

import java.util.Iterator;import java.util.PriorityQueue;public class Main{    public static void main(String[] args) {        PriorityQueue pq = new PriorityQueue();        pq.offer(new A(10));        pq.offer(new A(20));        pq.offer(new A(14));        pq.offer(new A(111));        pq.offer(new A(11));        Iterator it = pq.iterator();        while(it.hasNext()){            //输出10 11 14 111 20 由此可见,无法保证存储的顺序性            System.out.print(((A)(it.next())).getA()+" ");        }        System.out.println();        while(pq.size()>0){            //输出10 11 14 20 111 由此可见,可以保证出队列的顺序性            System.out.print(((A)(pq.poll())).getA()+" ");        }    }}class A implements Comparable<A>{    public int a;    public A(int a){        this.a = a;    }    public int getA(){        return a;    }    //实现Comparable接口,重写compareTo方法    @Override    public int compareTo(A a) {        return this.a-a.a;    }}

例子:定制排序

创建PriorityQueue队列时,传入一个Comparator对象,该对象对队列中的所有元素进行排序。

import java.util.Comparator;import java.util.Iterator;import java.util.PriorityQueue;public class Main{    public static void main(String[] args) {        //PriorityQueue的构造器有点特殊,前面的int代表创建当前队列的大小,        //后面的Comparator对compare进行重写        PriorityQueue pq = new PriorityQueue(7,new Comparator() {            @Override            public int compare(Object o1, Object o2) {                A a1 =(A)o1;                A a2 =(A)o2;                return a1.getNumber()-a2.getNumber();            }        });        pq.offer(new A(9));        pq.offer(new A(1));        pq.offer(new A(3));        pq.offer(new A(2));        pq.offer(new A(8));        Iterator it = pq.iterator();        while(it.hasNext()){            //输出1 2 3 9 8            System.out.print(((A)(it.next())).getNumber()+" ");        }        System.out.println();        while(pq.size()>0){            //输出1 2 3 8 9            System.out.print(((A)(pq.poll())).getNumber()+" ");        }    }}class A{    private int number;    public A(){    }    public A(int number){        this.number = number;    }    public int getNumber(){        return number;    }}

Deque接口与ArrayDeque实现类:

  • Deque接口是接口Queue的子接口,它代表一个双端队列。
  • ArrayDeque实现了Deque接口,它是基于数组实现的双端队列,
  • 创建ArrayDeque时可指定队列的长度,如果不指定,默认为16.
  • 如果程序中要使用栈,那么推荐使用ArrayDeque,因为Stack是一个很古老的类。

LinkedList实现类:

  • LinkedList类是List接口的实现类,这意味着他是一个List集合,可以根据索引来随机访问集合中的元素。
  • LinkedList类还实现了Deque接口,可以被当做双向队列使用,因此,即可以当做栈也可以当做队列使用。
  • LinkedList与ArrayList和ArrayDeque的实现机制完全不同,ArrayList和ArrayDeque以数组的形式保存元素,因此随机访问时有较好的性能;而LinkedList内部以链表的形式来保存集合中的元素,因此随机访问时性能较差,但是插入删除元素时性能较出色
    注意:用随机访问ArrayList和ArrayDeque要比用Iterator访问性能高。因为随机访问会被影射城市族元素的访问。

Map集合:

  • Map用于保存具有映射关系的数据,因此Map里保存key和value,key和value都可以是任何引用类型数据。
  • Map中的key不允许重复。
  • Set和Map之间的关系非常密切。
  • Map接口中创建了Entry内部类,来实现key-value键值对
  • Map中的方法
    • void clear()
    • boolean containsKey(Object key)
    • boolean containsValue(Object value)
    • Set entrySet() 返回Mao中包含的key-value对所组成的Set集合,每个集合都是Map.Entry对象
    • Object get(Object key)
    • boolean isEmpty()
    • Set keySet() 返回Map中所有key组成的Set集合
    • Object put(Object key,Object value)
    • void putAll(Map m)
    • Object remove(Object key)
    • boolean remove(Object key,Object value) Java8中新增方法
    • int size()
    • Collection values() 返回Map里所有value组成的Collection
  • 内部接口Entry中的方法:
    • Object getKey()
    • Object getValue()
    • Object setValue(V value)

例子:Map

import java.util.*;public class Main {    public static void main(String[] args) {        Map map = new HashMap();        map.put(1,2);        map.put(2,3);        map.put(3,4);        //通过Map接口中的entrySet返回Set(每个集合元素都是Entry)的特点。        //将Set转换成Entry,然后就可以调用内部接口Entry的方法了        Set set = map.entrySet();        Iterator it = set.iterator();        while(it.hasNext()){            Map.Entry me = (Map.Entry) it.next();            System.out.println(me.getKey()+"--"+me.getValue());            //System.out.println(it.next());//键值对1=2 2=3 3=4        }    }}

HashMap和Hashtable实现类:

  • HashMap和Hashtable类似于ArrayList和Vector,Hashtable是一个很古老的类。

      HashMap和Hashtable区别:       ·Hashtable是一个线程安全的Map实现类,但是HashMap是一个线程不安全的Map实现类;        ·Hashtable不允许key和value为null,如果为空,产生空指针异常;HashMap允许null作为key或value
  • HashMap只允许有一对key为空的数据,允许有无数个value为null的数据
  • 判断两个key相等的标准是:两个key通过equals()比较为true,并且hashCode也相等
  • 判断两个value相等的标准是:两个value通过equals()比较为true

  • 当使用自定义类最为key时,如果重写equals()和hashCode()方法,保证都相等。

LinkedHashMap是HashMap的子类:

  • HashMap的缺点就是,不能维护元素的插入顺序。
  • LinkedHashMap能维护元素的插入顺序,但是降低了性能。

Properties类是Hashtable是子类:

  • 能将键值对保存到文件中,到时候在加载。

**

SortedMap接口和TreeMap实现类:

**

TreeMap和TreeSet一样,也能对key和value进行排序,分为自然排序和定制排序:

  • 自然排序:所有key实现Comparable接口,重写compareTo方法。
  • 定制排序:创建TreeMap时,传入一个Comparator对象。

例子:TreeMap

import java.util.*;public class Main {    public static void main(String[] args) {        TreeMap tm = new TreeMap();        tm.put(new K(16), "你好");        tm.put(new K(12), "你好");        tm.put(new K(15), "你好");        tm.put(new K(1123), "你好");        tm.put(new K(13), "你好");        System.out.println(tm);    }}class K implements Comparable {    private int key;    public K(int key) {        this.key = key;    }    public String toString() {        return "key值是:" + key;    }    @Override    public int compareTo(Object o) {        K k = (K) o;        return key > k.key ? -1 : key < k.key ? 1 : 0;    }}

WeakHashMap实现类:

   用法与HashMap相似,区别在于HashMap中的key保留了对实际对象的强引用,意味着,只要该HashMap对象不被销毁,该HashMa 的所有key所引用的对象就不会被垃圾回收,HashMaori也不会自动删除这些key所对应的key-value对;但WeakHashMaori的key只保留了对实际对象的弱引用,这意味着如果WeakHashMap对象的key所引用的对象没有被其他强引用变量所引用,则这些key所引用的对象可能被垃圾回收,WeakHashMaori对象的key所引用的对象没有自动删除这些key所对应的key-value对。

IdentityHashMap实现类:

    在IdentityHashMap中,当且仅当两个key严格相等(key1==key2)时,IdentityHashMap带认为两个key相等对于普通的HashMap而言,只要key1.equals(key2)返回true,且它们的hashCode值相等即可。**例子:IdentityHashMap** 
import java.util.*;public class Main {    public static void main(String[] args) {        IdentityHashMap ihm = new IdentityHashMap();        ihm.put(new String("语文"), "语文1");        ihm.put(new String("语文"), "语文2");        ihm.put("Java", "Java1");        ihm.put("Java", "Java2");        //输出{Java=Java2, 语文=语文1, 语文=语文2}        System.out.println(ihm);    }}

EnumMap实现类:

 **key不能为null value可以为null。**

例子:EnumMap

import java.util.*;public class Main {    public static void main(String[] args) {        EnumMap em = new EnumMap(Season1.class);        em.put(Season1.FALL, "太爽了");        em.put(Season1.SUMMER, "太热了");        em.put(Season1.SPRING, null);        //输出{SPRING=null, SUMMER=太热了, FALL=太爽了}        System.out.println(em);    }}enum Season1 {    SPRING, SUMMER, FALL, WINTER;}

操作集合的工具类:Collections

  • Collections工具类提供大量方法对集合元素进项排序,查询,和修改等操作,还提供了将集合对象设置为可不变、对集合对象实现同步控制等方法。
  • 排序操作:
    void reverse(List list):反转指定List集合中元素的顺序。
    void shuffle(List list ):洗牌操作
    void sort(List list):升序排序
    void sort(List list,Comparator c):根据Comparator产生的顺序排序
    void swap(LIst list,int i,int j):将指定的List集合中的i处元素和j处元素进行交换
    void rotate(List list,int distance):distance 为正,将后distance移到前面,为负将前distance移到后面查找,替换:…..

  • 同步控制:Collections中提供了synchronizedCollectionXxx()方法可以将指定集合包装成线程同步的集合,从而解决多线程并发访问集合时的线程安全问题

例子:Collection

import java.util.*;public class Main {    public static void main(String[] args) {        Collection c = Collections.synchronizedCollection(new ArrayList());        List list = Collections.synchronizedList(new ArrayList());        Set s = Collections.synchronizedSet(new HashSet());        Map m = Collections.synchronizedMap(new HashMap());        //这样就获得了线程安全的集合对象    }}

设置不可变集合:

  • emptyXxx():返回一个空的、不可变的集合对象。List、SortedSet、Set、Map、SortedMap等
  • singletonXxx():返回一个只包含指定对象(只有一个或一项元素)的、不可变集合对象。List、Map
  • unmodifiableXxx():返回指定集合对象的不可变视图。List、SortedSet、Set、Map、SortedMap等
1 0
原创粉丝点击