黑马程序员——集合

来源:互联网 发布:网络舆情情况汇报 编辑:程序博客网 时间:2024/05/17 06:33

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

一、概述

  对象用于封装特有数据,对象多了需要存储。如果对象的个数不确定,就使用集合容器进行存储。其长度可变,不可以存储基本数据类型值。

1.集合框架

  集合容器因为内部的数据结构不同,有多种具体容器。不断的向上抽取,就形成了集合框架。如图为Collection的简化层次结构:
  

2.Colletion接口

  Colletion接口常用方法:
  1) 添加: add, addAll
  2) 删除: remove, removeAll, clear
  3) 判断: contains, containsAll, isEmpty
  4) 获取: size, iterator
  迭代器(Iterator)是对所有的Collection容器进行元素取出的公共接口。
  Iterator iterator = iterable.iterator();
  iterator.hasNext(); iterator.next();
  5) 其他: retainAll, toArray

/* Collection常用方法示例*/import java.util.*;public class CollectionDemo {    public static void main(String[] args){        Collection coll = new ArrayList();        show(coll);        System.out.println("-------------------");        Collection c1 = new ArrayList();        Collection c2 = new ArrayList();        show (c1, c2);    }    public static void show(Collection coll){        //添加 add        coll.add("abc1");//boolean add(Object obj);        coll.add("abc2");        coll.add("abc3");        System.out.println("coll: "+coll);        //删除 remove        coll.remove("abc2");//boolean remove(Object obj);        System.out.println("coll: "+coll);        //清空 clear        //coll.clear();        //判断 isEmpty  contains        System.out.println(coll.isEmpty()); //boolean isEmpty();        System.out.println(coll.contains("abc1")); //boolean contains(Object obj);        //获取 size        System.out.println(coll.size()); //int size();    }    public static void show(Collection c1, Collection c2){        //添加 addAll        c1.add("abc1");        c1.add("abc2");        c1.add("abc3");        c1.add("abc4");        c2.add("abc2");        c2.add("abc6");        c2.add("abc7");        System.out.println("c1: "+c1);        System.out.println("c2: "+c2);        c1.addAll(c2); //boolean addAll(Collection coll);        //删除 removeAll        boolean a = c1.removeAll(c2); //boolean removeAll(Collection coll);        System.out.println("removeAll: "+a);        //判断 containsAll        boolean b = c1.containsAll(c2);        System.out.println("containsAll: "+b); //boolean containsAll(Collection coll);        //交集 retainAll        boolean c = c1.retainAll(c2); //boolean retainAll(Collection coll);        System.out.println("retain: "+c1);    }}
/* * 迭代器示例 */import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;public class IteratorDemo {    public static void main(String[] args){        Collection coll = new ArrayList();        coll.add("abc1");        coll.add("abc2");        coll.add("abc3");        coll.add("abc4");        System.out.println(coll);        //调用集合中的迭代器方法,获取迭代器对象        Iterator it1 = coll.iterator();        while(it1. hasNext()){            System.out.println(it1.next());        }        //for循环结束,Iterator变量内存释放,更高效        for(Iterator it2 = coll.iterator(); it2.hasNext();){            System.out.println(it2.next());        }    }}

二、List

  Collection接口的两个子接口:
  a.List: 记录元素的保存顺序,且允许有重复元素
  b.Set: 不记录元素的保存顺序,且不允许有重复元素
  List接口: 线性表(linear list)
  List接口常用方法:
  1) 添加: add, addAll
  2) 删除: remove
  3) 修改: set
  4) 获取: get, indexOf, lastIndexOf, subList

