alt

单列集合Collection接口

  • List :有序、可重复 ==> ArrayList、LinkedList、Vector
  • Set:无序、不可重复 ==> HashSet、LinkedHashSet、TreeSet alt

Collection接口常用方法

  • 前提:向Collection接口实现类中add数据obj时,obj所在类一定要重写equals(),直接Lombok


============================当前集合被修改===========================
对象.add(Object o);
对象.addAll(Collection coll);	//把coll里所有元素添加到集合对象中
对象.clear();		//清空集合数据 size=0
对象.remove(Object o);	//如果集合含至少1个o,则移除1个
对象.removeAll(Collection coll);	//如果集合对象中包含co11元素,则移除所有该元素
对象.retailnAll(Collection coll);	//获取交集,原集合只剩交集部分
对象.toArray();		//集合转化为数组
Arrays.asList(传入一个数组);	  //数组转化为集合

Arrays.asList(new int[]{1,2,3,4}),new int[]{1,2,3,4}会被当成一个元素
Arrays.asList(1,2,3,5)
Arrays.asList("a","b","c","d")
Arrays.asList(new Integer[]{1,2,3,4})	//new 包装类
  
============================当前集合不会修改===========================
对象.size();
对象.isEmpty();	//size==0
对象.contains(Object o);	
//源码:equals(o),按内容判断。
//如果o重写了equals() 和 hashCode(),比较内容,否则 ,比较哈希值
对象.containsAll(Collection coll);	//判断coll所有元素是否全在集合对象里面
对象.equals(Collection coll);		
//因为List集合有序,所以除了比较元素内容是否一致之外,还要比各元素顺序是否一致
//如果是Set集合(无序),只需要比较元素内容

对象.iterator()	返回Iterator接口实例,用于遍历集合元素

-

Collection集合遍历

  • 1、迭代器Iterator
public static void main(String[] args) {
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(124);
  
        //获取迭代器
        Iterator it = coll.iterator();
  		//(1)遍历Collection集合
        while(it.hasNext()){//it.hasNext()判断是否还有下一个元素
            //it.next() :后移动一位,并取出元素
            System.out.println(it.next());
        }
  
  		//一定要重新获取iterator
  		it = coll.iterator();
  		//(2)移除不想要的元素
    	while(it.hasNext()){
          	Object obj = it.next();
          	if("hello".equals(obj)){
            	it.remove();	//移除当前位置元素
            }
        }
  	
  
	}
  • 2、Foreach增强fro 本质还是迭代器
		Collection coll = new ArrayList();
        coll.add(123);
        coll.add(124);

        //遍历Collection集合,快捷键coll.iter回车
        for (Object o : coll) {
            System.out.println(o);
        }

动态数组 :List接口( 有序,可重复 )

List接口常用接口
ArrayList list = new ArrayList();

list.add(int index,element e);	
list.get(int index);	//获取指定位置元素
//因为ArrayList底层是数组,所以下标索引从零开始。在下标为index位置插入e,后面元素后移一位
list.addAll(Collection coll);	//把coll所有元素添加进list集合
list.add(Collection coll);		//把coll集合当成一个元素,添加到集合中
list.indexOf(Object obj);		//返回obj在集合中首次出现的位置,否则返回-1
list.lastIndexOf(Object obj);	//返回obj在集合中最后一次出现的位置
list.remove(int index);			//重载方法,不是重写,所以调用删除指定索引或者指定值看左边是谁,删除指定位置元素
list.set(int index,element e);	//修改元素

====================集合改变===============================
List subList = list.subList(2,4);	//左闭右开,获取下标为2,3的元素并存储到一个新集合中

alt

面试题:[1,2]

alt

ArrayList:List接口主要实现类;线程不安全,效率高;底层Object[]存储,查询快,增删慢

alt

LinkedList:底层使用双向链表存储;增删快,查询慢
Vector:List接口古老实现类;线程安全,效率低;底层Object[]存储
面试题:ArrayList、LinkedList、Vector 三者区别
相同:都实现了List接口,存储数据特点一样:有序,可重复
不同:
	ArrayList:List接口主要实现类;线程不安全,效率高;底层Object[]存储,查询快,增删慢
	LinkedList:底层使用双向链表存储;增删快,查询慢
	Vector:List接口古老实现类;线程安全,效率低;底层Object[]存储

Set接口( 无序,不可重复 )用的比较少,没有额外方法,存放元素重写hashCode和equals

  • 无序性 :不等于随机性,而是按照hashCode值进行散列排序放进数组
  • 不可重复性 :添加元素先判断哈希值是否一样,不一样直接添加进去,一样(哈希冲突)时,equals()判断内容是否一样,不一样则添加。
先hashCode,再equals();计算hashCode是根据成员来算的,下面有一道经典的面试题
https://www.bilibili.com/video/BV1Kb411W75N?p=547&spm_id_from=pageDriver

alt

alt

alt

HashSet :Set接口的主要实现类;底层:数组+链表;线程不安全;可以存储null值
LinkedHashSet:作为HashSet的子类;"有序",实际上不是真正的有序,只是元素的数据结构是双向链表,所以知道插入顺序,适用于:频繁的遍历操作
(了解)TreeSet : 可以按照添加对象的指定属性,进行排序。

