集合的简介
集合是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中的三种长度表现:
- 数组;.length属性,返回值int
- 字符串;.length()方法,返回值int
- 集合;.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接口下有很多个集合,它们存储元素所采用的结构方式不同,因此这些集合有各自的特点,根据不同场景下使用不同的集合;
集合的数据存储常用结构有:堆栈、队列、数组、链表;
-
堆栈:采用堆栈结构的集合,对元素存取的特点:
-
先进后出;
-
栈的入口、出口都是栈的顶端位置;
-
压栈:就是存元素;即把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位置;
-
弹栈:就是取元素;即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶方向移动一个位置;
压栈、弹栈可联想弹夹;
-
-
队列:采用该结构的集合,对元素的存取特点:
- 先进先出,即存进去的元素要在它前面的元素取出后才能被取出;
- 队列的入口、出口在两端;
-
数组:采用该结构的集合,对元素存取的特点:
- 查找元素快;通过索引,可以快速访问指定位置的元素;
- 增删元素慢;
- 指定索引位置增加元素:需要创建一个新数组,将指定新元素存储在指定索引位置,再把原数组元素根据索引,复制到新数组对应索引的位置;
- 指定索引位置删除元素:需要创建一个新数组,把原数组元素根据索引,复制到新书组对应索引的位置,原数组中指定索引位置元素不复制到新数组中;
-
链表:才用该结构的集合,对元素存取的特点:
- 多个节点之间,通过地址进行连接;例如,多个人手拉手,每个人用自己的右手拉住下个人的左手,依次类推,这样多个人就连在一起了;
- 查找元素慢;想查找某个元素,需要通过连接的节点,依次向后查找指定元素;
- 增删元素快:
- 增加元素:操作如下图左,只需修改连接下个元素的地址即可;
-
删除元素;操作如下图右,只需修改连接下个元素的地址即可;
链表增删元素.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方法建立属于当前对象的比较方式;
特点:
- 无序集合,存储和取出的顺序不同;
- 没有索引;
- 不存储重复元素;
- 底层数据结构是哈希表;存取都比较快;线程不安全,运行速度快;
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;
}
哈希表的存储过程
- 首先调用本来的hashCode()方法算出哈希值;
- 在容器中找是否有与新元素哈希值相同的老元素,如果没有直接存入,如果有转到第三步;
- 新元素会与该索引位置下的老元素利用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集合遍历键找值方式
键找值方式:即通过元素中的键,获取键所对应的值;
- 获取Map集合中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键;
-
Set<K> keySet()
返回此映射中包含的键的Set视图;
-
遍历键的Set集合,得到每一个键;
-
根据键获取键所对应的值;
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)对象中的键与值;
- 获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回;
- 遍历包含键值对(Entry)对象的Set集合,得到每一个键值对对象;
- 通过键值对(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可直接使用;
可变参数
-
修饰符 返回值类型 方法名(参数类型...形参名)
等价于修饰符 返回值类型 方法名(参数类型[] 形参名)
-
...用在参数上称之为可变参数;可变参数本质就是一个数组;
-
注意:
- 有多个参数,参数中包含可变参数,那么可变参数一定要写在参数列表的末尾;
- 一个方法中只能有一个可变参数;
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- 接口: 用来明确所有集合中该具有的功能,相当于在定义集合功能标准;
- 抽象类:把多个集合中功能实现方式相同的方法,抽取到抽象类实现,具体集合不再遍写,继承使用即可;
- 具体类:继承抽象类,实现接口,重写所有抽象方法,达到具备指定功能的集合,每个具体集合类,根据自身的数据存储结构方式,对接口中的功能方法,进行不同方式的实现;
网友评论