Java集合总结

java集合有三大类,但在此文中值,知介绍其中的俩类,如果想了解详细的集合家族,

java集合成员全员介绍

Java集合类主要有俩个派系Collection和Map

常用集合家族图谱

Collection根接口

1、概述: Collection是单列集合的根接口,定义了所有单列集合中共有的功能
2、所有的方法:

boolean add(E e)
       确保此 collection 包含指定的元素(可选操作)。
boolean addAll(Collection<? extends E> c)
       将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。
void clear()
       移除此 collection 中的所有元素(可选操作)。
boolean contains(Object o)
       如果此 collection 包含指定的元素,则返回 trueboolean containsAll(Collection<?> c)
       如果此 collection 包含指定 collection 中的所有元素,则返回 trueboolean equals(Object o)
       比较此 collection 与指定对象是否相等。
int hashCode()
       返回此 collection 的哈希码值。
boolean isEmpty()
       如果此 collection 不包含元素,则返回 true。
Iterator<E> iterator()
       返回在此 collection 的元素上进行迭代的迭代器。
boolean remove(Object o)
       从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。
boolean removeAll(Collection<?> c)
       移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。
boolean retainAll(Collection<?> c)
       仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。
int size()
       返回此 collection 中的元素数。
Object[] toArray()
       返回包含此 collection 中所有元素的数组。
<T> T[]
toArray(T[] a)
       返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。

List子接口

1、概述: List 是Collection 的子接口,List接口中继承了Collection中的所有的方法,并且还增加了一些特有的方法(关于下标)
2、List集合的特点:有序、元素可以重复、有索引
3、List集合中的方法:
自己关于下标特有的方法:

add(int index,Object obj): 在指定的索引上添加指定元素
remove(int index): 根据下标删除指定的元素
set(int index,Object obj): 将指定下标的元素修改为指定的值
get(int index) 返回列表中指定位置的元素。

List遍历方式

package com.officn.day13;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;


public class Demo2 {
    
    public static void main(String[] args) {
        
        ArrayList<Integer> arrayList = new ArrayList();


        arrayList.add(1);//集合中不能添加基本数据类型,add()会自动装箱为引用数据类型
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);
        arrayList.add(5);
        
//        arrayList.remove(1);//删除下标为1 的元素,remove不会自动装箱
        arrayList.remove((Integer)1);//删除元素值为1的数据,
        
        //迭代器
        Iterator iterator = arrayList.iterator();
        
        while(iterator.hasNext()) {
            Object next = iterator.next();
            System.out.println(next);
        }
        //foreach遍历
        for (Object o : arrayList) {
            System.out.println(o);
        }
        //jdk8新特性,foreach方法  接口回调
        arrayList.forEach(new Consumer<Object>() {
            
            @Override
            public void accept(Object t) {
                // TODO Auto-generated method stub
                System.out.println(t);    
            }
            
        });
        
        //lambda表达式
        arrayList.forEach(t->System.out.println(t));
        //方法引用,对lambda进一步的简化
        arrayList.forEach(System.out::println);
    }


}

并发修改异常

1、概念:在使用迭代器Iterator遍历结合的同时,对List进行添加/删除操作,由此产生的异常为并发修改异常
代码示例:

package com.officn.day13;


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


public class Demo3 {
    
    public static void main(String[] args) {
        
        ArrayList list = new ArrayList();
        
        list.add("小优势");
        list.add("西游记");
        list.add("水浒传");
        list.add("三国演义");
        list.add("红楼梦");
        list.add("活着");
        
        Iterator iterator = list.iterator();
        while(iterator.hasNext()) {
            Object next = iterator.next();
//            //修改元素
//            if(next.equals("活着")) {
//                list.set(0, "小优势");
//            }
            //查询
            if(next.equals("小优势")) {
                System.out.println(list.get(list.size()-1));
            }
            //增加元素
//            Exception in thread "main"
//            java.util.ConcurrentModificationException并发修改异常
//            if(next.equals("小优势")) {     //迭代器执行时,不能操作list的增删
//                list.add("成龙");
//            }
//            
//            //删除元素
//            Exception in thread "main"
//            java.util.ConcurrentModificationException并发修改异常
//            if(next.equals("小优势")) {
//                list.remove("成龙");
//            }
            System.out.println(next);
            
        }
        
        
    }


}

并发修改异常的解决方法

1、迭代器遍历,迭代器增加
2、集合遍历,集合增加
代码示例:

package com.officn.day13;


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


public class Demo4 {
    
