Java集合Collection简介及List与Map使用示例

目录

集合框架

Collection接口框架

Iterator接口

List接口

List遍历

List示例

Map接口

Map遍历

Map示例

Set接口

Set遍历

线程安全集合


 

Java集合(java.util.*)是一非常重要的工具包:

  • 其包含了常用的数据结构:集合、链表、队列、栈、数组、映射等;

  • 集合可分为几个重要部分:List列表、Set集合、Map映射、工具类(Iterator、Enumeration、Arrays、Collections)。

集合框架

Java集合工具包框架图如下所示:

集合接口可分为Collection与Map两大类,而Collection又分为了List和Set两类:

  • List:是一个有序队列(每个元素都有索引,从0开始),包括LinkedList、ArrayList、Vector、Stack。

  • Set:是没有重复元素的集合,包括HashSet、TreeSet。

  • Map:是一个映射接口(即key-value键值对),包括AbstractMap(抽象类)、HashMap、TreeMap和WeekHashMap等。

  • Dictionary:是一个过时的抽象类(应使用Map接口替代)。

Collection接口框架

Collection是一个接口,主要分为List和Set。

 

Collection是高度抽象出来的集合接口,它包含了集合的基本操作:添加、删除、清空、遍历(读取)、是否为空、获取大小、是否保护某元素等等。

public interface Collection<E> extends Iterable<E> {
  boolean add(E object);
  boolean addAll(Collection<? extends E> collection);
  void clear();
  boolean contains(Object object);
  boolean containsAll(Collection<?> collection);
  boolean equals(Object object);
  int hashCode();
  boolean isEmpty();
  Iterator<E> iterator();
  boolean remove(Object object);
  boolean removeAll(Collection<?> collection);
  boolean retainAll(Collection<?> collection);
  int size();
  <T> T[] toArray(T[] array);
  Object[] toArray();
};

Iterator接口

Iterator是集合的迭代器接口,用于遍历集合中的元素。
注意:若线程A在用Iterator在遍历集合时,其他线程修改了集合的内容,则线程A访问集合时会抛出ConcurrentModificationException异常。

public interface Iterator<E> {
  boolean hasNext();
  E next();
  void remove();
};

List接口

List是继承于Collection的一个接口,表示有序队列,有四个实现类:

  • ArrayList:数组队列(动态数组),随机访问高效,随机插入、删除低效;

  • LinkedList:双向队列(可用作堆栈、队列与双端队列),随机操作低效;

  • Vector:矢量队列(动态数组),线程安全的;

  • Stack:堆栈,继承于Vector;

public interface List<E> extends Collection<E> {
  // 除Collection接口外,增加以下接口
  void add(int location, E object);
  boolean addAll(int location, Collection<? extends E> collection);
  E get(int location);
  int indexOf(Object object);
  int lastIndexOf(Object object);
  ListIterator<E> listIterator(int location);
  ListIterator<E> listIterator();
  E remove(int location);
  E set(int location, E object);
  List<E> subList(int start, int end);
};

具体使用时,可:

  • 对需快速插入、删除元素,使用LinkedList;

  • 对需快速随机访问元素,使用ArrayList;

  • 单线程操作使用ArrayList,多线程操作使用Vector(更好的方式参见‘线程安全集合’部分);

List遍历

List可以有多种遍历方式:

  • 通过Iterator迭代器

Integer value = null;
Iterator iter = myList.iterator();
while (iter.hasNext()) {
  value = (Integer)iter.next();
}
  • 通过for-each循环

Integer value = null;
for (Integer e:myList) {
  value = e;
}
  • 通过索引遍历(若是LinkedList,则非常低效)

Integer value = null;
for (int i=0; i<myList.size(); i++) {
  value = (Integer)myList.get(i);        
}

List示例

List的基本操作示例(以ArrayList为例):

class MyListData{
  private Integer id;
  private String name;
  // ...
  public Integer getId() { return id; }
  public String getName() { return name; }
}

List<MyListData> myList = new ArrayList<>();

查找与遍历,可方便地使用stream实现:

MyListData findById(Integer nId){
  return myList.stream().filter(d->d.getId()==nId).findFirst().orElse(null);
}

List<String> getAllName(){
  return myList.stream().map(MyListData::getName).collect(Collectors.toList());
}

删除时,除通过remove(index)/remove(object)外(都需要先获知移除的元素);若是根据条件移除,更方便的方式是通过Iterator来实现:

