集合

作者: 上炼致知 | 来源:发表于2020-05-12 19:00 被阅读0次

集合的简介

集合是java中提供的一种容器,可以用来存储多个数据;

集合和数组都是容器,它们的区别:

  • 数组的长度是固定的,集合的长度是可变的
  • 集合中存储的元素必须是引用类型数据

集合继承关系

ArrayList类继承了抽象类AbstractList,同时实现接口List,而List接口又继承了Collection接口;Collection接口为最顶层集合接口

说明我们在使用ArrayList类时,该类已经把所有抽象方法进行了重写,即Collection接口的所有子类都会被重写;

  • Collection接口常用的子接口有:List接口、Set接口;

  • List接口常用的子类有:ArrayList类、LinkedList类;

  • Set接口常用的子类有:HashSet类、LinkedList类

    集合继承关系图.png

集合Collection的方法

Collection接口中的方法,是集合中所有实现类必须拥有的方法;

  • Object[] toArray() Returns an array containing all of the elements in this collection;

    Collection<String> coll = new ArrayList<>();
    coll.add("abc");
    coll.add("123");
    //转成数组
    Object[] objs = coll.toArray();
    for (int i = 0; i < objs.length; i++) {
          System.out.println(objs[i]);
    }
    

    Java中的三种长度表现

    1. 数组;.length属性,返回值int
    2. 字符串;.length()方法,返回值int
    3. 集合;.size()方法,返回值int
  • boolean contains(Object o) 如果此collection包含指定的元素,则返回true;

    Collection<String> coll = new ArrayList<String>();
    coll.add("abc");
    coll.add("123");
    boolean flag = coll.contains("abc");
    System.out.println(flag);//true
    
  • void clear() 移除此collection中的所有元素

    Collection<String> coll = new ArrayList<String>();
    coll.add("abc");
    coll.add("123");
    System.out.println(coll);//[abc, 123]
    coll.clear();//移除所有元素
    System.out.println(coll);//[]
    
  • boolean remove(Object o) 从此collection中移除指定元素的单个实例(如果存在的话)

    Collection<String> coll = new ArrayList<String>();
    coll.add("abc");
    coll.add("123");
    boolean flag = coll.remove("abc");
    System.out.println(flag);//true
    System.out.println(coll);//[123]
    

迭代器的概述

Java中提供了很多个集合,它们在存储元素时,采用的存储方式不同,要取出这些集合中的元素,可通过一种通用的获取方式来完成;

Collection集合元素的通用获取方式:在取元素之前要先判断集合中有没有元素,如果有,就把这个元素取出来,继续再判断,如果还有就再取出来,直到把集合中的所有元素全部取出来,这种取出方式专业术语称为迭代

每种集合的底层数据结构都不同,例如:ArrayList底层是数组,LinkedList底层是链表,但是无论哪种集合,都会判断是否有元素,以及取出里面元素的动作;Java为我们提供了一个迭代器定义了统一的判断元素和取元素的方法;

接口Iterator的两个抽象方法

  • boolean hasNext() Returns true if the iterator has more elements;

  • E next() Return the next element in the iterator;

    以ArrayList为例:

    Collection<String> coll = new ArrayList<String>();
    coll.add("abc1");
    coll.add("abc2");
    coll.add("abc3");
    coll.add("abc4");
    Iterator<String> iterator = coll.iterator();
    //接口实现类对象,调用方法hasNext()判断集合是否有元素
    while (iterator.hasNext()) {
        //接口的实现类对象,调用方法next()取出集合中的元素
        String str = iterator.next();
        System.out.println(str);
    }
    

增强for循环

格式:

for (数据类型 变量名 : 数组或集合) {}

使用增强for循环遍历数组,好处是:代码少了,方便容器遍历;弊端:没有索引,不能操作容器里面的元素

int[] arr = {3, 1, 9, 0};
for (int i : arr) {
        System.out.println(i);
}
System.out.println(arr);//[I@1f89ab83
System.out.println(arr.toString());//[I@1f89ab83

