java集合框架基础知识总结

java集合框架总结

本人刚刚复习完集合框架,写在这里以便于记忆,还有自己的一些总结,与你们分享。

说到集合,我们首先得知道什么是集合。
集合其实就是java提供的一个容器,用来存放数据的容器
之前我们所学的数组,也可以存放数据,但是数组的长度是固定的,不方便我们使用,于是便有了集合。
再者,数组中存储的元素都是同一类型的元素,只可以存储一些基本的数据类型(int、String、Float、Char、…)
但是集合中存储的都是对象,而且对象的类型还可以不一致。
再开发中,一般使用对象居多的时候,我们可以选用集合来进行存储
再学习集合之前,我们需要先知道集合框架,如下图;
这是很重要的一张图
要想掌握集合的全部用法,应该从顶层向下学习
也就是,先学习Collection接口中的方法,他的方法子类都可以使用
在Collection接口中,定义的是所有单列集合中共性的方法,所有的单列集合都可以使用。
在Collection接口中,常用的共性方法用;

  1. public boolean add(E e):把指定的对象添加到当前的集合中
  2. public void clear();清空当前集合中的所有元素在这里插入代码片
  3. publin boolean remove(E e);把指定的对象从当前的集合中删除
  4. public boolean contains(E e);判断当前集合中是否包含指定的对象
  5. public boolean isEmpty();判断当前集合是否为空
  6. public int size();返回集合中元素的个数
  7. public Object[] toArray();把集合中的元素,存储到数组中
    看代码
public class demo1 {

    public static void main(String[] args) {

        Collection coll = new ArrayList(); //面向对象中的多态

        /**
         * add添加元素
         */
        coll.add(1);
        coll.add("abc");
        coll.add(1.23);
        coll.add("张三");
        System.out.println(coll);
        System.out.println("__________________________");

        /**
         * remove删除元素
         */
        coll.remove(1);
        System.out.println(coll);
        System.out.println("__________________________");

        /**
         * contains判断当前集合中是否包含指定的对象
         */
       boolean a = coll.contains(1.23);
        System.out.println(a);//如果存在就返回true,否则返回false
        System.out.println("__________________________");
        /**
         *  isEmpty判断当前集合是否为空
         */
      boolean b =  coll.isEmpty();
        System.out.println(b);//如果为空就返回true,否则返回false
        System.out.println("__________________________");

        /**
         * size返回集合中元素的个数
         */
          Integer i = coll.size();//推荐用Integer,不建议用int
        System.out.println(i);
        System.out.println("__________________________");
        /**
         * toArray把集合中的元素,存储到数组中
         */
        Object[] obj =  coll.toArray();
        System.out.println(obj);//[Ljava.lang.Object;@4554617c   这个数组的地址值
        for (Object o : obj) {
            System.out.println(o);  //输出遍历的数组    abc  1.23   张三
           }
        System.out.println("__________________________");

        /**
         * clear 清空元素
         */

       coll.clear();
        System.out.println(coll);

        /**
         * 判断集合是否为空
         */
        boolean d =coll.isEmpty();
        System.out.println(d);//true
    }
}

输出结果;
在这里插入图片描述

注意:Collection接口中没有带索引的方法;
在使用过程中,顶层不是接口就是抽象类,无法创建对象使用,需要使用底层的子类创建对象使用

在遍历集合中,还需要涉及到一个Iterator接口,也就是迭代。
迭代的概念;Collection集合元素的通用获取方式,再取元素之前要先判断集合中有没有元素,如果有,就把这个元素取出来,继续在进行判断,如果还有就再取出来,一直把集合中的所有元素取出,这种取出方式专业术语就叫做迭代

