集合框架的使用

集合框架概述

1.1为什么使用集合框架
	我们在java中学习过一个数据类型   ---  数组
	数组存在问题:  定容 (数组初始化的时候 一旦固定容量  从此就只能存储该容量的数据)
	如果我们一旦创建数组  发现数组的容量不够用了 此时就需要扩容就非常麻烦了。
	所以我们自己写了一个类MyArray
	在MyArray中定义方法getData()和setData(代码在下方) 
	此时我们可以手撕定义数组Java官方也能,所以 java官方就基于数组,
	根据不同的数据结构封装出来了很多的类,
	这些类统称为集合框架

MyArray.java

import java.util.Arrays;
public class MyArray {
     Object[] arr;
     int size=0;//获得数组的小标

    /*带参构造 自定义数组长度*/
    public MyArray(int size) {
        if (size<0){
            throw new RuntimeException("数组长度不合法");
        }
       arr = new Object[size];
    }
    /*setData()是为了设置数据*/
    public void setData(Object o){
        if (size>= arr.length){
            /*如果还想设置数据 但数据下标不够就扩容 使用该方法使得新的数组的长度变为原来的2倍*/
            Object[] newArr = Arrays.copyOf(arr, arr.length * 2);
            arr = newArr;
        }
        /*设置数据*/
        arr[size] = o;
        /*数组下标要自增*/
        size++;
    }
    /*getData()是为了获得数据*/
    public Object getData(int index){
        /*如果想得到某个数据而数组下标有误抛出这个异常*/
        if(index>=arr.length||index<0){
            throw  new ArrayIndexOutOfBoundsException("数组下标传入有误");
        }
        /*否则就将该值传给o返回给出去*/
        Object o = arr[index];
        return o;
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        MyArray m = new MyArray(3);
        m.setData("java01");
        m.setData("java02");
        m.setData("java03");
        m.setData("java04");
        System.out.println(m.getData(0));
        System.out.println("数组的长度为:"+m.arr.length);
       for (Object a:m.arr){
           System.out.println(a);
       }
    }
}
1.2集合框架体系


在这里插入图片描述

1.2.1 概念

Java集合框架(Java Collections Framework简称JCF)是为表示和操作集合,而规定的一种统一的标准的体系结构。集合框架包含三大块内容:对外的接口、接口的实现和对集合运算的算法。集合就是用于存储对象的容器。 只要是对象类型就可以存进集合框架中。集合的长度是可变的。 集合中不可以存储基本数据类型的值

1.2.2 集合和数组的区别

数组和集合相比数组的缺点是它长度是固定的,没有办法动态扩展。 而集合存储数据时是没有长度限制的,是可以动态扩展的。集合容器因为内部的数据结构不同,有多种不同的容器对象。这些容器对象不断的向上抽取,就形成了集合框架。

1.3 List接口及实现类
1.3.1 特点

(1)List集合是有序集合: 数据的添加和存储次序一致
(2)List集合可以存储重复的数据
(3)List集合中的数据可以通过下标访问
在这里插入图片描述
List集合中用到的方法 如下图(所有方法下面代码都会实现)
在这里插入图片描述

1.3.2 ArrayList实现类特点
  • 实现了List接口
  • 可以动态扩容(我们只管存,长度不够,底层会自动的扩容)
  • 通过下标可以快速访问数据
  • 查找快,插入删除慢
  • ArrayList底层是数组,对数组做了封装
  • 可以存储任意类型的数据,包括null
  • 数据按照存储次序排列
  • 数据可以重复
  • 多线程访问时不安全
1.3.3 ArrayList的创建和使用
1.3.3.1创建集合对象
List list = new ArrayList(); //创建一个集合对象 如果没有指定集合容器的长度默认为10
List list1 = new ArrayList(15);
1.3.3.2 添加元素
  /*添加元素操作,插入的值可以是任意类型*/
        list1.add("java01");
        list1.add("java02");
        list1.add(15.5);
        list1.add(18);
        list1.add(true);
        list1.add(new Date());
        list1.add(2,"hello");
        System.out.println(list1);
        list2.add("a");
        list2.addAll(list1);//将list1中全部元素添加到list2中
        System.out.println(list2);
1.3.3.2 删除元素
		list1.remove(2);//移除下标为2的元素
        System.out.println(list1);
        list1.clear();//清空集合中的元素.
        System.out.println(list1);
1.3.3.2 修改元素
		list1.set(1,"刘德华");//将下标为1设置为刘德华
        System.out.println(list1);