/* * List集合常用方法示例 */import java.util.ArrayList;import java.util.List;import java.util.Iterator;import java.util.ListIterator;public class ListDemo {    public static void main(String[] args){        List list = new ArrayList();        show(list);    }    public static void show(List list){        //添加        list.add("abc1"); //void add(index,element)        list.add("abc3");        list.add(1,"abc2");        System.out.println(list);        //删除        System.out.println("remove: "+list.remove(2)); //Object remove(index);        //修改        System.out.println("set: "+list.set(1,"abc8")); //Object set(index,element);        //获取        System.out.println(list.get(1)); //Object get(index);        System.out.println(list.indexOf("abc2")); //int indexOf(object);        System.out.println(list.lastIndexOf("abc8")); //int lastIndexOf(object);        System.out.println("sublist: "+list.subList(1, 2)); //List subList(fromIndex,toIndex);        //迭代器        Iterator it = list.iterator();        for (int x = 0; x < list.size(); x++){            System.out.println("get:"+list.get(x));        }    }}

  注:在迭代器过程中,不要使用集合操作元素,容易出现异常: java.util.ConcurrentModificationException。可以使用Iterator接口的子接口ListIterator来完成在迭代中对元素进行更多的操作,如下示例。

import java.util.ArrayList;import java.util.List;import java.util.ListIterator;public class ListIteratorDemo {    public static void main(String[] args){        List list = new ArrayList();        list.add("abc1");        list.add("abc2");        list.add("abc3");        System.out.println("list: " + list);        //只有List集合具有这种在迭代过程中完成对元素增删改查的特有的迭代器        ListIterator it = list.listIterator();        while(it.hasNext()){            Object obj = it.next();            if(obj.equals("abc3"))                it.add("abc9");        }        System.out.println("hasNext: "+it.hasNext());        System.out.println("hasPrevious: "+it.hasPrevious());        while(it.hasPrevious()){            System.out.println("previous: "+it.previous());        }        System.out.println("list: "+list);    }}

  List接口的主要实现类是 ArrayList. LinkedList, 以及早期的Vector

List实现类 内部数据结构 同步否 增删速度 查询速度 ArrayList 数组 否 慢 快 LinkedList 链表 否 快 慢 Vector 数组 是 慢 慢
LinkedList方法 旧方法 jdk1.6版本后新方法 添加 addFirst(); addLast(); offerFirst(); offerLast(); 获取不移除 getFirst(); getLast(); 如果链表为空,抛出NoSuchElementException peekFirst(); peekLast();如果链表为空,返回null。 获取并移除 removeFirst(); removeLast(); pollFirst(); pollLast(); 方法类型 可抛出异类的 返回元素的 Insert(插入) add(e) offer(e) Remove(移除) remove() poll() Examine(检查) element() peek()

两种重要的线性数据结构
  1)栈 Stack
  遵循“后进先出”(Last In First Out, LIFO)原则
  包含三个方法
  public Object push(Object item):将指定对象压入栈中。
  Public Object pop():将 栈最上面的元素从栈中取出,并返回这个对象。
  public boolean empty():判断栈中没有对象元素。
  2)队列 Queue
  遵循“先进先出”(First In First Out,FIFO)原则
  固定在一端输入数据(称为入队),另一端输出数据(称为出队)。

/* * 模拟队列 */import java.util.LinkedList;class Queue{    private LinkedList link;    public Queue(){        link = new LinkedList();    }    //入队    public void enQueue(Object obj){        link.addLast(obj);    }    //出队    public Object outQueue(){        return link.removeFirst();    }    //判断队列是否为空    public boolean isNull(){        return link.isEmpty();    }}public class QueueDemo {    public static void main(String[] args){        Queue d = new Queue();        d.enQueue("abc1");        d.enQueue("abc2");        d.enQueue("abc3");        d.enQueue("abc4");        while(!d.isNull())            System.out.println(d.outQueue());    }}

三、Set

  Set接口中的方法和Collection一致。
  1) HashSet:内部数据结构是哈希表,是不同步的。
  2) TreeSet:可以对Set集合中的元素进行排序,是不同步的。其底层是用TreeMap来实现的
  Set中对象不重复,即:hashCode()不等。如果hashCode()相等,再看equals或==是否为false。

/* *ArrayList是无序列表,若要有序列表,则用LinkedHashSet  */import java.util.HashSet;import java.util.Iterator;import java.util.LinkedHashSet;public class LinkedHashSetDemo {    public static void main(String[] args){        HashSet hs = new LinkedHashSet();        hs.add("abc");        hs.add("def");        hs.add("ghi");        Iterator it = hs.iterator();        while(it.hasNext()){            System.out.println(it.next());        }    }}

  TreeSet的两种排序方式:
  1)自然排序。让元素自身实现比较功能: 实现Comparable接口,覆盖compareTo方法。