其中有两个 比较常用的方法;
(1),boolean hasNext();如果仍有元素就可以迭代,返回的就是true,判断集合中还有没有下一个元素,有就返回true,没有就返回false
(2),E next()返回迭代的下一个元素;取出集合中的下一个元素
Iterator也是一个接口,我们无法直接使用,需要使用Iterator接口的实现类。
在Collection接口中有一个方法,Iterator(),这个方法的返回值就是迭代器的实现类
看代码

  Collection coll = new ArrayList(); //面向对象中的多态

        /**
         * add添加元素
         */
        coll.add(1);
        coll.add("abc");
        coll.add(1.23);
        coll.add("张三");
        System.out.println(coll);

        Iterator it = coll.iterator();
       boolean a = it.hasNext();
        System.out.println(a);//输出结果为true
        Object obj =it.next();
        System.out.println(obj);//输出结果为1
    }
}

也可以添加一个while循环,遍历出集合元素


        Iterator it = coll.iterator();
        while(it.hasNext()){
           Object obj =  it.next();
            System.out.println(obj);//输出结果;1  abc   1.23  张三
        }

也可以添加一个for循环


       for(Iterator it = coll.iterator();it.hasNext();){
           Object obj = it.next();
           System.out.println(obj);//输出1  abc   1.23   张三
       }

原理分析
在这里插入图片描述

还有种遍历集合的方式,高级for循环(也叫增强for循环)
增强for循环(也称为for each循环)是jdk 1.5以后出来的一个高级的for循环,专们用来遍历数组,它的内部原理其实是Iterator迭代器,所以在遍历的过程中,不能对集合进行增删操作;

格式;
for(集合/数组的数据类型 变量名:集合名/数组名){
sout(变量名)
}

上述代码中,集合转为数组部分,就是用的增强for循环
注意;
新for循环必须有被遍历的目标,目标只能是Collection或者是数组,新式for仅仅作为遍历操作出现。

在正式的学习集合之前,还要掌握一些泛型的基本知识。(在这里不一一列举)

直接看List接口;
List接口是继承的Collection接口,所以Collection接口中的方法,在List接口中也适用。
List接口的特点;

  • 有序集合,存储元素,与取出元素的顺序是一致的。
  • 有索引,包含了一些带有索引的方法
  • 允许存储一些重复元素
    List接口中的一些常用方法
    (1),public void add(int index,E element);将指定的元素,添加到该集合中的指定位置上;
    (2),public E get(int index);返回集合中指定的元素,
    (3),public E remove(int index):移除列表中指定位置的元素,返回的是被移除的元素;
    (4),public E set (int index,E element):用指定的元素替换集合中指定元素的位置,返回值是更新的元素。
    注意:在操作索引的时候,要注意防止索引越界,引发异常。
    代码实现;
public class demo1 {
    public static void main(String[] args) {

        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("a");
        System.out.println(list);
        //添加元素
        list.add(2,"hbsi");
        System.out.println(list);
       //移除元素
     String b =  list.remove(2);
        System.out.println(b);
        System.out.println(list);

        //返回指定元素
       String v = list.get(1);
        System.out.println(v);
        System.out.println(list);

        //替换元素
        String a = list.set(4,"asc");
        System.out.println(a);
        System.out.println(list);

        //遍历元素
        for (int i = 0; i < list.size(); i++) {
           String x =  list.get(i);
            System.out.println(x);
        }
//迭代器
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
          String s =  it.next();
            System.out.println(s);
        }

        //foreach
        for (String s : list) {
            System.out.println(s);
        }

        list.get(6);//越界异常    IndexOutOfBoundsException

    }
}

List集合的子类;
ArrayList集合与LinkedList集合 都实现了List接口,List接口中的方法,他们都可以用。

ArrayList集合:
他的底层是数组,特点:增删快,查询慢。
ArrayList集合中的方法大部分大继承与List接口

LinkedList集合;
(1),底层是链表结构(双向链表),查询慢,增删快。
(2),里边包含了大量操作首尾元素的方法。


什么是双向链表?
图解
在这里插入图片描述

此集合中常用的方法;