1.3.3.2 查找操作
/*查询操作*/
        Object o = list1.get(0);//根据下标获取元素
        System.out.println(o);
        int size = list1.size();//获得集合中元素的个数
        System.out.println(size);
        boolean f = list1.contains("java01");//判断集合中是否存在某个元素
        System.out.println(f);
        System.out.println(list1);
        int index = list1.indexOf("java02");//存在就返回第一次出现的位置否则返回-1
        System.out.println(index);
        /*遍历循环集合中的元素*/
        for (Object o2:list1){
            System.out.println(o2);
        }
1.3.4 ArrayList底层源码
从构造方法来入手
	new ArrayList(22) 底层声明了一个Object类型的数组 名字elementData
  	Object[] elementData
  	public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) { //大于0
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) { //等于初始化为一个空数组
            this.elementData = EMPTY_ELEMENTDATA;
        } else { //抛出一个异常
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

==========add("java01")======E理解为Object类型================  
   public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 扩容 
        elementData[size++] = e;  //把元素赋值给数组的相应位置
        return true;
    }
==========indexOf("java02") 判断元素在集合中第一次的位置=============
     public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i])) //和数组中的每个元素内容进行比对
                    return i;  //返回元素在集合中位置
        }
        return -1;
    }   

===========size() 请求数组的长度======================
 public int size() {
        return size;
    }   

============contain("java05")判断元素是否在集合中==============
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }
===============get(1) 获取指定位置的元素========
   public E get(int index) {
        rangeCheck(index); //判断指定的位置是否合法 

        return elementData(index);
    }  

    E elementData(int index) {
        return (E) elementData[index];
    } 

============toString() 为什么不打印对象的引用地址 
    [java01, java02, java03, java02]因为重写了Object里面的toString方法。
    
 public String toString() {
        Iterator<E> it = iterator();
        if (! it.hasNext())
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = it.next();
            sb.append(e == this ? "(this Collection)" : e);
            if (! it.hasNext())
                return sb.append(']').toString();
            sb.append(',').append(' ');
        }
    }   
    
    
通过对ArrayList方法的底层代码分析:底层就是对数组的操作。
    ArrayList的底层就是基于数组实现的。
1.4 LinkedList集合
	它是一个链表结构。
	LinkedList: 具有List的特征,底层以链表结构实现,
	可以进行头尾元素的添加删除;
1.4.1 LinkedList与ArrayList的区别
	ArrayList  底层体现出来的数据结构是 数组
	Linkedlist 底层体现出来的数据结构是 链表
1.4.2 LinkedList的使用
1.4.2.1 添加操作
 	    LinkedList linkedList = new LinkedList();
        linkedList.add("java01");
        linkedList.addFirst("java02"); //添加到头部
        linkedList.addLast("java03");//追加到尾部
        linkedList.addFirst("java04"); //追加到头部
        linkedList.addLast("java05");//追加到尾部
        System.out.println(linkedList);
1.4.2.1 删除操作
		linkedList.removeFirst();//移除头部元素
        System.out.println(linkedList);
        linkedList.remove(2);//移除指定位置的元素
        System.out.println(linkedList);
        linkedList.removeLast();//移除尾部的元素
        System.out.println(linkedList);
1.4.2.1 修改操作
linkedList.set(1,"java11");
1.4.2.1 查询操作
 //查询操作
        int size = linkedList.size();//求长度
        boolean empty = linkedList.isEmpty();//是否为空
        boolean b = linkedList.contains("java01");//判断元素是否在集合中
        Object o = linkedList.get(1);//根据下标获取指定位置的元素
        Object first = linkedList.getFirst();//获取第一个元素
        System.out.println(first);
        Object last = linkedList.getLast();
        System.out.println(last);
1.4.3 LinkedList底层源码
1.凡是查询源码 ,我们都是从类的构造方法入手:
     /**
     * Constructs an empty list.
     */
    public LinkedList() {
    }
 该类的构造方法内是空的,没有任何的代码。 但是该类中有三个属性。   
    transient int size = 0; //索引
   
    transient Node<E> first; //第一个元素对象 
   
    transient Node<E> last; //表示最后一个元素对象。
 
================ add的源码=====E:理解为Object类型==========================public boolean add(E e) {
        linkLast(e);
        return true;
    }


   void linkLast(E e) {
        final Node<E> l = last;
        //上一个节点   数据  下一个节点
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }
    
