javaSE笔记3

本文详细介绍了Java集合框架中的核心概念,包括集合与Map接口,以及ArrayList、LinkedList、Vector、HashSet、TreeSet和HashMap等实现类。讨论了它们各自的数据结构、特点、操作方法和性能,强调了泛型、线程安全、迭代器和自定义排序等方面的知识。此外,还涵盖了集合的初始化容量、扩容策略以及相关工具类Collections的使用。
摘要由CSDN通过智能技术生成

集合
1、集合是一个存放数据的容器,可以来容纳其他类型的数据。【数组其实就是一个集合】它主要包括Collection和Map集合
2、集合只能存放对象的引用,Java中每一种基本数据类型都有对应的引用类型。例如在集合中存储一个int型数据时,要先自动转换成Integer类后再存入;
3、集合存放的是对对象的引用,对象本身还是存放在堆内存中;
4、同一个集合可以存放不同类型、不限数量的数据。
5、集合在java中本身是一个容器,是一个对象。集合任何时候存储的都是“引用”。
6、在java中每一个不同的集合底层会对应不同的数据结构。往不同的集合中存储元素,等同于及那个数据放到了不同的数据结构当中。
   使用不同的集合等同于使用了不同的数据结构存储数据。
7、数据存储的结构就是数据结构。不同的数据结构,数据存储的方式不同。例如:数组、二叉树、链表、哈希表等。
8、所有的集合类和集合接口都在java.util包下。
9、在java中集合分为两大类:
   一类是单个方式存储元素:
       单个方式存储元素,这类集合的超级父接口是:java.util.Collection;【所有集合都继承java.lang.Iterable接口,表示可迭代的】
   一类是以键值对的方式存储元素的:
       以键值对的方式存储元素,这一类的集合中超级父接口:java.util.Map;
10、单个方式存储元素的集合继承结构:
    java.lang.Iterable
        java.util.Collection
            java.util.List和java.util.Set
11、常用方法:
    java.lang.Iterable接口的常用方法
        1.Iterator<T> iterator() 
    java.util.Collection继承了Iterable接口
        1.Iterator iterator()
    java.util.Iterator常用方法
        1.boolean hasNext();返回true表示还有元素可以迭代,返回false表示已经没有更多的元素。只是表示有没有下一个元素并不会移动迭代器指针。
        2.Object next();让迭代器前进一位(迭代器初始位置是在第一个元素之前),并且将指定的元素返回(拿到)。
        3.void remove();删除的是迭代器指向的当前元素
        集合结构发生改变(添加或删除元素)的时候必须重新获取迭代器对象,否则会抛出java.util.ConcurrentModificationException异常
        在迭代元素的过程中一定要使用迭代器Iterator的remove方法删除元素,不要使用集合自带的remove方法。
12、java.util.List:存储元素的特点:“有序可重复”,存储元素有下标。[“有序”说的是存进去是这个顺序取出来还是这个顺序。这里的顺序不是说大小顺序]【有序是因为List集合都有下标,从0开始以1递增】
    java.util.Set:存储元素的特点:“无序不可重复”,无序表示存进去是这个顺序,取出来就不一定是这个顺序了,Set集合没有下标。
13、java.util.List的实现类
    ArrayList:采用了“数组”这种数据结构,非线程安全的。
    LinkedList:采用了“双向链表”数据结构。
    Vector:采用了“数组”数据结构,线程安全的。Vector所有的方法都有synchronized关键字修饰,所以是线程安全的,但是效率较低,保证线程安全有别的方案,Vector使用较少了。
14、java.util.Set接口的实现类:
    HashSet:在new的时候,实际上底层new了一个HashMap集合(向HashSet集合中存储元素实际上是存储到了HashMap集合当中了).HashMap是一个数据表数据结构。
    Set接口被SortedSet接口继承。
        SortedSet集合存储元素的特点:由于继承了Set接口也是无需不可重复的,但是放在SortedSet集合中的元素可以自动排序(又称为可排序集合)。
            SortedSet接口实现类:TreeSet类:newTreeSet集合的时候,实际上在底层new了一个TreeMap集合,在TreeSet中存储元素的时候,实际上是存储到了TreeMap集合中。TreeMap底层采用了二叉树数据结构。