-public void addFirst(E e) :将指定元素插入此列表的开头。
-public void addLast(E e) :将指定元素添加到此列表的结尾。
-public E getFirst() :返回此列表的第一个元素。
-public E getLast() :返回此列表的最后一个元素。
-public E removeFirst() :移除并返回此列表的第一个元素。
-public E removeLast() :移除并返回此列表的最后一个元素。
-public E pop() :从此列表所表示的堆栈处弹出一个元素。
-public void push(E e) :将元素推入此列表所表示的堆栈。
-public boolean isEmpty() :如果列表不包含元素,则返回true。

代码演示;

	public class LinkedListDemo { 
	public static void main(String[] args) { 
	LinkedList<String> link = new LinkedList<String>(); 
	//添加元素     
	link.addFirst("abc1"); 
	link.addFirst("abc2"); 
	link.addFirst("abc3"); 
	System.out.println(link); 
	// 获取元素 
	System.out.println(link.getFirst()); 
	System.out.println(link.getLast()); 
	// 删除元素 
	System.out.println(link.removeFirst()); System.out.println(link.removeLast()); 
	while (!link.isEmpty()) { 
	//判断集合是否为空 
	System.out.println(link.pop()); 
	//弹出集合中的栈顶元素 
	   }
	System.out.println(link); 
	  }
	}

LinkedList集合也可以作为堆栈,队列的结构使用;
下一个集合;
Vector集合 底层也是数组。(JDK1.0开始)

(由于线程安全,查询速度慢,JDK1.2以后被ArrayList取代)
方法参要;(了解即可)
在这里插入图片描述
其中的方法大部分与ArrayList大同小异
但是他的接口Serializable很重要(序列化)

Set接口
java.util.Set接口 extends Collection接口;
Set接口的特点;
(1)不允许存储重复的元素
(2)没有索引,也没有带索引的方法,也不可以使用普通的For循环遍历
(3)Set接口中,元素无序

HashSet集合;
java.util.HashSet集合 implements Set 接口
特点;
(1),不如许存储重复的元素
(2),没有索引,没有带索引的方法,也不能使用普通的for循环遍历
(3),是一个无序集合,存储元素和取出元素的顺序有可能不一致
(4),底层是哈希表结构(查询的速度非常快)

代码展示;

package Day6_22;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Demo01 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();

        set.add("a");
        set.add("b");
        set.add("c");
        set.add("a");
//迭代器遍历
        Iterator<String> it = set.iterator();
   while(it.hasNext()){
       String b =it.next();
       System.out.println(b);
   }
   //for增强遍历
        for (String s : set) {
            System.out.println(s);
        }

    }
}

HashSet集合存储数据的结构(哈希表)
(1),首先需要认识什么是哈希值
哈希值:是一个十进制的整数,由系统随机的给出
(其实就是对象的地址值,是一个逻辑地址,模拟出来的地址,并不是数据实际存储的物理地址)
(2),在Object顶级父类中,有一个方法,可以获取对象的哈希值
int hashCode();返回的就是int类型的对象的哈希值

获取hashCode的代码实现;
在这里插入图片描述
其中有两个比较特殊,“重地”与“通话”这两个字符串的哈希值是相等的。
HashSet集合存储数据的结构(哈希表)简述

在JDK1.8版本之前:哈希表=数组+链表
在JDK1.8之后(包含1.8)之后;
哈希表=数组+链表/哈希表=数组+红黑树

特点:查询速度快
初始容量:16
数组结构:(把元素进行分组,(相同哈希值的元素是一组)链表/红黑树结构把相同哈希值的元素连接到一起)

图解(来源网络)
在这里插入图片描述
基本代码实现

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

        Set<String> set = new HashSet<>();
        set.add("abc");  //这是一个重复元素,(不允许存储重复元素)
        set.add("abc");
        set.add("重地");
        set.add("通话");
        System.out.println(set);//[重地, 通话, abc]
        System.out.println("abc".hashCode());
    }

原理代码分析,(图解,来源网络)
在这里插入图片描述