==================Node的源码 内部类=======================================   
   private static class Node<E> { //<E>泛型--object
        E item; //数据
        Node<E> next; //下一个节点
        Node<E> prev; //上一个节点

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
    ==================== get(1)-----获取元素========================
   public E get(int index) {
        checkElementIndex(index); //检查index下标是否正确。
        return node(index).item;  //李四Node对象
    }
 ========================node(index)=============================
 Node<E> node(int index) {
        //>> 位运算二进制运算 ----- size >> 1 一半的意思size/2
        if (index < (size >> 1)) { //前半部分
            Node<E> x = first; 
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {  //后半部分
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

1.4.4 总结LinkedList和ArrayList
 List:它是一个接口,该集合中的元素可以重复,而且是有序的(有下标)。
 ArrayList--->它的底层是数组结构,它的查询效率高,但是它的添加和删除效率低
	 (因为它要牵涉到数据的迁移。)
 	 常见方法: add();size();indexOf(); contains(); get();remove();isEmpty();
 LinkedList--->底层双向链表结构,它增加和删除效率高,但是它的查询效率低。
  	 常见的方法: 它的方法和ArrayList中的方法比较相似,它也有自己特有的方法: 
     addFirst() addLast() getFirst()  getLast()
2.1 Set接口及实现类

在这里插入图片描述

2.1.1 Set接口特点
  • Set接口是无序的
  • Set接口中的数据不允许重复
  • Set接口无法通过下标访问数据
  • 查找慢,插入删除快(底层数据结构是哈希表和红黑树)
  • Set集合使用equals()和hashCode()方法实现元素去重
2.1.2 HashSet实现类
2.1.2.1HashSet特点:
  • HashSet是Set接口的实现类
  • 线程不安全
2.1.2.2 创建HashSet对象
public class Test02 {
    public static void main(String[] args) {
   	 //如果没有指定容器大小 默认大小是16 装在因子是0.75
        HashSet  hashSet= new HashSet();

        HashSet  hashSet1 = new HashSet(16);//初始容器的大小(默认也是16)
        
        //loadFactor:--->0.7f 表示负载因子 当空间使用70%时 要求扩容
        HashSet hashSet2 = new HashSet(16,0.7f);
    }
}
2.1.2.3 添加元素
		HashSet hashSet = new HashSet();
        HashSet hashSet1 = new HashSet(16);
        hashSet.add("java01");
        hashSet.add("java02");
        hashSet.add("java03");
        hashSet.add("java04");
        hashSet.add("java02"); //无序不重复所以加不进去 hashet中元素只有4个
        System.out.println(hashSet);
        hashSet1.add("刘德华");
        hashSet1.add("张学友");
        hashSet1.add("黎明");
        hashSet.addAll(hashSet1);//添加多个元素
        System.out.println(hashSet);
2.1.2.3 删除元素
		System.out.println(hashSet);
        hashSet.remove("黎明");
        System.out.println(hashSet);
        hashSet.clear();//清空元素
        System.out.println(hashSet);
2.1.2.4 查询元素
		boolean c = hashSet.contains("刘德华");
        System.out.println(c);
        boolean empty = hashSet.isEmpty();
        System.out.println(empty);
2.1.2.5 遍历元素

1.foreach遍历

		/*foreach遍历*/
        for (Object o:hashSet) {
            System.out.println(o);
        }

2.迭代器遍历(Iterator)

迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,
可在容器对象container,例如链表或数组)上遍访的接口,
设计人员无需关心容器对象的内存分配的实现细节。
提供的方法:
hasNext():判断指针是否能够移动,能移动返回true否则返回false
next():指针移动并获取指定所在位置的元素
		Iterator it = hashSet.iterator();
        while (it.hasNext()){
            Object next = it.next();
            System.out.println(next);
        }
2.1.2.6 HashSet源码
从构造函数说起:
    /**
     * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
     * default initial capacity (16) and load factor (0.75).
     */
    public HashSet() {
        map = new HashMap<>();
    }
 在创建一个HashSet的对象时,底层创建的是HashMapHashMap底层后续更新
2.2 TreeSet实现类
TreeSet中的方法和HashSet中的方法一模一样 只是他们的实现不一样。
TreeSet 基于TreeMap 实现。TreeSet可以实现有序集合,但是有序性需要通过比较器实现。
2.2.1 特点
  • 有序
  • 不重复添加、删除、
  • 判断元素存在性效率比较高
  • 线程不安全
2.2.2 TreeSet操作

1.存储String类型的元素

		TreeSet treeSet = new TreeSet();
        treeSet.add("java01");
        treeSet.add("java02");
        treeSet.add("java03");
        System.out.println(treeSet);

2.存储一个对象类型

		treeSet.add(new Student("张三",18));
        treeSet.add(new Student("李四",17));
        treeSet.add(new Student("王五",19));
        System.out.println(treeSet);

此时编译器报错在这里插入图片描述
在这里插入图片描述
解决办法有两个:

第一个: 让Student类实现Comparable接口

//Student类
public class Student implements Comparable{
    String name;
    Integer age;

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return
                "name='" + name + '\'' +
                ", age=" + age;
    }
    /*排序:---返回如果大于0 表示当前元素比o大  如果返回-1 当前添加的元素比o小  返回0表示相同元素。*/
    @Override
    public int compareTo(Object o) {
        Student st = (Student) o;
        if(this.age>st.age){
            return 1;
        }else if (this.age < st.age){
            return -1;
        }
        return 0;
    }
}

//测试类
public class TreeSetDemo {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet();
        treeSet.add(new Student("张三",18));
        treeSet.add(new Student("李四",17));
        treeSet.add(new Student("王五",19));
        System.out.println(treeSet);
    }
}

第二种: 在创建TreeSet时指定排序的对象。
这种方法主要用到TreeSet集合中的带参构造
底层原理代码是:

public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }

