java集合梳理

 java里面集合属于顶层接口之一,也是我们日常使用的基础。梳理下有关知识点。
java集合梳理_第1张图片
一概述
Collection接口是 (java.util.Collection)是Java集合类的顶级接口之一。所以不能直接实例化一个Collection,但是可以实例化它的一个子类,Collection接口仅仅只是定义了每个子类共享的一系列方法。看以看上图,他的子类如下:list,set,queue.而map单独一类。 set:不记录元素的保存顺序,且不允许有重复元素;   List(列表):记录元素的保持顺序,且允许有重复元素。queue: 队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。map是存放kv键值对,方便查找.
二 Collection
增加和移除元素

add()方法向Collection中增加元素,如果Collection结构改变了,作为add()方法的结果,将返回true。如果一个Set的实例中已经存在了这个元素,那么不会重复增加,这个Set实例的结构也不会发生变化。另一方面,如果在一个List上调用这个方法,而这个List已经存在了这个元素,那么这个List将有两个这个元素。remove()方法移除一个元素。如果Collection中存在这个元素并且被移除了,这个方法将返回true。如果元素不存在,将返回false。这是对单个元素的操作,对应操作多个元素还有addAll(),removeAll().retainAll()方法正好和removeAll()方法相反。不是移除所有给定参数Collection中元素,而是保留保留这些元素,移除其他的。

 检测一个Collection是否包含一个确定的元素

Collection接口有两个方法来检查一个Collection是否包含一个或多个元素。这就是 contains() containsAll() 方法。

Collection大小

你可以通过调用size()方法来检测一个Collection的大小,”Size“表示Collection中的元素个数。

迭代一个Collection

你可以迭代collection中的所有元素,collection中包含的Iterator将完成这件事情,就像下面这样:

1 Collection collection = new HashSet();
2 //... add elements to the collection
3  
4 Iterator iterator = collection.iterator();
5 while(iterator.hasNext()){
6     Object object = iterator.next();
7     //do something to object;
8 }

泛型(Generic)

The Collection interface can be generified like this:

Collection<String> stringCollection = new HashSet<String>();
三 List
因为 List 是一个接口,为了使用它,你必须实例化一个具体的实现, Collection接口的所有方法在List接口里也适用 ,你可以在下列List的实现中选择:
  1. java.util.ArrayList
  2. java.util.LinkedList
  3. java.util.Vector
  4. java.util.Stack
具体方法参见api,下面demo整理常见方法。

public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> listA = new ArrayList<String>();
//尾部追加元素
listA.add("element 0");
listA.add("element 1");
listA.add("element 2");
//头部插入元素
listA.add(0, "element");
//追加指定collection多个元素到尾部
listA.addAll(new ArrayList());
//打印长度
System.out.println(listA.size());
// 如果列表包含指定的元素,则返回true
listA.contains("test");
//移除元素
listA.remove(0);
listA.remove("element 1");
//获取指定位置元素
listA.get(0);
// 用指定元素替换列表中指定位置的元素
listA.set(0, "set");
// 返回列表中首次出现指定元素的索引,如果列表不包含此元素,则返回 -1
listA.indexOf("lwc");
//access via new for-loop
for(Object object : listA) {
String element = (String) object;
System.out.println(element);
}
//清空
listA.clear();
System.out.println(listA.size());
}


运行结果:
4
set
element 2
0
充:关于ArrayList和LinkedList
ArrayList依赖于数组实现的,初始长度为10的Object[],并且可随需要而增加的动态数组。当元素超过10,那么ArrayList底层会新生成一个数组,长度为原来的1.5倍+1, 然后将原数组内容复制到新数组中,并且后续增加的内容会放到新数组中, 当新数组无法容纳增加的元素,重复该过程  
ArrayList对随机访问性能很好,但进行大量插入,删除操作,性能很差, 因为操作之后后续元素需要移动  
  LinkedList功能与ArrayList,Vector相同,内部是依赖双链表实现的, 因此有很好的插入和删除性能,但随机访问元素的性能很差。 LinkedList底层Entry结构  
         Entry{  
            Entry previous;  
            Object element;  
            Entry next;  
        }  
        其中element就是我们添加的元素,最后将生成的Entry对象加入到链表中  。
使用场景:插入和删除操作时,采用LinkedList好,搜索时,采用ArrayList好  。
四 set
  set是Collection的子接口,不包含重复元素,最多包含一个null,元素没有顺序 。实现类如下:
  • java.util.EnumSet
  • java.util.HashSet
  • java.util.LinkedHashSet
  • java.util.TreeSet
  HashSet是基于hashmap实现的,它不保证有序性。 HashSet中是否存在一个对象是通过equals()和hashCode()协同判断  。
LinkedHashSet是Ordered,采用双链表实现的,有固定顺序,也就是插入顺序,LinkedHashSet底层是使用LinkedHashMap实现的 。

SortedSet接口

保证迭代器按照元素递增顺序遍历的集合,可以按照元素的自然顺序进行排序  

常用方法  
    Object first()  
         返回此有序集合中当前第一个(最小的)元素  
    Object last()  
        返回此有序集合中最后一个(最大的)元素  
    SortedSet headSet(Object toElement)  
        返回此有序集合的部分视图,其元素严格小于toElement  
    SortedSet tailSet(Object fromElement)  
        返回此有序集合的部分视图,其元素大于或等于fromElement  
    SortedSet subSet(Object fromElement,Object toElement)  
        返回此有序集合的部分视图,元素范围从fromElement(包括)到toElement(不包括)  
    Comparator comparator()  
        返回与此有序集合关联的比较器,如果使用元素的自然顺序,则返回 null  
 TreeSet