HashSet存储自定义类型的元素
需要重写对象中hasCode和equals方法,建立自己的比较方式,才可以保证HashSet集合中的对象唯一
图解(来源网络)
在这里插入图片描述
下一个集合;
LinkedHashSet集合
java.util.linkedHashSet集合 extends HashSet集合
LinkedHashSet集合的特点;
底层是;
哈希表+链表;
这里多了一个链表,他的目的就是为了记录元素的存储数据,保证集合中的元素是有序的

代码实现;

public static void main(String[] args) {
 Set<String> set = new LinkedHashSet<String>(); 
 set.add("bbb"); 
 set.add("aaa");
  set.add("abc"); 
 set.add("bbc"); 
 Iterator<String> it = set.iterator();
  while (it.hasNext()) { System.out.println(it.next()); }
       } 
   }
   结果:bbb aaa abc bbc

输出的结果,按照输入的数据顺序展示

一个新的类(工具类)
java.utils.Collections : 是一个集合工具类;
常用方法;

-public static boolean addAll(Collection c, T… elements) :往集合中添加一些元素。 ------public static void shuffle(List<?> list) 打乱顺序 :打乱集合顺序。
-public static void sort(List list) :将集合中元素按照默认规则排序。
-public static void sort(List list,Comparator<? super T> ) :将集合中元素按照指定规则排 序。

方法的代码实现(来源于网络);
在这里插入图片描述

sort的简单应用(默认的升序排列);

package Day6_22;

import java.util.ArrayList;
import java.util.Collections;

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

        ArrayList<String> array = new ArrayList<>();

        array.add("c");
        array.add("b");
        array.add("a");
        array.add("d");

        System.out.println(array);
        Collections.sort(array);
        System.out.println(array);
        System.out.println("________________________________");

        array.add("1");
        array.add("3");
        array.add("5");
        array.add("2");
        System.out.println(array);

        Collections.sort(array);
        System.out.println(array);
        System.out.println("________________________________");

        array.add("小明");
        array.add("销量");
        array.add("重地");
        array.add("通话");

        System.out.println(array);
  Collections.sort(array);
        System.out.println(array);

        ArrayList<String> list = new ArrayList<>();
        list.add("小明");
        list.add("小红");
        list.add("小蓝");
        list.add("小紫");
        list.add("小绿");
        list.add("小粉");
        list.add("小花");
        list.add("小亮");
        list.add("小波");
        list.add("小男孩");
        list.add("小二");

        Collections.sort(list);
        System.out.println(list);//[小二, 小亮, 小明, 小波, 小男孩, 小粉, 小紫, 小红, 小绿, 小花, 小蓝]
    }
}

输出结果;

"C:\Program Files\Java\jdk1.8.0_74\bin\java" "-javaagent:D:\ide...............
[c, b, a, d]
[a, b, c, d]
________________________________
[a, b, c, d, 1, 3, 5, 2]
[1, 2, 3, 5, a, b, c, d]
________________________________
[1, 2, 3, 5, a, b, c, d, 小明, 销量, 重地, 通话]
[1, 2, 3, 5, a, b, c, d, 小明, 通话, 重地, 销量]
[小二, 小亮, 小明, 小波, 小男孩, 小粉, 小紫, 小红, 小绿, 小花, 小蓝]

Process finished with exit code 0

注意;
sort(List list)使用的前提;
被排序的集合里边存储的元素,必须实现Comparable接口,重写接口中的compareTo定义的排序规则

图解:
在这里插入图片描述

Comparable和Comparator的区别;
Comparable:自己(this)和别人(参数)比较,自己需要实现Comparable接口,并且重写比较的规则compareTo方法
Comparator:相当于找一个第三方裁判,比较两个

上代码;