增强for循环遍历集合:

ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("abc1");
arrayList.add("abc2");
arrayList.add("abc4");
for (String str : arrayList) {
    System.out.println(str);
}

泛型的引入

泛型指明了集合中存储数据的类型 <数据类型>,是一个安全机制,保证程序的安全性;

泛型类

定义格式:修饰符 class 类名<代表泛型的变量>{}

class ArrayList<E> {
    public boolean add(E e) {}
    public E get(int index) {}
}

/**
 * 例如:ArrayList<String> list = new ArrayList<String>();
 * 此时,变量E的值就是String类型
 */
  
/**
 * 例如:ArrayList<Integer> list = new ArrayList<Integer>();
 * 此时,变量E的值就是Integer类型
 */

泛型的方法

定义的格式:修饰符 <代表泛型的变量> 返回值类型 方法名(参数){}

/**
 * 例如,ArrayList集合中的方法
 * public <T> T[] toArray(T[] a) {}
 * 该方法,用来把集合元素存储到指定数据类型的数组,返回已存储集合元素的数组
 */
ArrayList<String> list = new ArrayList<String>();
String[] arr = new String[100];
String[] result = list.toArray(arr);
//此时变量T的值就是String类型,变量T
//pulic <String> String[] toArray(String[] a) {};

ArrayList<String> list = new ArrayList<String>();
Integer[] arr = new Integer[100];
Integer[] result = arr.toArray(arr);
//此时变量的值就是Integer类型
//public <Integer> Integer[] toArray(Integer[] a) {};

泛型的接口

//带有泛型的接口
public interface List<E> {
    abstract boolean add(E e);
}
//实现类,先实现接口,不理会泛型
public class ArrayList<E> implements List<E> { }
//调用者
new ArrayList<String>();

//实现类,实现接口的同时,也指定了数据类型
public class XXX implements List<String> {}
//调用者
new XXX()

泛型的好处

  • 将运行时期的ClassCastException转移到了编译时期,变成编译失败;
  • 避免了类型强转的麻烦

泛型的通配符

泛型的通配符:?;匹配所有的数据类型

public static void iteratorFun(Collection<?> coll) {
    Iterator<?> it = coll.iterator();
    while (it.hasNext()) {
        System.out.println(it.next());
    }
}

泛型的限定

? extends Fu    限制的是父类,上限限定,可以传递Fu和它的子类
? super Sun 限制的是子类,下限限定,可以传递Sun和它的父类

List接口

List接口介绍

List是有序的Collection,此接口的用户可以对列表中每个元素的插入位置进行精确的地控制,用户可以根据元素的索引访问元素,并搜索列表中的元素;与Set不同,List允许存储重复的元素

List接口:

  • 元素存取有序的集合;例如,存元素的顺序是11、22、33,则List集合中元素的存储就是按照11、22、33的顺序完成的;
  • 是一个带有索引的集合,通过索引就可以精确的操作集合中的元素;
  • 可以有重复元素的集合;

List接口的常用实现类有:ArrayList集合、LinkedList;

List接口常用方法

增加元素:

  • boolean add(E e) 向列表的尾部添加指定的元素
  • void add(int index, Element) 在列表的指定位置插入指定的元素

删除元素:

  • E remove(int index) 移除列表中指定位置的元素

  • boolean remove(Object o) 从此列表中移除第一次出现的指定元素(如果存在)

查询元素:

  • E get(int index) 返回列表中指定位置的元素

替换元素:

  • E set(int index, E element) 用指定元素替换列表中指定位置的元素
List<String> list = new ArrayList<>();
//尾部添加元素
list.add("abc");
list.add("123");
list.add("一二三");
list.add("唐");
System.out.println(list); //[abc, 123, 一二三, 唐]

//指定位置插入指定元素
list.add(3, "隋");
System.out.println(list); //[abc, 123, 一二三, 隋, 唐]