15、一类是以键值对的方式存储元素的集合中超级父接口:java.util.Map;
    1.Map集合和Collection没关系
    2.Map集合以key和value这种键值对的方式存储元素。 
    3.key和value都是存储java对象的内存地址。
    4.所有Map集合的key的特点是无需不可重复的。(Map集合的key和Set集合存储元素特点相同,存储到Set集合当中的元素就相当于存储到Map集合的key当中了)
16、Map接口的常用实现类:
    HashMap:集合采用hash表数据结构,是非线程安全的。
    SortedMap接口继承了Map接口:放在SortedMap集合的key部分的元素会自动按照大小顺序排序,称为可排序数组。
        SortedMap接口常用实现类TreeMap:TreeMap集合是一个二叉树。
    Hashtable:集合采用hash表数据结构,是线程安全的,其中所有的方法都带有synchronized关键字,效率较低,现在使用较少了,因为控制线程安全有其他更好的方案。
        Properties类继承了Hashtable类:
            Properties(属性类):存储元素的时候也是采用key和value的形式存储,并且key和value只支持String类型的,不支持其他类型的。
17、总结继承关系
    Collection(接口)
        List(接口) 
            ArrayList(实现类)
            LinkedList(实现类)
            Vector(实现类)
        Set(接口):往set集合中存储元素就相当于存储到Map集合的key部分。
            HashSet(实现类):往这个集合中存储元素就相当于存储到了HashMap集合的key部分
            SortedSet(接口)
                TreeSet(实现类):往这个集合中存储元素就相当于存储到了TreeMap集合的key部分
    Map(接口):Map集合的key和Set集合存储元素的特点相同
        HashMap(实现类)
        Hashtable(实现类)
            Properties(实现类)
        SortedMap(接口)
            TreeMap(实现类):底层是二叉树。TreeMap集合的key可以自动按照大小顺序排序。
18、java.util.collection;Collection中能存储什么类型?
        没有使用“泛型”之前,Collection中可以Object的所有子类型。
        使用了“泛型”之后,Collection中只能存储某个具体的类型。
    1.boolean add(Object e);将e添加到当前集合中。  
    2.boolean addAll(Collection<? extends E> c);将“集合c”中所有元素添加到当前集合。
    3.void clear();从当前集合中删除所有元素
    4.boolean contains(Object obj);如果当前集合包含obj则返回true【底层调用了equals,比较对象的内容】
    5.int size();获取集合中元素的个数,不是获取集合的容量。
    6.boolean remove(Object o);从当前集合中删除指定元素“o”(如果存在多个则只是删除单个实例),删除成功返回true,底层会调用equals比较时候集合中是否存在“o”元素。
    7.boolean isEmpty();判断集合是否为空,为空则返回true
    8.Object[] toArray();调用这个方法可以将集合转换成一个数组
19、存放在集合中的类型一定要重写equals方法。

List
1、List既然是Collection的子接口,肯定有Collection接口的方法又有List接口特有的方法。
2、List接口新增的方法
    1.void add(int index,Object elements);将指定的元素插入此列表中的指定位置,后续元素往后位移【不带index默认向集合尾部添加元素】
    2.Object get(int index);根据下标获取元素
    3.int indexOf(Object o);返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。 
    4.int lastIndexOf(Object o);返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。 
    5.Object set(int index, Object element);用指定的元素替换此列表中指定位置的元素。 
    6.Object remove(int index);删除该列表中指定位置的元素
3、因为List集合有下标,所以List集合有自己比较特殊的遍历方式,通过下标遍历。
    for (int i = 0;i < list.size();i++) {
        Object obj = list.get(i);
        //对obj进行操作
    }

ArrayList
1、初始化容量是10.(底层先创建了一个长度为0的数组,当添加第一个元素的时候,初始化容量为10)
2、ArrayList底层数Object类型的数组。
3、Constructor常用构造方法
   public ArrayList().构造一个初始容量为10的空列表
   public ArrayList(Collection<? extends E> c).构造一个包含指定元素的列表,按照他们由集合的迭代器返回顺序
   public ArrayList(int initialCapacity).构造一个具有指定容量的空列表
4、ArrayList每次扩容是原容量的1.5倍。(ArrayList底层是数组,怎样优化,尽可能少的扩容)
5、ArrayList集合和Vector集合底层都是数组,ArrayList是非线程安全的,Vector是线程安全的。

LinkedList
1、单向链表数据结构
   “节点”是单链表中基本的单元。
   每一个节点Node都有两个属性。
    一个是:存储的数据
    另一个是:写一个节点的内存地址