alt

  • 向TreeSet中添加数据,要求是相同类对象,类必须实现Comparable接口。不能添加不同类对象。

1、自然排序(实现comParable接口):comparTo()返回0,说明两对象相同

public class User implements Comparable<User> {
    @Override
    public int compareTo(User o) {
        //按姓名排,反过来排return   -this.Name.compareTo(user.Name);
        int compare =  this.Name.compareTo(o.Name);
        if(compare!=0)
        {
            return compare;
        }else{
            //当姓名一样时,比较年龄Integer比较
            return Integer.compare(this.age,o.age);
        }
    }
}

2、定制排序(Comparator):

public class Test05 {
    public static void main(String[] args) {

        Comparator<User> com = new Comparator<User>() {
            @Override
            public int compare(User u1, User u2) {
                //年龄升序,如果age一样,姓名倒序
                int result = Integer.compare(u1.getAge(),u2.getAge());
                if(result==0){
                    result = -u1.getName().compareTo(u2.getName());
                }
                return result;
            }
        };

        TreeSet<User> set = new TreeSet<>(com);
        set.add(new User("李四",14));
        set.add(new User("王五",20));
        set.add(new User("赵六",16));
    
        for (User user : set) {
            System.out.println(user);
        }
    }
}

alt

双列集合Map接口

  • Map结构的理解:
key :由Set存储,因为不可重复、无序,=
value :由Collenction存储,可重复、无序
Entry :key+value,不重复、无序、put相同key时value可覆盖
Map实际存的元素就是Entry。
  • ==> key存放的类要重写 hashCode()和equals(),除了TreeMap:自然排序和定制排序
  • ==> value存放的类要重写 equals()

alt

一个key对应一个value,多个key可以对应同一个value,例如学生-成绩
    HashMap、LinkedHashMap、TreeMap、Hashtable、Properties

HashMap :作为Map的主要实现类;线程不安全,效率高,可存储null的key和value

LinkedHashMap :保证在遍历map元素时,可以按照添加的顺序实现遍历;类似LinkedHashSet,适用于频繁的遍历操作

HashMap和LinkedHashMap底层:数组+链表+红黑树(jdk8) alt

TreeMap :类似TreeSet,可以保证按照添加的键值对进行排序;实现排序遍历。

	TreeSet和TreeMap底层都是红黑树
向TreeMap中添加key-value,要求key必须是由同一个类创建的对象
因为要按照key排序,自然排序、定制排序

Hashtable :古老实现类,线程安全,效率低,不能存储null的key和value

Properties :配置文件,key vlaue 都是String类型

面试题

  • HashMap底层原理 alt alt

jdk7 alt

jdk8变化 alt

  • HashMap和Hashtable的异同

  • CurrentHashMap 分段锁机制,适用于高并发

Map接口常用方法

//增删改操作
  map.put(Object key,Object value)	//key一般是String类型,key相同时,覆盖原有value
  map.putAll(Map m);//将m集合中所有key-value对存放进当前map中
  map.remove(Object key)
  map.clear();//清空
//元素查询操作
  map.get(Object key)
  boolean map.containsKey(Object key)
  boolean map.containsValue(Object value)
  map.size()
  map.isEmpty()
  map.equals(Object obj);	//判断两个map是否一样
//遍历方法
  Set set = map.keySet();
  Collection values = map.values();
  Set set = map.entrySet();
  

遍历

public class Test06 {
    public static void main(String[] args) {
        HashMap map = new HashMap();
        map.put("A",11);
        map.put("B",12);
        map.put("C",13);
        map.put("D",14);

        //遍历key
        Set set01 = map.keySet();
        for (Object o : set01) {
            System.out.println(o);
        }

        //遍历value
        Collection values = map.values();
        for (Object value : values) {
            System.out.println(value);
        }


        //遍历Map操作
        Set set = map.entrySet();
        for (Object o : set) {
            //强转为Entry
            Map.Entry entry = (Map.Entry)o;
            System.out.println(entry.getKey()+" : "+entry.getValue());
        }

    }
}

操作Set、List、Map的集合工具类Collections

  • 1、排序操作,均为static方法
=============================集合被修改====================================
  reverse(List) :反转List中元素的顺序
  shuffle(List) :打乱List集合顺序,进行随机排序
  sort(List) :根据元素的自然排序对指定List集合元素按升序排序
  sort(List,Comparator) :根据指定Comparator产生的顺序对List集合元素进行排序
  swap(List,int,int) :将指定list集合中的i处元素和j处元素进行交换
  • 其他操作
  max(Collection) :按自然排序,获取最大值
  max(Collection,Comparator) :按定制排序,获取最大值
  min(Collection) :按自然排序,获取最大值
  min(Collection,Comparator) :按定制排序,获取最大值
  int frequency(Collection,Object) :返回指定元素的出现次数
  void copy(List a,List b) :a的size()不能小于b的size(),将b的内容复制到a中
  List a = Arrays.asList(new Object[List.size()]);
  Collection.copy(a,b);
  boolean replaceAll(List list,Object a,Object b) :

返回一个线程安全的Xxx alt