Java集合学习总结

集合

Java的集合体系:Collection与Map。
在这里插入图片描述
Collection与Map都是抽象接口,List和Set也是抽象接口。ArrayList、Vector、LinkedList是List的具体实现类,HashSet、TreeSet是Set的实现类。HashMap、TreeMap是Map集合的实现类。

集合与数组的区别

长度上,数组长度不可变,集合可变;存储元素类型区别,数组可存任意类型,但一个数组中必须是同种类型。集合只能存引用类型,一个集合可存多种引用类型。

Collection接口

集合的顶层接口,有唯一的,有可重复的,有有序的,有无序的。

抽象方法

  添 加:boolean add(E e);添加一个元素
     boolean addAll(Collection<? extends E> c) 添加一个集合
  删 除:void clear();暴力删除集合所有元素
     boolean remove(Object o);删除一个元素
     void removeAll(Collection c);删除一个集合
  判 断:boolean contains(Object obj);判断是否包含某一个元素
     boolean containsAll(Collection c);判断是否包含一个集合
     boolean isEmpty();判断是否为空
  获 取:Iterator <E> iterator();集合的迭代器
     int size();获取集合长度
     Object [ ] toArray()

子接口List

  List集合体系特点:元素有序(存放与取出顺序一致);
          元素可以重复;
          可以通过索引得到元素;
  特有方法:
    添 加:boolean add(E e);
    获 取:E get(int index);
    删 除:E remove(int index) ;
       boolean remove(Object o);
    修 改:E set(int index, E element);
    迭代器:ListIterator listIterator(int index);该方法可以从指定位置开始迭代

List的三大实现类

  ArrayList  LinkedList  Vector
  特点:
    ArrayList:底层数据结构是数组,查询快,增删慢。线程不安全,效率高
    Vector:底层数据结构是数组,查询快,增删慢。线程安全,效率低,查询稍慢。
    LinkedList:底层数据结构是链表,查询慢,增删快。线程不安全,效率高。
  ArrayList的使用

ArrayList<String> arrayList = new ArrayList<String>();
		arrayList.add("Hello");
        arrayList.add("Java");
        //遍历有三种方法
        for (int i = 0; i < arrayList.size(); i++) {
            System.out.println(arrayList.get(i));
        }
        //迭代器遍历
        Iterator<String> iterator = arrayList.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        //增强for,源码也是迭代器
        for (String s : arrayList) {
            System.out.println(s);
        }

  Vector的使用:
  Vector的特有方法:
    添 加:void addElement(E obj);
    获 取:E elementAt(int index);
       Enumeration elements();枚举,与迭代器类似,hasMoreElements(),nextElement()方法。

 Vector<String> vector = new Vector<>();
        vector.add("Hello");
        vector.add("Java");
        //添加
        vector.addElement("World");
        for(String s:vector){
            System.out.println(s);
        }
        //获取
        Enumeration<String> elements = vector.elements();
        while (elements.hasMoreElements()){
            System.out.println(elements.nextElement());
        }

  LinkedList的使用:
  LinkedList数据结构为链表,有特殊的方法:
    添 加:void addFirst(E e);
       void addLast(E e);
    获 取:E getFirst();
       E getLast();
    删 除:E removeFirst();
       E removeLast();

 LinkedList<String> linkedList = new LinkedList<>();
        //独特的链表结构,可以模拟一个栈的存储
        linkedList.addFirst("first");
        linkedList.addFirst("second");
        linkedList.addFirst("third");
        linkedList.addFirst("fourth");
        linkedList.addFirst("last");
        for(String s:linkedList){
            System.out.println(s);
        }

子接口Set

  Set集合体系特点:元素不可以重复
     元素无序(存入与取出顺序不一样,有独特的排序规则)