2、双向链表数据结构
   每一个节点Node都有三个属性。
    一、前一个结点的内存地址
    二、节点中存储的数据
    三、后一个节点的内存地址
3、链表的优缺点:
    优点:随机增删元素效率较高。(因为删除(或增加)元素不涉及到大量元素位移的情况)
    缺点:查询效率较低,每一次查找某个元素的时候都需要从头节点开始往下遍历。
4、ArrayList和LinkedList
   ArrayList:底层是数组,在数组的末尾增加元素是不涉及到大量元素位移的情况的,所以效率基本不受影响。
   一般加元素都是往末尾加的,所以ArrayList用的比LinkedList多。
5、LinkedList没有初始化容量。
   最初的那个链表对象没有任何元素。first和last引用都是null。
6、链表中的元素在空间存储上,内存地址不连续。   

Vector
1、与ArrayList相同底层也是一个数组,不同的是ArrayList是非线程安全的,Vector是线程安全的。
2、Vector初始化容量为10。
3、Vector扩容之后是原容量的2倍(ArrayList扩容后是原容量的1.5倍)
4、java.util.Collections;是java的集合工具类。
   怎样将List集合转换成线程安全的。
   Collections.synchronizedList(List<Object> list);

泛型机制
1、JDK5.0之后推出的新特性:“泛型”。
2、List集合支持泛型:以ArrayList集合为例展示使用泛型的语法结构。
   List<类型名1> 变量名 = new ArrayList<类型名2>();【编译之后会把它改写成:List<类型名1> 变量名 = new ArrayList();“类型名2写不写意义不大”。JDK8之后才可以这么用,JDK8以前“<类型名2>”不能省略】
    注意:1.“类型名1”必须和“类型名2”相同,否则编译报错。
          2.只写“类型名1”整个集合的泛型类型就已经起作用了,类型名2可以省略(也可以只写一对尖括号),但是类型名1不能省略。(只写类型名2,整个List集合的泛型机制不起作用)。          
   如果类型名是Animal,就表示上述List集合中只允许存储Animal类型的数据。(指定了List只能存储Animal类型,List集合只能存储Animal类型或者Animal类型的子类型)
3、有泛型类型的类不指定泛型类型的,默认的泛型类型都是Object类型。
4、public interface Iterator<E> {
        E next();
   }
   如果指定了迭代器的泛型类型(迭代类型),那么Iterator类的next方法就会返回“迭代类型”。如果不指定迭代器的迭代类型,next方法返回的都是Object类型的【说明了有泛型类型的类如果要是没有指定泛型类型,那么默认的泛型类型就是Object】。
5、泛型这种语法机制,只在编译阶段起作用,是给编译器参考的。(运行阶段意义不大)
6、使用了泛型的好处:
    1.集合中的元素类型统一了。
    2.从集合中取出来的元素是泛型指定的类型,不需要进行大量的“向下转型”。
   使用泛型的缺点:
    1.导致集合中存储的元素缺乏多样性。
    2.大都数业务中,集合中元素的类型还是统一的。所以这种泛型被大家认可。
7、迭代器的迭代类型必须和集合的泛型类型一致,否则编译报错。
8、自定义泛型类型的语法结构:“<>”里面一般是写“E”或者“T”
        [修饰符列表] class 类名<泛型类型名1,泛型类型名2,泛型类型名3,......> {
            
        }
    定义接口也可以使用泛型类型,不仅有内部类,还有内部接口。
    new自定义类型对象(带泛型类型的):
        类名<泛型类型名1,泛型类型名2,泛型类型名3,......> 变量名 = new 类名();【“<泛型类型名1,泛型类型名2,泛型类型名3,......>”泛型类型的格式必须与定义时的泛型类型个数一致】

    例子:使用泛型可以动态变换方法的参数类型和返回值类型。
    public class Test02<A,B> { //此例中A就代表String类型,B就代表Integer类型【A,B代表的类型可以动态变换】
        public A m1 (A a) {
            return a;
        }
        public void m2 (B b) {
            System.out.println(b);
        }
        public static void main(String[] args) {
            Test02<String,Integer> t1 = new Test02<>();
            System.out.println(t1.m1("薛英豪"));
            t1.m2(100);
        }
    }