//删除指定位置元素
list.remove(1)  ;
System.out.println(list); //[abc, 一二三, 隋, 唐]

//替换(修改)指定位置元素
list.set(1, "四五六");
System.out.println(list); //[abc, 四五六, 隋, 唐]

for (int i = 0; i < list.size(); i++) {
    String str = list.get(i);
    //返回列表中指定位置的元素
    System.out.println(str);
}

List的并发修改异常

在迭代过程中,不能使用集合的方法对元素进行操作,否则会导致迭代器并不知道集合中的变化,容易引发数据的不确定性;

解决办法:可通过ListIterator迭代器进行操作元素,ListIterator的出现,解决了使用iterator迭代过程中可能会发生的错误情况;

List集合存储数据的结构

List接口下有很多个集合,它们存储元素所采用的结构方式不同,因此这些集合有各自的特点,根据不同场景下使用不同的集合;

集合的数据存储常用结构有:堆栈、队列、数组、链表;

  • 堆栈:采用堆栈结构的集合,对元素存取的特点:

    • 先进后出

    • 栈的入口、出口都是栈的顶端位置

    • 压栈:就是存元素;即把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位置;

    • 弹栈:就是取元素;即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶方向移动一个位置;

      压栈、弹栈可联想弹夹;

  • 队列:采用该结构的集合,对元素的存取特点:

    • 先进先出,即存进去的元素要在它前面的元素取出后才能被取出;
    • 队列的入口、出口在两端;
  • 数组:采用该结构的集合,对元素存取的特点:

    • 查找元素快;通过索引,可以快速访问指定位置的元素;
    • 增删元素慢
      1. 指定索引位置增加元素:需要创建一个新数组,将指定新元素存储在指定索引位置,再把原数组元素根据索引,复制到新数组对应索引的位置;
      2. 指定索引位置删除元素:需要创建一个新数组,把原数组元素根据索引,复制到新书组对应索引的位置,原数组中指定索引位置元素不复制到新数组中;
  • 链表:才用该结构的集合,对元素存取的特点:

    • 多个节点之间,通过地址进行连接;例如,多个人手拉手,每个人用自己的右手拉住下个人的左手,依次类推,这样多个人就连在一起了;
    • 查找元素慢;想查找某个元素,需要通过连接的节点,依次向后查找指定元素;
    • 增删元素快
      1. 增加元素:操作如下图左,只需修改连接下个元素的地址即可;
      2. 删除元素;操作如下图右,只需修改连接下个元素的地址即可;


        链表增删元素.png

ArrayList集合

ArrrayList集合数据存储的结构是数组结构,元素增删慢,查找快;由于日常开发中使用最多的功能为查询数据,遍历数据,所以ArrayList是最常用的集合;

LinkedList集合

  • LinkedList集合底层采用链表结构,每次查询都要从链头或者链尾找起,查询相对数组较慢
  • LinkedList删除元素,直接修改元素记录的地址值即可,不用大量移动元素

LinkedList集合数据存储的结构是链表结构,方便元素添加、删除的集合,实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了大量收尾操作的方法;LinkedList是List的实现类,List中的方法LinkeddList都可以使用;

在开发中,LinkedList集合可以作为堆栈和队列的集合使用

添加:

  • void addFirst(E e) 将制定元素插入此列表的开头;
  • void addLast(E e) 将指定元素添加到此列表的结尾;

获取:

  • E getFirst() 返回此列表的第一个元素;
  • E getLast() 返回此列表的最后一个元素;

移除:

  • E removeFirst() 移除并返回此列表的第一个元素;
  • E removeLast() 移除并返回此列表的最后一个元素;

弹出和压入:

  • E pop() 从此列表所表示的堆栈处弹出一个元素;
  • void push(E e) 将元素推入此列表所表示的堆栈;

判断:

  • boolean isEmpty() 如果此列表不含元素,则返回true;