package Day6_22;


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

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

        ArrayList<Integer> arr = new ArrayList<>();

        arr.add(4);
        arr.add(6);
        arr.add(2);

        System.out.println("__________________");

        Collections.sort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                //return o1 - o2;//升序
                return o2 - o1;//降序
            }
        });

        System.out.println(arr);

        ArrayList<Person> list = new ArrayList<>();

        list.add(new Person("a古力娜扎", 12));
        list.add(new Person("f周润发", 50));
        list.add(new Person("s大黄蜂", 80));
        list.add(new Person("b雷神", 20));

        System.out.println("__________________");
        System.out.println(list);
        Collections.sort(list, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge() - o2.getAge();
            }
        });
        System.out.println("__________________");
        System.out.println(list);


        Collections.sort(list, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
              int result =  o1.getAge()-o2.getAge();
              if(result==0){
                 result = o1.getName().charAt(0) -o2.getName().charAt(0);
              }
              return result;
            }
        });

        System.out.println("__________________");
        System.out.println(list);
    }
}

Comparable和Comparator两个接口的区别;
Comparable:强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法 被称为它的自然比较方法。只能在类中实现compareTo()一次,不能经常修改类的代码实现自己想要的排序。实现 此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)进行自动排序,对象可以用作有序映射中 的键或有序集合中的元素,无需指定比较器。

Comparator强行对某个对象进行整体排序。可以将Comparator 传递给sort方法(如Collections.sort或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用Comparator来控制某些数据结构(如有序set或 有序映射)的顺序,或者为那些没有自然顺序的对象collection提供排序。

代码分析;
在这里插入图片描述
Map集合(重点)
Map集合与Collection中的集合的区别;
Collection中的集合,元素都是孤立存在的(单身狗),向集合中存储的元素都是一个一个的单个元素。
Map中的集合,元素都是成对的出现的,(夫妻)。每个元素都由键与值两个部分组成,通过键可以找到对应的值。
SO,Collection中的集合是单列集合,Map中的集合是双列集合。
注意;
Map集合中不可以包含重复的键,值可以重复:每一个键都只能对应一个唯一得值。

java.util.Map<K,V>集合
Map集合的特点;
(1),Map集合是一个双列集合,一个元素包含两个值(Key,Value)
(2),Map 集合中的元素,Key和Value的数据类型可以相同,也可以不同
(3),Map集合中的元素,Key不允许重复,但是value可以重复
(4),Map集合中的元素,Key和Value是一一对应的

HashMap集合;
java.util.HashMap<K,V>集合implements Map<K,V>接口
(1),HashMap集合的底层是哈希表,特点;查询的速度特别快
(2),JDK1.8之前:数组+单向链表 ,jdk1.8之后 :数组+单向链表/红黑树(链表的长度超出8):提高查询的速度
(3),HashMap集合是一个无序集合

LinkedHashMap集合
java.util.LinkedHashMap<K,V>集合extends HashMap(K,V)
LinkedHashMap集合的特点;
(1),LinkedHashMap集合底层是哈希表+链表(保证迭代的顺序)
(2),LinkedHashMap集合是一个有序的集合,存储元素和取出元素的顺序一致

Map集合中的常用方法;
public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。
public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的 值。
public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
public Set keySet() : 获取Map集合中所有的键,存储到Set集合中。
public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)

(1)put方法(来源网络)
在这里插入图片描述

(2)remove方法(来源网络)
在这里插入图片描述

(3),get方法(来源网络)
在这里插入图片描述
(4)containKey方法(来源网络)
在这里插入图片描述

遍历Map集合
Map集合的第一种遍历方式
通过键找值得方法
Map集合中的方法;Set keySet() ;返回的就是此映射中包含的键Set视图
实现的步骤;
(1),使用Map集合中的方法keySet(),把Map集合中所有的Key取出来,存储带一个Set集合中
(2),遍历Set集合,获取Map集合中的每一个key
(3),通过Map集合中的方法get(key),通过key找到value