所以要实现Comparator接口,因此我们可以自定义类实现Comparator接口即可,具体代码如下:
Student类:

public class Student{
    String name;
    int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return
                "name='" + name + '\'' +
                        ", age=" + age;
    }
}

自定义类实现Comparator接口

public class MyComparator implements Comparator{

    @Override
    //原理与ComparableTo那个相同
    public int compare(Object o1, Object o2) {
        Student s1 = (Student)o1;
        Student s2 = (Student) o2;
        if (s1.getAge()>s2.getAge()){
            return 1;
        }else if(s1.getAge()<s2.getAge()){
            return -1;
        }
        return 0;
    }
}

测试类:

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

        MyComparator myComparator = new MyComparator();
        TreeSet treeSet = new TreeSet(myComparator);

        treeSet.add(new Student("张三",18));
        treeSet.add(new Student("李四",17));
        treeSet.add(new Student("王五",19));
        treeSet.add(new Student("赵六",20));
        
        System.out.println(treeSet);
    }
}
注意:如果运行不起来记得看看导包是否错误
3.1 Map接口极其实现类

Map接口特点:

  • 以键值对方式存储数据(Collection是单值集合)
  • 键不能重复,键重复时,后面的数据会覆盖前面的数据
  • 可以存储null键值对
  • 数据无序
    在这里插入图片描述
    在这里插入图片描述
3.1.1 HashMap实现类

HashMap实现了Map接口,拥有Map接口的基本特点。HashMap线程不安全,效率高。HashMap的底层是由哈希表、链表加红黑树构成的

3.1.1.1 创建HashMap对象
		//默认初始化大小16 负载因子0.75
        Map hashMap1 = new HashMap();
        Map hashMap2 = new HashMap(16);
        Map hashMap3 = new HashMap(16,0.75f);
2.3.1.2 添加操作
		 /*添加操作*/
        //存储按键值对
        hashMap1.put("张三",18);
        hashMap1.put("李四",19);
        hashMap1.put("王五",20);
        //键不能重复 否则覆盖值
        hashMap1.put("王五",21);
        System.out.println(hashMap1);
        //添加多个键值对
        hashMap2.putAll(hashMap1);
        System.out.println(hashMap2);
        /*hashMap1.putIfAbsent():如果指定的key存在,则不放入hashmap1中 如果不存在则放入*/
        hashMap1.putIfAbsent("赵六",20);
        hashMap1.putIfAbsent("赵六",21);
        System.out.println(hashMap1);
2.3.1.3 删除操作
 		/*删除操作*/
        hashMap1.remove("王五");
        System.out.println(hashMap1);
        hashMap2.clear();//清空map容器
        System.out.println(hashMap2);
2.3.1.4 修改操作
		hashMap1.replace("李四",17);
        System.out.println(hashMap1);
2.3.1.5 查询操作
		/*查询操作*/
        hashMap1.put("王五",19);
        System.out.println(hashMap1);
        boolean f = hashMap1.containsKey("张三");//是否包含指定的key
        System.out.println(f);
        Object v = hashMap1.get("张三");//根据key获得value
        System.out.println(v);
        Set set = hashMap1.keySet();//获得key集合
        System.out.println(set);
        //遍历 根据key集合获得其值
        for (Object key:set) {
            Object value = hashMap1.get(key);
            System.out.println(key+"====>"+value);
        }
3.1.2 HashMap的底层原理
JDK1.7 和 JDK1.8他们是有区别得。
JDK1.7使用得数据结构: 数组+链表  而且链表插入模式为头部插入(造成死循环)。
jdk1.8使用得数据结构: 数组+链表+红黑树 而且链表得插入模式为尾部插入。