Vector集合

Vector集合数据存储的结构是数组结构,是JDK最早提供的集合,Vector中提供了一个独特的取出方式,就是枚举Enumeration,它其实就是早起的迭代器;此接口Enumeration的功能与Iterator接口的功能类似;

Vector集合已被ArrayList替代,枚举Enumeration已被迭代器Iterator替代;

Vector常见方法(被ArrayList替代)

  • void addElement(E obj) 向自定的组件添加到此向量的末尾,将其大小加1;
  • E elementAt(int index) 返回指定索引处的组件;
  • Enumeration<E> elements() 返回此向量的组件的枚举;

Enumeration枚举常见方法(被Iterator替代)

  • boolean hasMoreElements() 测试此枚举是否包含更多元素;
  • E nextElements() 如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素;

Set接口

LIst接口可以存放重复元素,但是Set接口不能存储重复元素;通过元素的equals方法来判断是否为重复元素;

HashSet集合介绍

HashSet集合实现Set接口,由哈希表支持(实际上是一个HashMap集合),HashSet集合不能保证迭代的顺序与元素存储顺序相同

HashSet集合,采用哈希表结构存储数据,保证元素唯一性的方式依赖于:hashCode()与equals()方法;

HashSet集合存储数据的结构

什么是哈希表:哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数组结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中,而这样的数组就称为哈希数组,即哈希表

当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法,由于任何对象都是Object类的子类,所以任何对象都有这个方法,即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置;

这里需要注意,如果两个两个对象的hashCode方法算出来的结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中;

总结:保证HashSet集合元素的唯一性,其实就是根据对象的hashCode和equals方法来决定的;如果我们往HashSet集合中存放自定义的对象,那么保证其唯一,就必须覆写hashCode和equals方法建立属于当前对象的比较方式

特点:

  1. 无序集合,存储和取出的顺序不同
  2. 没有索引
  3. 不存储重复元素
  4. 底层数据结构是哈希表;存取都比较快;线程不安全,运行速度快
HashSet<String> hs = new HashSet<>();
hs.add("zhangsan");
hs.add("lisi");
hs.add("wangwu");
hs.add("zhangsan");
//迭代器方法取出集合中的每个元素
Iterator<String> iterator = hs.iterator();
while (iterator.hasNext()) {
    System.out.print(iterator.next() + " "); //lisi zhangsan wangwu 
}
System.out.println();
//增强for循环的方法取出集合中的每个元素
for (String str : hs) {
    System.out.print(str + " ");//lisi zhangsan wangwu 
}
System.out.println();

哈希表的数据结构

哈希表的数据解构.JPG
  • 加载因子:表中填入的记录数/哈希表的长度;

    例如,加载因子是0.75,代表数组中的16个位置,其中存入16*0.75=12个元素;如果在存入第13个元素,导致存储链子过长,会降低哈希表的性能,那么此时会扩充哈希表,底层会开辟一个长度为原长度2倍的数组,把老元素拷贝到新书组中,再把新元素添加到数组中;

  • 当存入元素数量>哈希表长度加载因子*,就要扩容,因此加载因子决定扩容时机;

字符串对象的哈希值

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;
        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

哈希表的存储过程

  1. 首先调用本来的hashCode()方法算出哈希值
  2. 在容器中找是否有与新元素哈希值相同的老元素,如果没有直接存入,如果有转到第三步
  3. 新元素会与该索引位置下的老元素利用equals方法一一对比,一旦新元素.equals(老元素)返回true,那么停止对比,说明元素重复,不再存入;如果与该索引位置下的老元素都通过equals方法对比返回false,说明没有重复,存入

HashSet存储自定义类型元素

给HashSet中存放自定义类型元素时,需要重写对象中的hashCode和equals方法,建立自己的比较方法,才能保证HashSet集合中的对象唯一

LinkedHashSet介绍