Map集合的第二种遍历方式;
Set<Map.Entry<K,V>> entrySet()遍历集合
Map.Entry(K,V);在Map接口中有一个内部接口Entry
作用;
当Map集合创建,那么就会在Map集合中创建一个Entry对象,用来记录键与值(键值对对象,键与值得对应关系)
步骤;
(1),使用Map集合中的方法,entrySet(),把Map集合中的多个Entry对象取出来,存储到一个Set集合中
(2),遍历Set集合,获取每一个Entry的值
(3),使用Entry对象中的方法,getKey()和getValue()获取键与值

来源(网络)
在这里插入图片描述
在HashMap中存储自定义类型的键值
其中,Map集合保证Key是唯一的
作为Key的元素,必须重写hashCode方法和equals方法,以保证key的唯一;(其用法相同)

代码演示;student学生类;

public class Student {

private String name; 
private int age; 
public Student() { 
}
public Student(String name, int age) {
 this.name = name; 
 this.age = age; 
 }
 public String getName() { 
 return name;
  }
  public void setName(String name) {
   this.name = name; 
   }
   public int getAge() { 
   return age; 
   }
   public void setAge(int age) { 
   this.age = age; 
   }
   @Override
    public boolean equals(Object o) { 
    if (this == o) return true;
     if (o == null || getClass() != o.getClass()) return false; 
     Student student = (Student) o; 
     return age == student.age && Objects.equals(name, student.name); 
     }
     @Override 
     public int hashCode() {
      return Objects.hash(name, age); 
      } 
      }

测试类

public class HashMapTest { 
public static void main(String[] args) { 
//1,创建Hashmap集合对象。
 Map<Student,String>map = new HashMap<Student,String>(); 
 //2,添加元素。 
 map.put(newStudent("lisi",28), "上海"); 
 map.put(newStudent("wangwu",22), "北京"); 
 map.put(newStudent("zhaoliu",24), "成都");
 map.put(newStudent("zhouqi",25), "广州");
  map.put(newStudent("wangwu",22), "南京");
   //3,取出元素。键找值方式 
   Set<Student>keySet = map.keySet();
    for(Student key: keySet){ Stringvalue = map.get(key); System.out.println(key.toString()+"....."+value); } } }

HashMap中的子类LinkedHashMap

java.util.LinkedHashMap<K,V> extends HashMap<K,V>

Map 接口的哈希表和链表实现,具有可预知的迭代顺序
底层原理:哈希表+链表(记录元素的顺序)(用法相同)

Hashtable<K,V>集合

HashTable:底层也是一个哈希表,是一个线程安全的集合,单线程集合,速度慢
HashMap:底层是一个哈希表,是一个线程不安全的集合,多线程集合。速度快
HashMap集合(之前学的所有的集合):可以存储null值null键
HashTable集合:不可以存储null值null键
Hashtable和Vector一样,在jdk1.2版本以后就被取代了(HashMap,ArrayList)
Hashtable的子类Properties依然活跃在历史的舞台;
Properties集合是唯一一个和IO流相结合的集合

(来源网络)
在这里插入图片描述

在JDK9中集合的优化;
JDK9的新特性;
List接口,Set接口,Map接口:里边增加了一个静态的方法of,可以给集合一次性的添加多个元素
static List of (E…elements)
使用前提;
当集合中存储的元素的个数已经被确定了,不在改变的时候
注意;
(1),of方法只适用于List接口,Set接口,Map接口,不适用于接口的实现类;
(2),of方法的返回值是一个不能改变的集合,集合不能在使用add,put方法,添加元素,会抛出异常
(3),Set接口和Map接口在调用of方法的时候,不能有重复的元素,否则会抛出异常

代码演示;

public static void main(String[] args) {
 Set<String> str1=Set.of("a","b","c"); 
 //str1.add("c");这里编译的时候不会错,但是执行的时候会报错,因为是不可变的集合 
 System.out.println(str1); 
 Map<String,Integer> str2=Map.of("a",1,"b",2); 
 System.out.println(str2);
  List<String> str3=List.of("a","b"); 
  System.out.println(str3);
   }

还有一些其他集合,这些只是最为常用得几个。如有不足,请在下方评论区共勉。
注意:转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值