从构造函数入口:
/**
 * Constructs an empty <tt>HashMap</tt> with the default initial capacity
 * (16) and the default load factor (0.75).
 */
public HashMap() {
    this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

在这里插入图片描述JDK1.8 HashMap原理
存储元素使用put(key,value),根据key的hash计算出相应得哈希值,根据相应的算法求出该元素在数组中的位置, 如果求出的哈希值相同,则称为哈希冲突,会根据equals()来判断元素是否一致,如果equals不同,则挂在单向链表上(就是数据结构中的链地址法解决冲突), 如果哈希碰撞得个数超过8个,则把链表转换为红黑二叉树。
在这里插入图片描述

//底层代码如下
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                 //如果key得hash值相同,判断key得equals是否相同,替换原来得元素
                e = p;
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        // 判断链表得长度是否超过8个
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            // 把链表转换为红黑树结构
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }
3.1.2 Hashtable实现类
Hashtable也实现了Map接口,但是与HashMap相比有如下特点:
以键值对方式存储数据
键不能重复
数据无序键和值都不能存储null	
线程安全,效率低
Hashtable hashtable =new Hashtable();hashtable.put("aaa",100);//hashtable.put("aaa",null);hashtable.put(null,100);
hashtable.put("xxx",100);
System.out.println(hashtable);
4.1 泛型
1. 泛型就是限制我们得数据类型。

2.为什么使用泛型?
我们原来在定义集合时,是如下得定义方式:
    List list=new ArrayList();//该集合没有使用泛型
    list.add("java01");
    list.add("java02");

    String str= (String) list.get(0);//获取元素 需要进行强制类型转换
    System.out.println(str);
获取元素时,不方便对元素进行相应得其他操作。
3.使用泛型
List<类型>  list=new ArrayList<类型>(); 只能在该集合中存储指定得类型。
public static void main(String[] args) {
    List<String> list=new ArrayList<>();//这里就限制了集合中每个元素得类型。
    list.add("java01");
    list.add("hello"); //因为集合中只能添加String类型
    list.add("world"); //因为集合中只能添加String类型

    String s = list.get(0); //在获取元素时 默认就是相应得数据类型 而无需在进行转换

    //<K,V>:K:表示键得泛型  V:表示值得泛型
    HashMap<String,Integer> map=new HashMap<>();
    map.put("name",15);
    map.put("age",25);
    Set<String> keys = map.keySet();
}
4.自定义泛型
public class Test03 {
public static void main(String[] args) {
    //在创建泛型类对象时没有指定相应得泛型类型。则默认为Object类型
    Point p1=new Point();
    p1.setX(15);
    p1.setX("北纬50度");

    //这里得泛型必须都是对象类型
    Point<Integer> p2=new Point<Integer>() ;
    p2.setX(25);
    p2.setY(65);
    Integer x = p2.getX();
    Integer y = p2.getY();
    p2.show();

    Point<String> p3=new Point<>();
}
}


class Point<T>{

 private T x;
 
 private T y;
 
 public void show(){
     System.out.println("x坐标为:"+x+";y坐标为:"+y);
 }

public T getX() {
    return x;
}

public void setX(T x) {
    this.x = x;
}

public T getY() {
    return y;
}
public void setY(T y) {
    this.y = y;
}
}
5.1 总结

在这里插入图片描述
1) 需要数据唯一时,使用Set集合

  • 需要保持规则顺序,此时用TreeSet
  • 不需要指定顺序,此时用HashSet
  • 需要保证代码添加数据的次序,此时用LinkedHashSet

2) 不需要唯一时,使用List集合

  • 需要频繁增删操作时,使用LinkedList
  • 不需要频繁增删操作,需要做大量查询操作时,使用ArrayList

3) 如果以键值对方式存储数据时,使用HashMap

4) 通过类名记住集合框架类的结构和所属体系

List: ArrayList LinkedList
Set : HashSet TreeSet

  • 后缀名就是该集合所属的体系。

  • 前缀名就是该集合所属的数据结构。

  • 看到array:想到的就是数组,查询速度快。因为有角标是连续的内存地址。

  • 看到link:想到的就是链表,增删动作的速度快,而且要想到 add get remove+first /last的 方法

  • 看到hash:想到的就是哈希表,那么就具有唯一性,
    而且要想到元素需要覆盖hashcode方法 和equals方法

  • 看到tree:想到的就是二叉树,接下来想到的就是排序,然后就是两个接口 Comparable接口
    实现compareTo(To) Comparator接口 实现compare() 方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值