MyListData removeData(Integer nId){
  Iterator<MyListData> iter=myList.Iterator();
  while(iter.hasNext()){
    MyListData d = iter.next();
    if(d.getId()==nId){
      iter.remove();
      return d;
    }
  }

  return null;
}

Map接口

Map是映射接口,存储的是键值对(Key-Value),且不能包含重复的键。主要包括以下实现类:

  • SortedMap:有序的Map;

  • NavigableMap:继承于SortedMap,支持导航函数的Map;

  • HashMap:基于‘拉链法’实现的散列表,一般用于单线程;

  • Hashtable:基于‘拉链法’实现的散列表(线程安全的),一般用于多线程中;

  • WeakHashMap:基于‘拉链法’实现的散列表,但其键是‘弱键’(不阻挡GC的垃圾回收);

  • TreeMap:有序的散列表,基于红黑树实现;

public interface Map<K,V> { 
  void clear();
  boolean containsKey(Object key);
  boolean containsValue(Object value);
  Set<Entry<K, V>> entrySet();
  boolean equals(Object object);
  V get(Object key);
  int hashCode();
  boolean isEmpty();
  Set<K> keySet();
  V put(K key, V value);
  void putAll(Map<? extends K, ? extends V> map);
  V remove(Object key);
  int size();
  Collection<V> values();
};

Map遍历

Map提供了forEach接口,以遍历元素;也能以键集、值集和键值集的形式遍历(设键String,值Integer类型):

  • 通过forEach接口:

Integer value=null;
myMap.forEach((k,v)->
{
  value=v;
});
  • 通过entrySet遍历

String key = null;
Integer value = null;
Iterator iter = myMap.entrySet().iterator();
while(iter.hasNext()) {
    Map.Entry entry = (Map.Entry)iter.next();
    key = (String)entry.getKey();
    value = (Integer)entry.getValue();
}
  • 通过keySet遍历

String key = null;
Integer value = null;
Iterator iter = myMap.keySet().iterator();
while (iter.hasNext()) {
    key = (String)iter.next();
    value = (Integer)myMap.get(key);
}
  • 通过values遍历

Integer value = null;
Collection c = myMap.values();
Iterator iter= c.iterator();
while (iter.hasNext()) {
    value = (Integer)iter.next();
}

Map示例

Map的基本操作示例(以ConcurrentHashMap为例)

class MyMapData{
  private Integer id;
  private String name;
  private int count;
  // ...
  public Integer getId() { return id; }
  public String getName() { return name; }
  public void incCount() { ++count; }
}

Map<String,MyMapData> myMap = new ConcurrentHashMap<>();

基本操作可直接通过Map接口实现:

void AddData(String key, MyMapData data){
  myMap.put(key, data);
}

MyMapData getData(String key){
  return myMap.get(key); // 不存在时,返回null
}

通过forEach可依次处理元素:

void inceaseCount(){
  myMap.forEach((k,v)-> {v.incCount();});
}

通过键集、值集和键值集的removeIf接口,可方便删除元素:

void removeByName(String strName){
  myMap.values().removeIf(v->{
    return v.getName().equals(strName);
  });
}

Set接口

Set的实现类都是基于Map来实现的,且继承于Collection接口:

  • HashSet:基于HashMap实现,不保证元素顺序,允许有null元素;

  • TreeSet:基于TreeMap实现,是一个有序集合;

Set遍历

Set可通过如下方式遍历:

  • 通过Iterator迭代器

Integer value = null;
Iterator iter = mySet.iterator();
while (iter.hasNext()) {
  value = (Integer)iter.next();
}
  • 通过for-each循环

Integer value = null;
for (Integer e:mySet) {
  value = e;
}

线程安全集合

早期的线程安全集合有Vector与HashTable,后来被ArrayList与HashMap替代,但后两者是非线程安全的,为此Collections中提供了同步的包装方法Collections.synchronizedXXX:

List<E> synArrayList = Collections.synchronizedList(new ArrayList<E>());

Set<E> synHashSet = Collections.synchronizedSet(new HashSet<E>());

Map<K,V> synHashMap = Collections.synchronizedMap(new HashMap<K,V>());

而1.8后在java.util.concurrent中新增了常用集合对应的线程安全集合,多线程环境下优先考虑。如:

  • ConcurrentHashMap:线程安全的HashMap;

  • CopyOnWriteArrayList:线程安全的ArrayList;

  • CopyOnWriteArraySet:线程安全的ArraySet;

  • 还有:ConcurrentSkipListMap、ConcurrentSkipListSet、ConcurrentLinkedQueue、ConcurrentLinkedDeque等

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值