增强for循环(foreach)
1、语法结构:
    for(数组或集合中元素类型 变量名 : 将要遍历的数组或集合) {
        System.out.println(变量名);
    }
    数组中的元素的类型好确定:因为数组中只可以存储一种数据类型的数据。
    集合中的元素的类型:如果有泛型类型那就是泛型类型,如果没有泛型类型,那就是Object类型的。
    数组或集合中元素类型都是属于Object类型的。
2、foreach缺点:1.没有下表,在需要使用下标的情况下,不建议使用foreach循环。
                2.无法修改元素的内容。
3、例子:List<String> list = new ArrayList();
         list.add("123");
         list.add("456");
         list.add("789");
         for (String data : list) {
            System.out.println(data);
         }

Set集合
1、无序:存进去的顺序和取出来的顺序不同
   不可重复。
2、HashSet:放到HashSet集合中的元素实际上是放到了HashMap集合的key部分了。
3、TreeSet:放到TreeSet集合中的元素实际上是放到了TreeMap集合的key部分。
   在TreeSet集合中存储的元素可以自动按照大小顺序排序!称为可排序集合。
   
Map接口 
1、Map接口和Collection接口没有继承关系。
2、Map集合以key和value的方式存储数据:键值对
   key和value都是引用数据类型。
   key和value都是存储对象的内存地址。
   key起到主导作用,value是key的一个附属品。
3、Map集合中常用方法
    1.void clear();从集合中删除所有元素
      contains方法底层都是调用equals方法进行比对的。
    2.boolean containsKey(Object key);如果集合中包含指定key则返回true,如果集合中不包含指定key则返回false。
    3.boolean containsValue(Object value);如果集合中包含指定value则返回true,如果集合中不包含指定value则返回false。
    4.V get(Object key);通过指定key获取value
    5.boolean isEmpty();集合为空返回true
    6.Set<K> keySet();返回Map集合中包含所有键的Set集合
    7.V put(K key, V value);往集合中添加元素。
    8.V remove(Object key);通过指定的key删除集合中的元素。
    9.int size();返回集合中元素的数量。
    10.Collection<V> values();返回Map集合中所有的value。
    11.Set<Map.Entry<K,V>> entrySet();将Map集合转换成Set集合。
        map1集合对象
        key                value
        -------------------------------------------
         1                    zhangsan
         2                    lisi
        Set set = map1.entrySet();
        set集合对象
        1=zhangsan【注意:Map集合通过entrySet()方法转换成这个Set集合,Set集合中元素的类型是Map.Entry<K,V>】
        2=lisi
4、遍历Map集合的方式:
    1.迭代器方法:通过keySet()方法返回Map集合中所有key的set集合,通过迭代器遍历set集合,通过get(指定key)方法获取指定的value。
    2.foreach方法:通过keySet()方法返回Map集合中所有key的set集合,通过foreach遍历set集合,通过get(指定key)方法获取指定的value。
    3.Set<Map.Entry<K,V>> entrySet():将Map集合转换成Set集合,Set集合中元素的而类型为Map.Entry<K.V>类型的,直接输出是“K=V”这样的格式输出。

HashMap
1、哈希表是数组和单向链表的结合体。
   数组:在查询方面效率很高,随机增删元素方面效率很低。
   单项链表:在随即增删方面效率很高,在查询方面效率很低。
   哈希表将以上两种数据结构融合在一起,充分发挥他们各自的优点。
2、HashMap底层源代码:
    public class HashMap<K,V> {
    
        //HashMap实际上底层是一个数组。(一维数组)
        Node<K,V>[] table;

        //静态内部类HashMap.Node
        static class Node<K,V> {
            final int hash;//哈希值(哈希值是key的hashCode()方法的执行结果。hash值可以通过哈希函数/算法,可以转换存储成数组的下标)
            final K key;//存储到Map集合中的key
            V = value;//存储到Map集合中的value
            Node<K,V> next;//下一个节点的内存地址
        }
    
    }
3、哈希表/散列表:是一个一维数组,这个数组中每一个元素是一个单向链表。
4、map.put(k,v)添加元素实现原理:
    第一步:先将k,v封装到一个Node对象当中。
    第二步:底层会调用k的hashCode()方法得出hash值,然后通过哈希算法将hash值转换成数组的下标。
            下标位置上如果没有元素,就直接把Node添加到这个位置上了。
            如果下标位置上已经有了链表:此时会拿着k和链表上的每一个k进行equals,如果所有的k都返回false,那么这个新节点将被添加到链表的末尾。如果其中有一个equals返回了true,那么这个节点的value将会被覆盖。