/*TreeSet的两种排序方式*/import java.util.TreeSet;import java.util.Iterator;import java.util.Comparator;class Person implements Comparable{    private String name;    private int age;    public Person(){    }    public Person(String name, int age){        this.name = name;        this.age = age;    }    public void setName(String name){        this.name = name;    }    public String getName(){        return this.name;    }    public void setAge(int age){        this.age = age;    }    public int getAge(){        return this.age;    }    public int hashCode(){        return name.hashCode() + age * 39;    }    public boolean equals(Object obj){        if (this == obj)            return true;        if(!(obj instanceof Person))            throw new ClassCastException("类型错误");        Person p = (Person)obj;        return this.name.equals(p.name) && this.age == p.age;    }    public int compareTo(Object o){        Person p = (Person) o;        //先按照年龄排序,再按照姓名排序        int temp = this.age-p.age;        return temp == 0? this.name.compareTo(p.name):temp;    }}public class TreeSetDemo {    public static void main(String[] args){        TreeSet ts = new TreeSet();        ts.add(new Person("Amy",28));        ts.add(new Person("Beth",23));        ts.add(new Person("Cathy",21));        ts.add(new Person("Caroline",23));        ts.add(new Person("Milly",25));        Iterator it = ts.iterator();        while(it.hasNext()){            Person p = (Person)it.next();            System.out.println(p.getName()+" : "+p.getAge());        }    }}

  2)比较器。让集合自身具备比较功能: 定义一个类实现Comparator接口,覆盖compare方法。

import java.util.TreeSet;import java.util.Iterator;import java.util.Comparator;class Person implements Comparable{    private String name;    private int age;    public Person(){    }    public Person(String name, int age){        this.name = name;        this.age = age;    }    public void setName(String name){        this.name = name;    }    public String getName(){        return this.name;    }    public void setAge(int age){        this.age = age;    }    public int getAge(){        return this.age;    }    public int hashCode(){        return name.hashCode() + age * 39;    }    public boolean equals(Object obj){        if (this == obj)            return true;        if(!(obj instanceof Person))            throw new ClassCastException("类型错误");        Person p = (Person)obj;        return this.name.equals(p.name) && this.age == p.age;    }    public int compareTo(Object o){        Person p = (Person) o;        int temp = this.age-p.age;        return temp == 0? this.name.compareTo(p.name):temp;    }}class ComparatorByName implements Comparator{    public int compare(Object o1, Object o2){        Person p1 = (Person) o1;        Person p2 = (Person) o2;        int temp = p1.getName().compareTo(p2.getName());        return temp == 0? p1.getAge()-p2.getAge():temp;    }}public class TreeSetDemo {    public static void main(String[] args){        TreeSet ts = new TreeSet(new ComparatorByName());        ts.add(new Person("Amy",28));        ts.add(new Person("Beth",23));        ts.add(new Person("Cathy",21));        ts.add(new Person("Caroline",23));        ts.add(new Person("Milly",25));        Iterator it = ts.iterator();        while(it.hasNext()){            Person p = (Person)it.next();            System.out.println(p.getName()+" : "+p.getAge());        }    }}

四、Map

  Map接口,即映射,是键-值对(key-value pair)的集合,map集合中必须保证键的唯一性。
  Map的层次结构如下图所示:
  

  Map接口常用方法:
  1) 添加
  value put(key,value):返回前一个和key关联的值,如果没有返回null。
  2) 删除
  void clear():清空map集合。
  value remove(Object key):根据指定的key删除这个键值对。
  3)判断
  boolean containsKey(key);
  boolean containsValue(value);
  boolean isEmpty();
  4)获取
  value get(key):通过键获取值,如果没有该键返回null。
  int size():获取键值对个数。

