集合使用的总结

  集合在程序设计中有着举足轻重的地位,集合的操作无非就是增删遍历等基本的动作,所以就以上基本操作,本文结合案例及代码分别加以说明。
  首先,集合从大的方向来分,分为单列集合(Collection)和双列集合(Map)。简单地说,就是Collection中存储的是单一的内容,而Map集合中存储的是键和值,就像看到的表格,Collection只有一列,所以叫单列集合,而Map有两列,Map的一个元素分为两部分,一列存键,一列存值,并且键唯一不能重复。
  下来,先看看Collection集合。
  Collection
      |---List  元素不唯一,存储和了取出顺序一致。
          |---ArrayList     底层数据结构是数组。特点:查询快,增删慢,线程不安全,高效。
          |---Vector   底层数据结构是数组。特点:线程安全,效率不如ArrayList,被ArrayList取代。
          |---LinkedList  底层数据结构是链接列表。特点:增删快,查询慢。线程不安全,高效。
      |---Set  元素唯一,但存储和取出顺序不一致。
          |---HashSet  底层数据结构是哈希表。特点:依赖于哈希表。
                |---LinkedHashSet  底层数据结构是哈希表和链接列表。特点:元素唯一,有序。
          |---TreeSet   底层是二叉树。特点:元素可排序。
  整个Collection体系,除最底层的是具体实现类,其他都是接口,只定义一些基本的功能,而具体实现都是在类中。添加删除元素相对简单,这里就一笔带过。而对于遍历而言,Collection提供迭代器遍历,而增强for的遍历其实底层也是靠迭代器实现,暂且认为这是两种方式,对于List集合还可以使用普通for循环配合get()方法进行遍历。
  1、针对List集合编写以下测试代码:

package cn.io;

import java.util.ArrayList;
import java.util.Iterator;

public class ListDemo {
    public static void main(String[] args) {
        //创建集合对象,同理这里可以用Vector和LinkedList替换ArrayList。
        ArrayList<String> arrayList = new ArrayList<>();
        //向集合添加元素,共三项。
        arrayList.add("Hello");
        arrayList.add("World");
        arrayList.add("Jason");
        //删除添加到集合的Jason,结果中不存在。
        arrayList.remove("Jason");
        //着重看一下遍历,三种方式完成。
        //迭代器遍历
        Iterator<String> it = arrayList.iterator();
        while (it.hasNext()) {
            String s = it.next();
            System.out.println(s);
        }
        //这里再加上使用普通for循环配合迭代器的操作。
        for (Iterator<String> iterator = arrayList.iterator(); iterator.hasNext();) {
            String s = iterator.next();
            System.out.println(s);
        }
        //遍历方式二,使用增强for对集合进行遍历。
        for(String s : arrayList){
            System.out.println(s);
        }
        //遍历方式三,使用普通for循环配合get()方法遍历。
        for (int i = 0; i < arrayList.size(); i++) {
            String s = arrayList.get(i);
            System.out.println(s);
        }
        //同理,对于Vector和LinkedList的操作都是一样,只是在定义ArrayList的时候换成对应的集合就行。
    }
}

  对于Set集合,JDK没有提供对应的get()方法,所以遍历就不能通过普通for循环配合get()方法来遍历。
  2、Set集合的操作示例代码:
  Set集合的HashSet操作示例可参考 集合HashSet的使用 中的详细说明。
  Set的集合还有另一个就是TreeSet,这个集合的使用请参考 集合TreeSet的使用 中示例。
  接下来就是LinkedHashSet,HashSet的子类。这个集合比较特殊,底层结构是链表和哈希表。虽然结构特殊,但是使用起来也没有过分的地方,就把它看成HashSet使用吧,代码示例可参考HashSet,不同的是,它颠覆了Set集合的无序,它的有序靠链表结构保证,唯一靠哈希表结构。

  集合Collection总结:List集合有三种遍历方式,Set集合有两种遍历方式。

  说完了Collection集合,接下来就是Map集合了。乍一看Map集合的格式就有点怕怕的感觉,其实也蛮简单,先看看Map集合的构架。
  Map
    |---HashMap  底层数据结构是哈希表。
          |---LinkedHashMap  底层数据结构是哈希表和链表。
    |---Hashtable  底层数据结构是哈希表。
    |---TreeMap    底层数据结构是二叉树。
  集合Map的定义格式:Map<K k,V v> map = new HashMap<>();因为Map是接口不能用来创建对象,所以只能使用实现了该接口的类来创建对象,这种写法又是面向对象的第三个特点--多态。
  1、看看HashMap集合的代码

package cn.io;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class HashMapDemo {
    public static void main(String[] args) {
        //创建HashMap集合对象
        HashMap<String, String> hashMap = new HashMap<>();
        //添加对象到HashMap集合
        hashMap.put("柳兰歌", "财务");
        hashMap.put("冷文卿", "业务");
        hashMap.put("李念儿", "开发");
        hashMap.put("柳婵诗", "市场");
        hashMap.put("景茵梦", "工程");
        //重复添加一条记录
        hashMap.put("景茵梦", "设计");
        //遍历方式一,先获取键的集合,再根据键找对应的值。
        Set<String> set1 = hashMap.keySet();
        for(String emp : set1){
            System.out.println("职员:" + emp + "   部门:" + hashMap.get(emp));
        }
        //遍历方式二,先获取键值对对象的集合,再根据键值对对象找对应的键和值。
        Set<Map.Entry<String, String>> set2 = hashMap.entrySet();
        for (Map.Entry<String, String> entry : set2) {
            System.out.println("职员:" + entry.getKey() + "   部门:" + entry.getValue());
        }
        //从程序结果看到最后一条记录并没有添加到集合,因为Map的键不重复,
        //所以当第六条记录添加时发现键已存在,就用新值替换掉旧值,最后结果是  “职员:景茵梦   部门:设计”
    }
}

  应特别注意:V put(K key, V value),它是将指定的值与此映射中的指定键关联。
    也就是说,如果键不存在时,就将键和值存入,如果键已存在,则会用新值替换旧值并将旧值返回。但如果是存储自定义对象,刚需要在类中重写hashCode()和equals()方法才能保证键的唯一。
  2、再下来就是TreeMap,TreeMap的唯一和排序需依赖于实现Comparable或Comparator接口。

package cn.io;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;

public class TreeMapDemo {
    public static void main(String[] args) {
        TreeMap<String, Integer> treeMap = new TreeMap<>(new Comparator<String>() {
            @Override
            public int compare(String arg0, String arg1) {
                int num1 = arg0.length() - arg1.length();
                int num2 = num1 == 0 ? arg0.compareTo(arg1) : num1;
                return num2;
            }
        });
        treeMap.put("Roxette", 20);
        treeMap.put("Sarah", 21);
        treeMap.put("Carpenters", 23);
        treeMap.put("Britney", 22);
        treeMap.put("Beyonce", 19);
        //重复添加一条记录
        treeMap.put("Beyonce", 21);
        Set<String> set1 = treeMap.keySet();
        for(String key : set1){
            System.out.println("Name:" + key + "   Age:" + treeMap.get(key));
        }
    }
}

  示例中第六条依然会替换原来的值。TreeMap的唯一及排序都是针对键的操作,如果是自定义类需要实现Comparable接口或Comparator接口。虽然String类已经实现了Comparable接口,但是这里实现了Comparator接口,以此为准。
  
        如果是哈希表结构,就需要重写hashCode()和equals()。
        如果是二叉树结构,就需实现Comparable或Comparator。

原文地址:https://www.cnblogs.com/magics/p/3644255.html