5、v=map.get(k)获取元素实现原理:
   先调用k的hashCode()方法得出哈希值,哈希值通过哈希算法转换成数组下标,通过下标快速定位到某个位置上,
   如果这个位置上什么也没有,直接返回null。
   如果这个位置上有单向链表,那么拿着参数k和单向链表上的每一个 k进行equals,如果所有equals方法返回false,那么get方法返回null
   只要单向链表中有一个节点的k和参数k的equals返回true,那么get方法最终返回这个节点的value
6、无论是添加元素还是获取元素Map集合的key都会先后调用两个方法:hashCode和equals;所以这两个方法都需要重写。
7、哈希表数据结构中,同一个单向链表上所有节点的hash值相同,因为他们的数组下标是一样的。
8、hashCode方法需要重写,再重写时返回一个固定的值可以吗?会出现什么问题?
   所有的节点都放到了数组的同一个下标的位置,这样底层哈希表就变成了纯单向链表了,导致无法发挥哈希表数据结构的性能。
   这种情况我们称为“散列分布不均匀”。
9、hashCode方法需要重写,再重写时返回的值都设定为不一样的值?会出现什么问题?
   所有的节点都放到了数组的不同下标的位置,这样导致底层哈希表就变成了一个一维数组了,没有链表的概念了,所以也就不能体现哈希表的性能了。
10、放在HashMap集合key部分的元素,以及放在HashSet集合中的元素,需要同时重写hashCode和equals方法。
11、HashMap集合的默认初始化容量是16,默认加载因子是0.75
    默认记载因子的意思是:当集合底层的容量达到75%的时候,数组开始扩容。
    HashMap集合的初始化容量必须是2的倍数(这是官方推荐的),
    这是为了达到散列分布均匀,为了提高HashMap集合的存取效率,所必须的。
12、HashMap集合中:
    重写hashCode()方法:使操作哈希表中的元素的时候,找到某一列(一维数组中的某一个下表位置)。
    equals方法保障了:找到某一个下标之后,使用equals方法进行比对是否同一个key。
    如果不重写hashCode方法,hashCode方法默认返回对象的内存地址,导致每一个元素添加到HashMap集合时候,一维数组下标都不一样,而变成了一个纯属组的数据结构,散列分布不均匀,不能发挥哈希表的性能。
13、并且如果equals方法返回true,那么两个对象的hashCode方法返回值必须一样,默认情况下hashCode方法的返回值是两个对象的内存地址,需要我们自己重写hashCode方法使两个相等的对象hashCode返回值一样。
    equals方法返回true表示两个对象相同,再同一个链表上比较。那么对于同一个链表上的节点来说,他们的哈希值都是相同的,所以hashCode方法的返回值也相同。    
14、hashCode和equals方法:
    1.equals() 的作用是用来判断两个对象是否相等。
    2.hashCode() 的作用是获取对象的哈希码;哈希码一般是一个整数,用来确定对象在哈希表(比如 HashMap)中的索引位置。
    3.官方:
        如果根据equals(Object)方法,两个对象相等,那么对两个对象中的每一个调用hashCode方法必须产生相同的整数结果。
        如果根据equals(java.lang.Object)方法,两个对象不相等,那么对两个对象中的每一个调用hashCode方法都必须产生不同的整数结果,这是不必要的。
        然而,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。
    4.equals方法返回true,那么hashCode返回值也是一样的,那为什么一定要用哈希码来确定对象在哈希表(比如 HashMap)中的索引位置,不直接用equals?
        因为equals返回true那么hashCode返回值必须相同,但是equals返回false,hashCode也可能返回相同。
        如果单纯用equals来确定对象再哈希表中的位置索引,哈希表数据结构就会变成数组数据结构了。
15、对于HashMap集合而言hashCode方法就是决定某个元素放到底层哈希表数据结构的“哪”一列。
16、哈希表中对于同一个单向链表上的节点来说,他们的哈希值可能是相同的,也可能时不同的(发生哈希碰撞导致不同的哈希值通过哈希算法转换成的数组下标是相同的)。
    哈希值相同的一定在同一个链表上,哈希值不同的可能在同一个链表上。