import java.util.Map;import java.util.HashMap;public class MapMethodDemo {    public static void main(String[] args){        Map<Integer, String>map = new HashMap<Integer, String>();        method(map);    }    public static void method(Map<Integer, String> map){        //添加        System.out.println(map.put(23,"Lucy")); //null        System.out.println(map.put(21,"Glen")); //null        System.out.println(map);         map.put(28,"Richa");        map.put(25,"Samantha");        System.out.println(map);        //删除        //map.clear();        System.out.println("remove: "+map.remove(21));        //判断        System.out.println("containsKey: "+map.containsKey(23));        System.out.println("containsValue: "+map.containsKey("Richa"));        System.out.println("isEmpty: "+map.isEmpty());        //获取        System.out.println("get: "+map.get(23));        System.out.println("size: "+map.size());    }}

  获取Map集合元素并打印的三种方式:
  1)通过keySet方法获取map中所有的键所在的set集合,再通过set的迭代器获取到每一个键。再对每一个键通过map集合的get方法获取其对应的值。

import java.util.Iterator;import java.util.Map;import java.util.HashMap;import java.util.Set;public class MapDemo {    public static void main(String[] args){        Map<Integer, String> map = new HashMap<Integer, String>();        method(map);    }    public static void method(Map<Integer, String>map){        map.put(23,"Lucy");        map.put(21,"Glen");        map.put(28,"Richa");        map.put(25,"Samantha");        Set<Integer> keySet = map.keySet();        Iterator<Integer> it = keySet.iterator();        while(it.hasNext()){            Integer key = it.next();            String value = map.get(key);            System.out.println(key+" : "+value);        }    }}

  2)Map转成Set——entrySet方法:该方法将键和值的映射关系作为对象存储到了Set集合中,而这个映射关系的类型就是Map.Entry类型。

import java.util.Iterator;import java.util.Map;import java.util.HashMap;import java.util.Set;public class MapDemo2 {    public static void main(String[] args){        Map<Integer, String> map = new HashMap<Integer, String>();        method(map);    }    public static void method(Map<Integer, String>map){        map.put(23,"Lucy");        map.put(21,"Glen");        map.put(28,"Richa");        map.put(25,"Samantha");        Set<Map.Entry<Integer, String>> entrySet = map.entrySet();        Iterator<Map.Entry<Integer, String>> it = entrySet.iterator();        while(it.hasNext()){            Map.Entry<Integer, String> me = it.next();            Integer key = me.getKey();            String value = me.getValue();            System.out.println(key+" : "+value);        }    }}

  3)只取value值时:将Map的value存入Collection集合,再通过Collection的迭代器获取value。

import java.util.Collection;import java.util.Iterator;import java.util.Map;import java.util.HashMap;public class MapDemo3 {    public static void main(String[] args){        Map<Integer, String> map = new HashMap<Integer, String>();        method(map);    }    public static void method(Map<Integer, String>map){        map.put(23,"Lucy");        map.put(21,"Glen");        map.put(28,"Richa");        map.put(25,"Samantha");        Collection<String> values = map.values();        Iterator<String> it = values.iterator();        while(it.hasNext()){            System.out.println(it.next());        }    }}
Map子类 内部结构 线程 Remark Hashtable 哈希表 同步 不允许null作为键,null作为值 HashMap 哈希表 同步 允许null作为键,null作为值 TreeMap 二叉树 不同步 可以对Map集合中的键进行排序
/*用LinkedHashMap输出Map内容跟存入顺序一致。*/import java.util.HashMap;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.Map;public class LinkedHashMapDemo {    public static void main(String[] args){        HashMap<Integer, String> hm = new LinkedHashMap<Integer, String>();        hm.put(7, "Vance");        hm.put(3, "Emily");        hm.put(1, "Bill");        hm.put(5, "Alex");        Iterator<Map.Entry<Integer, String>> it = hm.entrySet().iterator();        while(it.hasNext()){            Map.Entry<Integer, String> me = it.next();            Integer key = me.getKey();            String value = me.getValue();            System.out.println(key + ": " +value);        }    }}
/* * 实例:输入1——7的数字,显示是星期几,并打印其英文表示 * 分析:星期几和英文是映射关系——优先考虑HashMap */import java.util.HashMap;import java.util.Map;public class HashMapTest {    public static void main(String[] args){        String week = getWeek(1);        System.out.println(week);        System.out.println(getWeekByMap(week));    }    public static String getWeekByMap(String week){        Map<String, String> map = new HashMap<String, String>();        map.put("星期一","Mon");        map.put("星期二","Tue");        map.put("星期三","Wed");        map.put("星期四","Thu");        map.put("星期五","Fri");        map.put("星期六","Sat");        map.put("星期日","Sun");        return map.get(week);    }    public static String getWeek(int week){        if (week<1 || week>7)            throw new RuntimeException("没有对应的星期,请重新输入");        String[] weeks = {"","星期一","星期二","星期三","星期四","星期五","星期六","星期日"};        return weeks[week];    }}
/* * 实例:获取字符串中每一个字母出现的次数。 * 分析:映射关系——数组和Map;关系中没有顺序编号——Map; * 键有顺序——TreeMap */import java.util.Iterator;import java.util.Map;import java.util.TreeMap;public class MapTest {    public static void main(String[] args){        String str = "fdqavcbsacdfss";        String s = getCharCount(str);        System.out.println(s);    }    public static String getCharCount(String str){        //将字符串变为字符数组        char[] chs = str.toCharArray();        //定义Map集合        Map<Character, Integer> map = new TreeMap<Character, Integer>();        for(int i = 0; i < chs.length; i++){            //如果不是字母,则不统计,跳出本次循环            if(!(chs[i]>='a' && chs[i]<='z' || chs[i] >='A' && chs[i] <='Z'))                continue;            //将数组中的字母作为键去查map表。返回值:map.contains(key)? null : key.equals(k))            Integer value = map.get(chs[i]);            int count = 0;            //如果map中已经存在,则count = key.equals(k);            if(value!=null){                count = value;            }            count++;            map.put(chs[i], count);        }        return mapToString(map);    }    private static String mapToString(Map<Character, Integer> map){        StringBuilder sb = new StringBuilder();        //定义迭代器对象迭代map中存储的键        Iterator<Character> it = map.keySet().iterator();        while(it.hasNext()){            Character key = it.next();            Integer value = map.get(key);            sb.append(key+"("+value+")");        }        return sb.toString();    }}

四、Collections工具类

  Collections:是集合框架的工具类,里面的方法都是静态的。
  Collections常用方法:
  1) 排序:sort, shuffle
  2) 查找:binarySearch, max
  3)替换:replace, replaceAll, fill, swap
  4)反转:reverse, reverseOrder
  5)同步:synchronizedList