HashSet有一个子类LinkedHashSet,它是链表和哈希表组合的一个数据存储结构

它能保证元素的有序性,存储和取出顺序相同

线程不安全,运行速度快

判断集合元素唯一的原理

ArrayList的contains方法判断元素是否重复原理

  • boolean contains(Object o) 如果此列表中包含指定的元素,则返回true;

    ArrayList的contains方法底层依赖equals方法,在调用contains方法时会使用传入元素的equals方法依次与集合中的旧元素所比较,从而根据返回的布尔值判断是否有重复的元素;

    如果ArrayList存放自定义类型时,由于自定义类型在未重写queals方法前,判断是否重复的依据是地址值,所以如果想根据内容判断是否为重复元素,需要重写元素的equals方法

HashSet的add/contains等方法判断元素是否重复原理

  • boolean add(E e) 如果在此set中尚未包含指定元素,则添加指定元素;
  • boolean contains(Object o) 如果此set包含指定元素,则返回true;

Set集合不能存放重复集合,其添加方法在添加时会判断是否有重复元素,有重复元素就不添加,没有重复才添加;

HashSet集合由于是无序的,其判断唯一的依据是元素类型的hashCode和equals方法的返结果,规则如下:

先判断新元素与集合内已经有的旧元素的HashCode值:如果不同,说明是不同元素,添加到集合;如果相同,再判断equals比较结果,返回true则元素相同,返回false则元素不同,添加到集合;

所以,使用HashSet存储自定义类型,如果没有重写该类的hashCode和equals方法,则判断重复时使用的是地址值,如果想通过内容比较元素是否相同,需要重写该元素类的hashCode和equals方法

总结

List Set
有序集(元素存与取的顺序相同);
可以存储重复的元素
无序的集合(元素存与取的顺序可能不同)
不能存储重复的元素
List集合中特有的方法:
void add(int index, Object element)
Object get(int index)
Object remove(int index)
Object set(int index, Object element)
ArrayList LinkedList
底层数据结构是数组
查询快,增删慢
底层数据结构是链表
查询慢,增删快
HashSet LinkedHashSet
元素唯一,不重复
底层结构是哈希表结构
元素的存和取顺序不能保证一致
元素唯一,不重复
底层结构是哈希表结构+链表结构
元素的存取顺序一致

Map接口

Map接口概述

Map接口下的集合与Collection接口下的集合存储数据的形式不同:

Collection接口下的集合 Map接口下的集合
元素孤立存在,向集合中存储元素采用一个一个元素的方式存储 元素成对存在,每个元素由键和值两部分组成,通过键可以找到对应的值
称为单列集合 称为双列集合
不能包含重复的键,值可以重复,每个键只能对应一个值
常用集合为HashMap集合、LinkedHashMap集合

Map接口中常用集合概述

HashMap<K, V> LinkedHashMap<K, V>
存储数据采用哈希表结构,元素的存取顺序不一致,由于需要保证键的唯一不重复,需要重写自定义类型的hashCode()和equals()方法 是HashMap下的子类,存储数据采用哈希表结构+链表结构,通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证键唯一不重复,需要重写键的hashCode()和equals()方法;

Map接口常用方法

  • V get(Object key) 获取指定键所对应的值

  • V remove(Object key) 根据指定的键删除元素,返回被删除元素的值

  • V put(K key, V value) 若指定的键在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中;若指定的键在集合中存在,则返回值为集合中键原来所对应的值,并把指定键所对应的值替换成指定的新值

//创建Map对象
Map<String, String> map = new HashMap<>();
//给map添加元素
map.put("星期一", "Monday");
map.put("星期日", "Sunday");
System.out.println(map);//{星期日=Sunday, 星期一=Monday}

System.out.println(map.put("星期一", "Mon"));//Monday
System.out.println(map);//{星期日=Sunday, 星期一=Mon}

//根据指定key获取对应的value
String eng = map.get("星期一");
System.out.println(eng);//Mon