Set的实现类

  HashSet TreeSet
    HashSet:底层数据结构为哈希表,元素不可重复
    TreeSet:底层数据结构为红黑树(平衡二叉树)元素不可重复且排序
  HashSet的使用:
    HashSet集合保证元素无序,主要由hashCode()和equals()方法来判断的。源码如下:

//add方法
public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
//put方法
public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }
 //继续调用putVal方法,并且用hash算法算出添加值的哈希值
 if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;

    在putVal方法里,先比较哈希值是否相等,再比较equals是否相等。所以有以下问题:在存引用对象时,若一个对象重复造了两次,所以哈希值不会相同,都可以存入集合,这样元素便重复了。
    要想保证不重复,就需要让两个重复对象的哈希值相同,所以根据对象的成员变量重写类的hashCode方法即可,但同时需要重写equals方法,判断对象成员变量是否相同,这样就可以排除重复元素。

public static void main(String[] args) {
        HashSet<People> hs = new HashSet<>();
        People p1 = new People(12, "one");
        People p2 = new People(13, "two");
        People p3 = new People(12, "one");
        //在没有重写hashCode和equals时都可以添加成功
        System.out.println("P1的添加"+hs.add(p1));//结果:P1的添加true
        System.out.println("P2的添加"+hs.add(p2));//结果:P2的添加true
        System.out.println("P3的添加"+hs.add(p3));//结果:P3的添加true
    }
public static void main(String[] args) {
        HashSet<People> hs = new HashSet<>();
        People p1 = new People(12, "one");
        People p2 = new People(13, "two");
        People p3 = new People(12, "one");
        //在重写hashCode和equals后
        System.out.println("P1的添加"+hs.add(p1));//结果:P1的添加true
        System.out.println("P2的添加"+hs.add(p2));//结果:P2的添加true
        System.out.println("P3的添加"+hs.add(p3));//结果:P3的添加false
    }

  TreeSet集合的使用:
    TreeSet集合对元素进行排序,分为自然排序和比较器排序。自然排序就是默认排序规则,比较器排序需要实现Comparator接口。
当存放Integer类型时,Integer类已经实现了Comparator接口,可以使用自然排序。

//自然排序
 public static void main(String[] args) {
        TreeSet<Integer> ts = new TreeSet<>();
        ts.add(10);
        ts.add(0);
        ts.add(25);
        ts.add(0);
        for (Integer i : ts) {
            System.out.println(i);
        }
        //输出结果0 10 25
    }
//比较器排序
public static void main(String[] args) {
        People p1 = new People(12, "one");
        People p2 = new People(10, "two");
        People p3 = new People(14, "three");
        //TreeSet<People> ts = new TreeSet<>();
        //不实现比较器时报异常java.lang.ClassCastException: com.IO.People cannot be cast to java.lang.Comparable
        //下面采用匿名内部类方法实现接口
        TreeSet<People> ts = new TreeSet<>(new Comparator<People>() {
            @Override
            public int compare(People o1, People o2) {
                return o1.age-o2.age;
            }
        });
        ts.add(p1);
        ts.add(p2);
        ts.add(p3);
        for(People p:ts){
            System.out.println(p.name+"---"+p.age);
        }
        //输出结果
        //two---10
        //one---12
        //three---14
    }

Map接口

  Map接口与Collection一样为顶层接口,与Collection系列集合不同之处是:Map集合存的都是键值对,以key,value形式成对出现。第二个不同是,Map键唯一,而Collection只有Set系列保证元素唯一。第三个不同,Map数据结构针对的是键,Collection数据结构针对的是元素。

Map接口抽象方法:

  添 加:V put(K key, V value);返回值为该键对应的原值,也可以作为修改的方法。
  删 除:void clear();
     V remove(Object key);
  判 断:boolean containsKey(Object key);
     boolean containsValue(Object value);
     boolean isEmpty();
  获 取:V get(Object key);根据键获取值
     Set keySet();获取键的集合
     Collection values();获取值的集合
     Set<Map.Entry<K,V>> entrySet();获取键值对对象
  遍历方法:
     因为Map比较特殊,所以遍历时也比较特殊。有两种方法,一:获取键的集合,用键获取值;二:获取键值对对象的集合,遍历集合获取键和值。