import java.util.Collections;import java.util.List;import java.util.Comparator;import java.util.ArrayList;public class CollectionsDemo {    public static void main(String[] args){        demo();    }    public static void demo(){        List<String> list = new ArrayList<String>();        list.add("Caroline");        list.add("Amy");        list.add("Lisa");        list.add("Sandy");        list.add("Beth");        list.add("Daisy");        //对list集合进行指定顺序的排序        Collections.sort(list);        System.out.println(list);        Collections.sort(list, new ComparatorByLength());        System.out.println(list);        mySort(list, new ComparatorByLength());        System.out.println(list);        //shuffle: 使用默认随机源对指定列表进行置换        Collections.shuffle(list);        System.out.println(list);        //查找,找不到返回-1        int index = Collections.binarySearch(list, "Beth");        System.out.println("index  = "+index);        //获取最大值        String max = Collections.max(list, new ComparatorByLength());        System.out.println("max = "+max);        //替换        Collections.replace(list,"Lisa","Milly");        System.out.println(list);    }    public static <T> void mySort(List<T> list, Comparator<? super T> comp){        for(int i = 0; i < list.size()-1; i++){            for (int j = i+1; j < list.size(); j++){                if(comp.compare(list.get(i), list.get(j))>0){                    Collections.swap(list, i, j);                }            }        }    }}class ComparatorByLength implements Comparator<String>{    public int compare(String o1, String o2){        int temp = o1.length()-o2.length();        return temp == 0? o1.compareTo(o2):temp;    }}

五、Arrays工具类

  Arrays:集合框架的工具类,里面的方法都是静态的。
  List asList(数组) 可以将数组转成集合,以便于增删操作。
  使用Collection的 toArray 方法可以将集合转成数组。当指定类型的数组长度小于集合的size,那么该方法内部会创建一个新的数组。所以一般数组长度指定为集合的size。

import java.util.ArrayList;import java.util.Arrays;import java.util.List;public class ArraysDemo {    public static void main(String[] args){        //数组——>集合: List asList(array)        String[] arr = {"Amy", "Lucy", "Cathy"};        List<String> list = Arrays.asList(arr);        System.out.println(list.contains("Lucy"));        int[] arr1 = {31, 11, 51, 61};        List<int[]> list1 = Arrays.asList(arr1);        System.out.println(list1);        Integer[] arr2 = {31, 11, 51, 61};        List list2 = Arrays.asList(arr2);        System.out.println(list2);        //集合——>数组: toArray        List<String> list3 = new ArrayList<String>();        list3.add("abc1");        list3.add("abc2");        list3.add("abc3");        String[] arr3 = list3.toArray(new String[2]);        System.out.println(Arrays.toString(arr3));    }}
0 0
原创粉丝点击