    public static void main(String[] args) {
        
        ArrayList list = new ArrayList();
        
        
        list.add("小优势");
        list.add("西游记");
        list.add("水浒传");
        list.add("三国演义");
        list.add("红楼梦");
        list.add("活着");
        
        //集合遍历,集合添加
        for(int i =0; i<list.size(); i++) {
            if(list.get(i).equals("红楼梦")) {
                list.add("平凡世界");
            }
            System.out.println(list.get(i));
        }
        
        //集合遍历,集合删除
        for(int i =0; i<list.size(); i++) {
            if(list.get(i).equals("红楼梦")) {
                list.remove("活着");
            }
            System.out.println(list.get(i));
        }
        
        //迭代器遍历,迭代器删除
        ListIterator iterator = list.listIterator();
        while(iterator.hasNext()) {
            Object next = iterator.next();
            if(next.equals("活着")) {
                iterator.remove();
            }
            System.out.println(next);
        }
        
        //迭代器遍历,迭代器添加
        ListIterator<String> iterator1 = list.listIterator();
        while(iterator1.hasNext()) {
            Object next = iterator1.next();
            if(next.equals("活着")) {
                 iterator1.add("悲惨世界");
            }
            System.out.println(next);
        }
        
        System.out.println("================");
        
        for (Object object : list) {
            System.out.println(object);
        }
    
    }


}

List集合的实现类

ArrayList

	1、概念:底层采用数组形式实现,顺序存储(有List中的方法,无特有方法)

LinkedList

	1、概念:底层采用节点实现,链式存储

特有方法

addFirst(Object obj):在头部添加元素
addLast(Object obj):在尾部添加元素
removeFirst():删除头部元素
removeLast():删除尾部元素
getFirst():获取头部元素
getLast():获取尾部元素

ArrayList和LinkedList比较:

List比较
ArrayList查询修改快,删除增加慢,非线程安全,有索引
LinkList查询修改慢,删除增加快,非线程安全,有索引
验证代码
package com.officn.day13;
import java.util.ArrayList;
import java.util.LinkedList;
public class Demo5 {
    
    public static void main(String[] args) {
        
        ArrayList arrayList = new ArrayList();
        LinkedList linkedList = new LinkedList();
        
        for(int i =0; i<1000000;i++) {
            arrayList.add(i);
            linkedList.add(i);
        }
        
        int index = 50000;

        //arrayList查询时间
        long start1 = System.nanoTime();
        arrayList.get(index);
        long end1 = System.nanoTime();
        System.out.println(end1 - start1);//5700
        
        //linkedList查询时间
        long start2 = System.nanoTime();
        linkedList.get(index);
        long end2 = System.nanoTime();
        System.out.println(end2 - start2);//985900

        //ArrayList在头添加元素
        long start3 = System.nanoTime();
        for (int i = 0; i < 500; i++) {
            arrayList.add(0, i);
        }
        long end3 = System.nanoTime();//241714400
        System.out.println(end3 - start3);

        //LinkedList在头添加元素
        long start4 = System.nanoTime();
        for (int i = 0; i < 500; i++) {
            linkedList.add(0, i);
        }
        long end4 = System.nanoTime();
        System.out.println(end4 - start4);//175600
    }
}

Set集合

1、概述:Set接口是Collection 根接口的子接口,和List接口是兄弟关系
2、特点:无序,不可以重复,没有索引
3、存储特点:
相同的元素无法存进set元素
集合本身不保证顺序,存进去和取出来的顺序不一定一样

HashSet:

1、概念:HashSet是Set的实现类,其底层采用的是哈希表的存储结构(数组+单向链表)
2、HashSet保证元素的唯一性原理:

		重写equals方法,比较各个对象的属性值是否全部相等
		重写hashCode,相同的对象要有相同的哈希值,不同的对象要有不同的哈希值

3、重写equals和hashCode方法

package com.officn.day14;
import java.util.LinkedHashSet;
public class Demo3 {
     
     public static void main(String[] args) {
         
         // 创建一个set集合
         //HashSet<Student> students = new  HashSet<Student>();
         LinkedHashSet<Student> students = new  LinkedHashSet<Student>();
         Student s1 = new Student("小红", 16);
         System.out.println(s1.hashCode());
         
         Student s2 = new Student("小紫", 86);
         System.out.println(s2.hashCode());
         
         Student s3 = new Student("小蓝", 56);
         System.out.println(s3.hashCode());
         
         Student s4 = new Student("小黑", 166);
         System.out.println(s4.hashCode());
         
         Student s5 = new Student("小绿", 34);
         System.out.println(s5.hashCode());
         
         Student s6 = new Student("小粉", 116);
         System.out.println(s6.hashCode());
         
         //增加一个重复的元素
         Student s7 = new Student("小红", 16);
         System.out.println(s7.hashCode());
         students.add(s1);
         students.add(s2);
         students.add(s2);
         students.add(s2);
         students.add(s3);
         students.add(s4);
         students.add(s5);
         students.add(s6);
         students.add(s7);
         
         
         for (Student student : students) {
              System.out.println(student);
         }
         
     }
}
class Student{
     
     String name;
     int age;
     public Student() {
         super();
         // TODO Auto-generated constructor stub
     }
     
     
     
     public Student(String name, int age) {
         super();
         this.name = name;
         this.age = age;
     }
     @Override
     public String toString() {
         return "Student [name=" + name + ", age=" +  age + "]";
     }
     @Override
     public int hashCode() {
         final int prime = 31;
         int result = 1;
         result = prime * result + age;
         result = prime * result + ((name == null) ? 0  : name.hashCode());
         return result;//如果年龄姓名相同便返回相同的hashCode
     }
     @Override
     public boolean equals(Object obj) {
         if (this == obj)
              return true;
         if (obj == null)
              return false;
         if (getClass() != obj.getClass())
              return false;
         Student other = (Student) obj;
         if (age != other.age)
              return false;
         if (name == null) {
              if (other.name != null)
                  return false;
         } else if (!name.equals(other.name))
              return false;
         return true;
     }
     
}