实现类HashMap、TreeMap

  实现类有HashMap、TreeMap,还有LinkedHashMap、Hashtable(没有按驼峰命名规则),特点如下:
   HashMap:哈希表的数据结构,元素无序唯一(无序指的是存放去取的无序,唯一对键有效)。
   LinkedHashMap:也使用了链表,元素有序唯一。
   Hashtable:源于jdk1.0,在jdk1.2被改造在Map接口下。与HashMap相似。线程安全,效率低,是同步的,不允许null键和null值;HashMap线程不安全,效率高,允许null键与null值。
   TreeMap:键排列有序,也是自然排序和比较器排序。
HashMap使用:

 public static void main(String[] args) {
        HashMap<Integer, String> hm = new HashMap<>();
        hm.put(1,"Hello");
        hm.put(2,"Java");
        hm.put(3,"World");
        //遍历--用键获取值
        for(int i=1;i<4;i++){
            System.out.println("key="+i+",value="+hm.get(i));
        }
        //遍历--获取键值对对象
        Set<Map.Entry<Integer, String>> entries = hm.entrySet();
        for(Map.Entry a:entries){
            System.out.println("key="+a.getKey()+",value="+a.getValue());
        }
        //输出结果
        //key=1,value=Hello
        //key=2,value=Java
        //key=3,value=World
        //key=1,value=Hello
        //key=2,value=Java
        //key=3,value=World
    }

TreeMap的使用

public static void main(String[] args) {
        People p1 = new People(12, "康康");
        People p2 = new People(10, "迈克");
        People p3 = new People(11,"玛利亚");
        //用TreeMap存这三个人,作为键,值为每个人的爱好。默认以年龄排序
        TreeMap<People, String> tm = new TreeMap<>(new Comparator<People>() {
            @Override
            public int compare(People o1, People o2) {
                return o1.age-o2.age;
            }
        });
        tm.put(p1,"篮球");
        tm.put(p2,"游泳");
        tm.put(p3,"唱歌");
        //遍历
        Set<Map.Entry<People, String>> entries = tm.entrySet();
        for(Map.Entry mess:entries){
            System.out.println(mess.getKey().toString()+"的爱好是"+mess.getValue());
        }
        //输出结果
        //People{age=10, name='迈克'}的爱好是游泳
        //People{age=11, name='玛利亚'}的爱好是唱歌
        //People{age=12, name='康康'}的爱好是篮球
    }

集合工具类

  为了方便集合操作,Java也提供了一个工具类------Collections。
  几个常用的方法:
  static <T extends Comparable<? super T>> void sort(List list) 对list集合排序,默认自然排序
  static <T extends Comparable<? super T>> void sort(List list,Comparator<? super T> c) 比较器排序
  static int binarySearch(List<? extends Comparable<? super T>> list, T key) 二分查找
  static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) Collection集合最大值
  static void reverse(List<?> list) 集合反转
  static void shuffle(List<?> list) 随机置换元素

总结

  集合从大的分有两大类,Collection和Map,前者存储的都是单一元素,后者为键值对。使用Collection时,若对元素没有要求,ArrayList最佳。若需要保证元素唯一,可以用HashSet;若同时需要排序时,采用TreeSet。在使用Map时,有排序要求就使用TreeMap,没有就用HashMap。
  此篇文章仅仅用于对自我知识总结,以便复习,也希望对集合知识不是清晰的Java学习者有一点帮助。作者也是Java萌新,望大佬多多指点。
  附带一个模拟扑克牌发牌的程序,用于练习。
   链接:https://pan.baidu.com/s/15G32-CSr-lWBxazcameQYg
   提取码:g3hl

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值