TreeSet是SortedSet接口的实现,元素不论以什么元素插入,在遍历的时候,都会以天然顺序遍历  
TreeSet底层是使用TreeMap实现的  
构造方法  
    public TreeSet()  
    public TreeSet(SortedSet s)    
    public TreeSet(int initialCapacity)  
    public TreeSet(Comparator<? super E>)  
    public TreeSet(Collection c)  
因为TreeSet是带排序的, 所以想要为TreeSet增加自定义类型,必须指定排序规则。举例:
Comparator comparator = new MyComparator();
SortedSet setB = new TreeSet(comparator);
 五 Map
map是存放key-value键值对元素的,它不是collection的子接口。
Map是接口,他的实现类如下:
  • java.util.HashMap
  • java.util.Hashtable
  • java.util.EnumMap
  • java.util.IdentityHashMap
  • java.util.LinkedHashMap
  • java.util.Properties
  • java.util.TreeMap
  • java.util.WeakHashMap
HashMap存放key,vlaue.它不是有序的。也不是线程安全的。 Hashtable是线程安全的。
TreeMap存放key,vlaue,它是有序的,基于红黑树(Red-Black tree)的 NavigableMap 实现,该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
java集合梳理_第2张图片
下面是treemap的例子
java集合梳理_第3张图片
 treemap运行结果如下:
********treemap************
key:3;value:ff
key:4;value:dd
key:5;value:cc
key:6;value:gg
**********treemap by value***********
5:cc
4:dd
3:ff
6:gg

六queue
  队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。 在队列这种数据结构中,最先插入的元素将是最先被删除的元素;反之最后插入的元素将是最后被删除的元素,因此队列又称为“先进先出”(FIFO—first in first out)的线性表。

add                增加一个元索                                         如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove      移除并返回队列头部的元素       如果队列为空,则抛出一个NoSuchElementException异常
element   返回队列头部的元素                         如果队列为空,则抛出一个NoSuchElementException异常
offer              添加一个元素并返回true              如果队列已满,则返回false
poll                  移除并返问队列头部的元素        如果队列为空,则返回null
peek              返回队列头部的元素                         如果队列为空,则返回null
put                  添加一个元素                                           如果队列满,则阻塞
take                移除并返回队列头部的元素         如果队列为空,则阻塞
上面可以看出来,为避免抛出异常,要 使用offer()来加入元素,使用poll()来获取并移出元素。
java.ulil.concurrent包提供了阻塞队列的4个变种。 LinkedBlockingQueue 它是基于链表的队列。 ArrayBlockingQueue 基于数组的阻塞循环队 列。 PriorityBlockingQueue 是一个带优先级的 队列,而不是先进先出队列。元素按优先级顺序被移除,该队列也没有上限。 DelayQueue (基于PriorityQueue来实现的)是一个存放Delayed 元素的无界阻塞队列,只有在延迟期满时才能从中提取元素。

package com.cplatform.sampling.util;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ArrayBQTest {

// 创建等待队列
BlockingQueue bqueue = new ArrayBlockingQueue(20);
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
ArrayBQTest test =new ArrayBQTest();
// TODO Auto-generated method stubs
ArrayBlockingQueue queue = new ArrayBlockingQueue(2);

Thread pthread = new Thread(test.new producerThread(queue));
pthread.start();

Thread c1thread = new Thread(test.new ConsumerThread(queue));
Thread c2thread = new Thread(test.new ConsumerThread(queue));
c1thread.start();
c2thread.start();
Thread.sleep(5000);
System.out.println("****p done****");
pthread.stop();
Thread.sleep(4000);
c1thread.stop();
c2thread.stop();
System.out.println("****over****");
}

class producerThread implements Runnable {

private ArrayBlockingQueue queue;

public producerThread(ArrayBlockingQueue queue){
this.queue =queue;
}

public void run() {
while(true){
try {
String temp = System.currentTimeMillis()+"";
queue.put(temp);
Thread.sleep(1*1000);

System.out.println(Thread.currentThread().getName() + "正在生产。。。"+temp);
} catch (InterruptedException e) {

}
}
}
}

class ConsumerThread implements Runnable {

private ArrayBlockingQueue queue;

public ConsumerThread(ArrayBlockingQueue queue){
this.queue =queue;
}

public void run() {
while(true){
try {
String res=(String) queue.poll();
Thread.sleep(2*1000);

System.out.println(Thread.currentThread().getName() + "正在消费。。。"+res);
} catch (InterruptedException e) {

}
}
}
}
}


 
上面demo是基于ArrayBlockingQueue实现的生产者、消费者模式。根据业务可以调整为线程池。另外,为了演示用了stop。有时候interrupt也停不下来,应该采用volite修饰的标记符去判断,安全的停止。
本篇就先整理到这里。尤其要注意多线程并发的情况下,容器的性能及安全性问题。
参考:
http://www.cnblogs.com/end/archive/2012/10/25/2738493.html
http://blog.csdn.net/itlwc/article/details/10148321

你可能感兴趣的:(java集合梳理)