输出:
680868
688144
20979936
32906270
853084
39794467
680868
Student [name=刘洋, age=16]
Student [name=刘能, age=86]
Student [name=刘德化, age=56]
Student [name=范冰冰, age=166]
Student [name=李程, age=34]
Student [name=黎国祥, age=116]
LinkedHashSet

1、概念:是HashSet的一个子类,与HashSet的保证元素唯一的原理相同
2、特点:既保证元素的唯一性,又保证元素的存储顺序

Map集合

1、概述:Map: 映射 双列集合的顶级接口.
2、特点:数据存储是以(key-value)形式存储的,其中key不能重复,value可以重复
3、常用的方法

void clear()从此映射中移除所有映射关系(可选操作)。
boolean containsKey(Object key)   如果此映射包含指定键的映射关系,则返回 trueboolean containsValue(Object value)  如果此映射将一个或多个键映射到指定值,则返回 true。
Set<Map.Entry<K,V>> entrySet()  返回此映射中包含的映射关系的 Set 视图。
boolean equals(Object o)  比较指定的对象与此映射是否相等。
V get(Object key)  返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
int hashCode()   返回此映射的哈希码值。
boolean isEmpty()  如果此映射未包含键-值映射关系,则返回 true。
Set<K> keySet()  返回此映射中包含的键的 Set 视图。
V put(K key, V value) 将指定的值与此映射中的指定键关联(可选操作)。
void putAll(Map<? extends K,? extends V> m) 从指定映射中将所有映射关系复制到此映射中(可选操作)。
V remove(Object key)  如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
int size()  返回此映射中的键-值映射关系数。
Collection<V> values()  返回此映射中包含的值的 Collection 视图。

4、Map集合的遍历:

package com.officn.day14;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.function.BiConsumer;
import java.util.Set;
public class Demo4 {
     
     public static void main(String[] args) {
         
         HashMap<Integer, String> hashMap = new  HashMap<>();
         
         hashMap.put(1, "多态");
         hashMap.put(2, "继承");
         hashMap.put(3, "封装");
         hashMap.put(4, "对象");
         hashMap.put(5, "异常");
         hashMap.put(6, "集合");
         hashMap.put(7, "泛型");
         
//       key-Value形式遍历
         Set<Integer> keySet = hashMap.keySet();
         for (Integer integer : keySet) {
              System.out.println(integer+"=="+hashMap.get(integer));
         }
         
//       Value遍历
         Collection<String> values = hashMap.values();
         for (String string : values) {
              System.out.println(string);
         }
         
//       获取所有键值对形成的一个set集合
         Set<Entry<Integer, String>> entrySet =  hashMap.entrySet();
         for (Entry<Integer, String> entry : entrySet)  {
              System.out.println(entry.getKey()+"++"+entry.getValue());
         }
         
         
//       forEach遍历   接口回调
         hashMap.forEach(new BiConsumer<Integer,  String>() {
              @Override
              public void accept(Integer t, String u) {
                  System.out.println(t + "--" + u);
              }
         });
//       Lambda表达式
         hashMap.forEach((t,v)->System.out.println(t+"***"+v));
     }
}

HashMap

1、概念:是Map接口的实现类,底层采用的是哈希表进行存储的.
2、HashMap保证元素的唯一性原理:
与HashSet一样为保证键的唯一性,在对象中重写equals和HashCode方法
HashSet是有HashMap实现出来的,HashSet就是HashMap的键这一列
3、一道HashMap的例题:统计一个字符串中每个字符出现的个数

package com.officn.day14;
import java.util.HashMap;
import java.util.Scanner;
public class Demo5 {
     
     public static void main(String[] args) {
         
         Scanner sc = new Scanner(System.in);
         
         String str = "aaaabbccddd!@#@#$@#$%cc66ff";
         HashMap<Character, Integer> hashMap = new  HashMap<>();
         
         for (int i = 0; i < str.length(); i++) {
              
              char charAt = str.charAt(i);
              
              if (hashMap.containsKey(charAt)) {
                  
                  int count = hashMap.get(charAt);
                  hashMap.put(charAt, ++count);
                  
              }else {
                  hashMap.put(charAt, 1);
              }
              
         }
         
         hashMap.forEach((t,v)->System.out.println(t+"--"+v));
         
     }
}

LinkedHashMap

1、概念:是HashMap的子类,维护键的添加顺序

TreeMap

1、概念: 是SortedMap接口的实现类,SortedMap 是Map接口的子接口
2、特点:TreeMap可以根据键自动由小到大排序

List、Set、Map的特点表格

集合名称特点
List有序,有索引,可以重复
Set无序,没索引,不能重复
Map键是唯一的,值不是惟一的 每个键只能对应唯一的值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值