17、结论:放在HashMap(key)中的元素和HashSet中的元素都需要重写equals和hashCode方法。
    因为底层都是哈希表数据结构,所以要通过重写hashCode方法使得哈希表散列分布均匀。
18、HashMap再JDK8之后,如果哈希表的单向链表中的元素超过8个,单向链表这种数据结构就会变成红黑树数据结构。
    当红黑树(二叉树)上的节点数量小于6时,会重新把红黑树变成单向链表。
    这种方式是为了提高检索效率。
19、HashMap扩容之后时原容量的2倍。(ArrayList扩容是原容量的1.5倍,Vector扩容之后是原容量的2倍).
20、HashMap和Hashtable的区别:
    HashMap的key和value都可以放null,Hashtable的key和value都不可以放null。
    HashMap是非线程安全的,Hashtable是线程安全的。

Hashtable
1、底层是哈希表数据结构。
2、Hashtable的默认初始化容量是11,默认加载因子是0.75.(当存储的数据达到总容量的75%的时候,开始扩容)
3、Hashtable扩容是怎么扩容的:扩容之后是“原容量*2+1”.

Properties
1、Properties是一个Map集合,继承Hashtable,Properties的key和value都是String类型。
2、常用方法:
    1.Object setPropertirs(String key,String value);存元素
    2.String getProperties(String key);取元素
    3.void load(InputStream inStream) ;将流加载到Properties集合中【key=value的形式】
    4.void load(Reader reader) ;将流加载到Properties集合对象当中【key=value的形式】
3、key=value【文件中的数据都是这样的键值对的话,称为“属性”配置文件】
   java规范中要求,属性配置文件名建议以“.properties”后缀。

TreeSet
1、TreeSet集合底层实际上是一个TreeMap。
2、TreeMap集合底层是一个二叉树。
3、放到TreeSet集合中的元素等同于放到TreeMap集合的key部分了。
4、TreeSet集合中的元素:无序不可重复,但是可以按照元素的大小顺序自动排序。(称为可排序集合)
5、放在TreeSet集合中的元素需要实现Comparable接口(可排序的)。并且实现compareTo方法(在这个方法中编写排序规则)。(equals方法可以不写了)
   最终HashMap底层的代码就会调用compareTo方法完成排序。
6、为什么TreeSet中不能又存数字1又存字符串“1”。HashSet就可以。
   因为TreeSet底层会自动排序,排序的时候会调用对象的compareTo方法进行对象的排序。
   compareTo一般都是本类对象和本类对象才能比较大小,弄两个类型不一样的当然就会抛出异常。
7、第一种方式:使用TreeSet的无参构造方法。
    因为放到TreeSet/TreeMap集合中的元素会自动排序,所以放到集合中的元素必须实现可排序接口(java.lang.Comparable接口),并且是实现接口中的方法(compareTo方法),在此方法中定义排序的规则。
   第二种方式:使用TreeSet的无参构造方法。public TreeSet(java.util.Comparator comparator)
    因为放到TreeSet/TreeMap集合中的元素会自动排序,所以放到集合中的元素可以不实现Comparable接口,但是需要有一个比较器对象。(实现Comparator接口,并实现compare方法,在compare方法中编写比较规则),在实例化集合对象的时候,把比较器传进去。

二叉树
1、TreeSet/TreeMap是自平衡二叉树。遵循左小右大的原则存放。
2、遍历二叉树又三种方式。
    全序遍历:根左右
    中序遍历:左根右
    后序遍历:左右根
3、TreeSet/TreeMap是中序遍历。
    Iterator迭代器采用的也是中序遍历。

集合工具类(java.util.Collections)
1、Collections.synchronizedXXX();把一个集合变成线程安全的
   XXX可以是List、Set、Collection....
2、Collections.sort(XXX);对集合进行排序,前提是放在XXX集合中的元素必须是可排序的,自定义排序规则。
   排序规则:
    第一种:实现Comparable接口。
    第二种:自定义比较器,实现Comparator接口。

   


容量总结:
StringBuffer:初始化容量是16.
ArrayList:初始化容量:10,扩容是原来的1.5倍。
Vector:初始化容量:10,扩容是原来的2倍。
HashSet和HashMap:初始化容量是16(最好是2的倍数,默认记载因子是0.75),扩容之后是原来的2倍。
Hashtable:初始化容量11,扩容之后是原来的“2倍+1”
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛英豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值