//删除指定元素,返回被删除元素的值
String value = map.remove("星期日");
System.out.println(value);//Sunday
System.out.println(map);//{星期一=Mon}

Map集合遍历键找值方式

键找值方式:即通过元素中的键,获取键所对应的值;

  1. 获取Map集合中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键;
  • Set<K> keySet()回此映射中包含的键的Set视图
  1. 遍历键的Set集合,得到每一个键;

  2. 根据键获取键所对应的值;

    Map<String, String> map = new HashMap<>();
    map.put("yi", "one");
    map.put("er", "two");
    map.put("san", "three");
    //获取map中所有的key
    Set<String> keySet = map.keySet();
    //遍历存放所有key的Set集合
    Iterator<String> iterator = keySet.iterator();
    
    while (iterator.hasNext()) {
        //得到每一个key
        String key = iterator.next();
        //通过key获取对应的value
        String value = map.get(key);
        System.out.println(key + " = " + value);
    }
    

Entry键值对对象

在Map接口设计时,提供了一个嵌套接口:Entry;Entry将键值对的对应关系封装成了对象即键值对对象,这样在遍历Map集合时,就可以从每个键值对(Entry)对象中获取对应的键与对应的值;

  • static interface Map.Entry<K, V> 映射项(键-值对);Entry是Map接口中提供的一个静态内部嵌套接口
  • K getKey() 返回与此项对应的键;获取Entry对象中的键
  • V getVaule() 返回与此项对应的值;获取Entry对象中的值
  • Set<Map.Entry<K, V>> entrySet() 返回此映射中包含的映射关系的Set视图;用于返回Map集合中所有的键值对(Entry)对象,以Set集合形式返回

Map集合遍历键值对方式

键值对方式:即通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值;

  1. 获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回;
  2. 遍历包含键值对(Entry)对象的Set集合,得到每一个键值对对象;
  3. 通过键值对(Entry)对象,获取Entry对象中的键和值;
Map<String, String> map = new HashMap<>();
map.put("yi", "one");
map.put("er", "two");
map.put("san", "three");

//获取键值对对象的Set集合
Set<Map.Entry<String, String>> entrySet = map.entrySet();
//遍历键值对对象的Set集合
Iterator<Map.Entry<String, String>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
    //得到每一个键值对
    Map.Entry<String, String> entry = iterator.next();
    //通过每一对键值对得到key
    String key = entry.getKey();
    //通过每一对键值对得到value
    String value = entry.getValue();
    System.out.println(key + " = " + value);
}
System.out.println("=======================");
// 增强for循环方式遍历
for (Map.Entry<String, String> entry : entrySet) {
    //通过每一对键值对得到key
    String key = entry.getKey();
    //通过每一对键值对得到value
    String value = entry.getValue();
    System.out.println(key + " = " + value);
}
  • Map集合不能直接使用迭代器或者foreach进行遍历,但是转成Set之后就可以使用

HashMap存储自定义类型键值

  • 当给HashMap存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须覆写对象的hashCode()和equals()方法
  • 如果要保证map中存放的key和取出的顺序一致,可以使用LinkedHashMap

LinkedHashMap特点

  • 有序

Hashtable的特点

底层数据结构是哈希表,特点和HashMap一样;

HashMap Hashtable
线程不安全的集合,运行速度快 线程安全集合,运行速度慢
和Vector一样,被取代
允许存储null值,null键 不允许存储null值,null键
子类Properties依然活跃

静态导入

在导包的过程中可以直接导入静态部分,这样某个类的静态成员就可以直接使用了

  • import static XXX.YYY; 导入后YYY可直接使用;

可变参数

  • 修饰符 返回值类型 方法名(参数类型...形参名) 等价于 修饰符 返回值类型 方法名(参数类型[] 形参名)

  • ...用在参数上称之为可变参数;可变参数本质就是一个数组

  • 注意:

    1. 有多个参数,参数中包含可变参数,那么可变参数一定要写在参数列表的末尾
    2. 一个方法中只能有一个可变参数
public static void main(String[] args) {
    int[] arr = {1, 3, 5, 7};
    int sum = add(arr);
    System.out.println(sum);
}
public static int add(int...param) {
    int sum = 0;
    for (int i = 0; i < param.length; i++) {
      sum += param[i];
    }
    return sum;
}

Collections集合工具类

  • static void shuffle(List<?> list) 使用默认随机源对指定列表进行置换;即将集合元素顺序打乱

    List<Integer> list = new ArrayList<>();
    list.add(5);
    list.add(1);
    list.add(9);
    list.add(6);
    System.out.println(list);//[5, 1, 9, 6]
    //调用工具类shuffle对集合随机排序
    Collections.shuffle(list);
    System.out.println(list);//[5, 9, 6, 1]
    
  • static <T extends Comparable<? super T> void sort(List<T> list) 根据元素的自然顺序对指定列表按升序进行排序;

    List<String> list = new ArrayList<>();
    list.add("ewrew");
    list.add("qwesd");
    list.add("Qwesd");
    list.add("bv");
    list.add("wer");
    System.out.println(list);//[ewrew, qwesd, Qwesd, bv, wer]
    //调用集合工具类的方法sort
    Collections.sort(list);
    System.out.println(list);//[Qwesd, bv, ewrew, qwesd, wer]
    
  • static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) 使用二分搜索法搜索指定列表,以获得指定对象;

    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(5);
    list.add(8);
    list.add(10);
    list.add(15);
    list.add(20);
    //调用工具类方法binarySearch
    int index1 = Collections.binarySearch(list, 16);
    System.out.println(index1);//-6
    int index2 = Collections.binarySearch(list, 15);
    System.out.println(index2);//4
    

集合继承体系

集合继承体系.png
  • 接口: 用来明确所有集合中该具有的功能,相当于在定义集合功能标准;
  • 抽象类:把多个集合中功能实现方式相同的方法,抽取到抽象类实现,具体集合不再遍写,继承使用即可;
  • 具体类:继承抽象类,实现接口,重写所有抽象方法,达到具备指定功能的集合,每个具体集合类,根据自身的数据存储结构方式,对接口中的功能方法,进行不同方式的实现;

相关文章

  • 我的Swift的学习总结 -->第二周

    集合 集合:Set,定义一个集合可以写成:var 集合名 : Set<集合类型> = [集合元素],具体的集合应用...

  • markdown 测试

    集合 集合 集合 引用

  • kotlin学习第五天:集合,高阶函数,Lambda表达式

    集合 list集合 list集合分为可变集合与不可变集合。由list of创建的集合为不可变集合,不能扩容,不能修...

  • kotlin练习 ---- 集合练习

    kotlin练习 - 集合练习 Set集合 Set集合创建 Set集合的使用 List集合 List集合创建 Li...

  • 集合总结

    集合 集合分为单列集合和双列集合两种: 一.单列集合: Collection是单列集合的顶级接口: 其中有三类集合...

  • 映射、元组、集合

    映射 元组 集合 集合之seq 集合之set 集合之map

  • 16.Collection集合

    主要内容: Collection 集合 迭代器 增强for List 集合 Set 集合 1,集合 集合是java...

  • 集合与有序集合

    集合分为有序集合 (zset) 和无序集合 (set), 一般无序集合也直接说成集合 无序集合 (set) 无序集...

  • python入坑第八天|集合

    好的,各位蛇友,我们今天来学习集合。 内容: 集合的创建 集合操作符号 集合的内置函数 集合的创建 集合用set(...

  • 集合框架

    集合框架的概念 集合:存放数据的容器 集合框架:java中,用于表示集合,以及操作集合的类和接口的统称 数组与集合...

网友评论

      本文标题:集合

      本文链接:https://www.haomeiwen.com/subject/businhtx.html