集合
类名:collection类是一个接口。collections是集合工具类。
第一阶段:
封装继承多态集合反射
概念
对象的容器,存储对象的对象,可替代数组(数组的长度固定弊端)。(只能存储对象)
特点
容器的工具类,定义了对多个对象进行操作的常用方法。
位置
java.util.*
集合类的主要架构
List接口
List接口,有序序列,有序集合。
ArrayList类
ArrayList实现接口List,List接口实现Collect接口。
可调整大小的数组的实现List接口,除了实现List 接口
之外,该类还提供了一些方法来操纵内部使用的存储列表的数组的大小,这个类是大致相当于Vector
不同之处在于它是不同步的(线程不安全)。
泛型:用于统一集合中的数据类型。
基本使用
构造方法
ArrayList() 无参构造
方法
add()
作用:添加元素,默认添加在末尾。在指定位置添加元素。
参数:object 或 index,object;
当传入一个对象时,默认添加在末尾;
当传入一个index和obj时,会在指定下标处添加元素obj;
返回值:布尔值或无
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
set(int index, E element)
作用:用指定的元素替换此列表中指定位置的元素。
参数:下标index和元素
返回值:返回之前对应下标的老元素
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 修改指定下标元素
Object res1 = arrlist.set(1, "xiaoyu");
System.out.println("res1 = " + res1); // 返回老元素
get(int index)
作用:返回此列表中指定位置的元素
参数:集合内的下标index
返回值:对应下标集合内的元素
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 获取元素
Object res2 = arrlist.get(0);
System.out.println("res2 = " + res2); // 返回元素
size()
作用:返回此列表中的元素数
参数:无;
返回值:int类型;
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 获取元素数量
int size = arrlist.size();
System.out.println("size = " + size);
E remove(int index)
作用:删除集合内的元素
参数:object或下标,
当传入object时,从前往后匹配,删除第一个匹配到的元素;
当传入下标index时,删除指定下标的元素;
返回值:
当传入obj类型时,返回值类型是布尔类型,是否删除成功;
当传入是下标时,返回值是删除的元素本身;
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 删除元素
boolean res3 = arrlist.remove(44.5);
System.out.println("res3 = " + res3);
// 删除元素
Object res4 = arrlist.remove(1);
System.out.println("res3 = " + res4);
contains(Object o)
作用:集合中是否包含指定的元素
参数:传入object元素;
返回值: 存在则返回true,否则为false;
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
boolean res1 = arrlist.contains("sakuna");
System.out.println("res1 = " + res1); // true
clear()
作用:从集合中删除所有元素;
参数:无;
返回值: 无;
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 删除所有元素
arrlist.clear();
indexOf(Object o)
作用:返回指定元素的在集合中第一次出现的索引,如果此列表不包含元素,则返回-1;
参数:obj元素;
返回值:int类型或-1;
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 返回第一次出现的位置
int index = arrlist.indexOf(44.5);
System.out.println("index = " + index); // 0
isEmpty()
作用:集合是否为空;
参数:无;
返回值:布尔值;
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 返回第一次出现的位置
boolean empty = arrlist.isEmpty();
System.out.println("empty = " + empty);
iterator():ArrayList类中的Iterator方法实现了List接口中的接口抽象方法,List接口实现了Iterator抽象类中的方法。
作用:迭代器遍历元素;
参数:无;
返回值:迭代器Iterator对象;
示例:
// 创建ArrayList对象,同时设置泛型
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 创建迭代器对象
Iterator<String> iterator = arrlist.iterator();
集合遍历
对于ArrayList而言,底层为数组。
方式1:普通for循环遍历
// 创建ArrayList对象,同时设置泛型
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 遍历元素
for (int i = 0; i < arrlist.size(); i++) {
System.out.println("item" + i + " = " + arrlist.get(i));
}
方式2:迭代器遍历
// 创建ArrayList对象,同时设置泛型
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 迭代器遍历
// 创建迭代器对象
Iterator<String> iterator = arrlist.iterator();
// 使用迭代器类中的实例方法 iterator.hasNext() 判断当前迭代器对象中是否还有元素
while (iterator.hasNext()){
System.out.println(iterator.next());
}
方式3:增强for循环:底层实现还是迭代器,JDK1.5新增内容,属于对迭代器书写格式的简化。
// 创建ArrayList对象,同时设置泛型
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 增强for循环
for (String str : arrlist) {
System.out.println("str = " + str);
}
增强for遍历
idea快捷键:元素名称.for
增强for循环:可以遍历数组,遍历集合。底层实现还是迭代器,JDK1.5新增内容,属于对迭代器书写格式的简化。
// 创建ArrayList对象,同时设置泛型
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 增强for循环
for (String str : arrlist) {
System.out.println("str = " + str);
}
集合特点
- 有序,空间连续(默认顺序是元素插入顺序);
- 有下标
- 允许重复
- 允许null元素
- 线程不安全
数据结构
ArrayList的数据结构是数组。
源码解析
通常在Java中把某个对象的引用置为null,就可以等着Java中的gc等着回收空间。
1、 调用ArrayList无参构造的时候,在底层维护了一个长度为0的数组。
2、调用ArrayList中的add方法时,才将数组的长度改为10,当集合空间不够时,扩容集合空间,默认扩容为原有空间的1.5倍空间。
3、 增删改查效率问题
增删改查效率:查询 和 修改 快
添加如果需要扩容的、插入元素的情况 效率较低 因为需要复制数组 或者 移动元素
删除需要移动元素的情况 效率低
迭代器类
Iterator类
迭代器是无法保证顺序,集合中的元素将原封不动的保存在迭代器对象中。
迭代器是没有下标概念的,每次遍历先查询迭代器对象中还有没有元素,如果有则取出(返回元素),然后继续遍历。没有则返回null。
迭代器遍历的过程
遍历之前游标指针默认指向空;
当调用了 hasNext() 方法之后,指针就会向后移动一位,同时把这个元素从迭代器对象中删除;
也就是永远也无法再迭代器对象中找到这个返回的数据了。
方法
hasNext()
作用:如果迭代具有更多元素,则返回 true,否则返回false;
参数:无;
返回值:布尔类型;
示例:
Iterator<String> iterator = arrlist.iterator();
boolean b = iterator.hasNext();
next()
作用:返回迭代中的下一个元素;
参数:无;
返回值:Object;
示例:
// 创建ArrayList对象,同时设置泛型
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 迭代器遍历
// 创建迭代器对象
Iterator<String> iterator = arrlist.iterator();
String next = iterator.next();
System.out.println("next = " + next); // next = sakuna
泛型
泛型:用于统一集合中的数据类型。
// 创建ArrayList对象,同时设置泛型 String
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 遍历元素
for (int i = 0; i < arrlist.size(); i++) {
System.out.println("item" + i + " = " + arrlist.get(i));
}
Vector类
基本使用
构造函数
初始容量为10,扩容容量默认为2倍,可通过构造函数指定扩容倍数。
无参构造
Vector()
有参构造
Vector(int initialCapacity, int capacityIncrement)
构造具有指定初始容量和容量增量
方法: 此类中拥有的方法和ArrayList类中的方法是一样的。
add()
作用:添加元素,默认添加在末尾。在指定位置添加元素。
参数:object 或 index,object;
当传入一个对象时,默认添加在末尾;
当传入一个index和obj时,会在指定下标处添加元素obj;
返回值:布尔值或无
示例:
// 创建ArrayList对象
Vector vector = new Vector();
// add 方法 实例级别
boolean res1 = vector.add("sakuna is kawaii");
// 在指定位置插入元素
vector.add(1,"yousa");
...
集合遍历
集合遍历的方式和ArrayList类中方式相同。
方式1:
// 普通for循环遍历
for (int i = 0; i < vector.size(); i++) {
Object item = vector.get(i);
System.out.println("item = " + item);
}
方式2:
// 迭代器遍历
Iterator iterator = vector.iterator();
while (iterator.hasNext()){
Object item = iterator.next();
System.out.println("item = " + item);
}
方式3:
// 增强for遍历
for (Object item : vector) {
System.out.println("item = " + item);
}
面试题
ArrayList类和Vector类的区别?
1、ArrayList线程不安全,Vector线程安全;
2、ArrayList无参构造维护长度为0空数组,Vector无参构造维护长度为10的数组;
3、ArrayList默认扩容1.5倍,Vector扩容2倍;
4、ArrayList不允许指定增量,Vector可以指定增量;
StringBuffer和StringBuilder的区别
StringBuffer 线程安全
StringBuilder 线程不安全
源码解析
1、调用构造,创建对象时,代码执行过程。
2、 添加元素的时候,代码执行过程。
3、删除元素时,代码执行过程。
LinkedList类
如同生活中的链子一样,实现了List接口,同时实现了Deque(队列)接口,他有列表的功能,同时拥有数组功能。
基本使用
构造方法
// 构造一个空列表
LinkedList()
// 构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序
LinkedList(Collection<? extends E> c)
方法: 除了拥有ArrayList类相同的方法以外,还单独拥有操作头部和尾部的方法。
add()
作用:添加元素,默认添加在末尾。在指定位置添加元素。
参数:object 或 index,object;
当传入一个对象时,默认添加在末尾;
当传入一个index和obj时,会在指定下标处添加元素obj;
返回值:布尔值或无
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
...
remove():这个方法和ArrayList中的remove有些许差别,他支持无参删除
作用:删除集合内的元素
参数:object或下标或无
当传入object时,从前往后匹配,删除第一个匹配到的元素;
当传入下标index时,删除指定下标的元素;
当无参时,默认删除第一个元素;
返回值:
当传入obj类型时,返回值类型是布尔类型,是否删除成功;
当传入是下标时,返回值是删除的元素本身;
当无参时,返回删除元素本身;
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
Object rmItem = linkedList.remove(); // sakuna
Object rmItem2 = linkedList.remove(1); // Hikari
System.out.println("rmItem = " + rmItem);
addFirst()
作用:在链表的头部添加元素
参数:object元素
返回值:无
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
linkedList.addFirst("charl");
addLast()
作用:在链表的尾部添加元素
参数:object
返回值:无
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
linkedList.addFirst("charl");
// 在链表的末尾添加元素
linkedList.addLast("Reine");
getFirst()
作用:获取链表的第一个元素
参数:无;
返回值:Object元素;
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
linkedList.addFirst("charl");
linkedList.addLast("Reine");
// 获取列表的首个元素
Object firstItem = linkedList.getFirst();
System.out.println("firstItem = " + firstItem);
getLast()
作用:获取链表的最后一个元素
参数:无;
返回值:Object元素;
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
linkedList.addFirst("charl");
linkedList.addLast("Reine");
// 获取列表的首个元素
Object firstItem = linkedList.getFirst();
Object lastItem = linkedList.getLast();
System.out.println("firstItem = " + firstItem);
System.out.println("lastItem = " + lastItem);
removeFirst()
作用:删除集合内的第一个元素
参数:无
返回值:删除的元素本身
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
linkedList.addFirst("charl");
linkedList.addLast("Reine");
// 删除第一个元素
Object rmFirstItem = linkedList.removeFirst();
System.out.println("rmFirstItem = " + rmFirstItem); // rmFirstItem = charl
removeLast()
作用:删除集合内的最后一个元素
参数:无
返回值:删除的元素本身
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
linkedList.addFirst("charl");
linkedList.addLast("Reine");
// 删除第一个元素
Object rmFirstItem = linkedList.removeFirst();
System.out.println("rmFirstItem = " + rmFirstItem); // rmFirstItem = charl
// 删除最后一个元素
Object rmLastItem = linkedList.removeLast();
System.out.println("rmLastItem = " + rmLastItem); // rmLastItem = Reine
集合遍历
遍历如同ArrayList集合遍历方式
方式1:for循环(一次一次的查询获取到数据),越往后查询越慢,因为空间不连续,需要先查找相邻的元素,才能找到指定元素。而ArrayList底层使用的是数组,可以一次查询到对应元素,所以ArrayList类中for循环比较快。
// 普通for循环遍历
for (int i = 0; i < linkedList.size(); i++) {
Object item = linkedList.get(i);
System.out.println("item = " + item);
}
方式2:迭代器遍历(直接下一个返回数据,效率要高于for循环遍历)
// 迭代器遍历
Iterator iterator = linkedList.iterator();
while (iterator.hasNext()){
Object item = iterator.next();
System.out.println("item = " + item);
}
方式3:增强for循环遍历(底层使用的仍是迭代器)
// 增强for遍历
for (Object item : linkedList) {
System.out.println("item = " + item);
}
不推荐普通方式遍历 LinkedList集合
集合特点
有序,空间不连续,可以利用碎片空间;
有下标;
可以重复;
允许null元素;
线程不安全;
空间不连续示意图:
在内存物理空间上不连续,但是还是有顺序的。
数据结构
LinkedList类中的每个元素(Node)的特点。
LinkedList的数据结构是双向链表。
不需要扩容;
删除,添加元素不需要移动元素;
查询,修改(也需要先查询)元素效率低,因为必须要先找到相邻元素位置,才能找到对应元素;
新增元素默认在末尾添加元素;
双向链表
数据结构:双向链表 没有初始大小 没有上限大小 不需要扩容
源码定义:
private static class Node<E> {
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; // 指向前一个元素地址
}
}
源码解析
1、调用构造,创建对象时,代码执行过程。
2、 添加元素的时候,默认添加元素到末尾,代码执行过程。
3、删除元素时,代码执行过程,需要先查询元素(这里做了优化,设置长度中间值,大于中间值从后往前,小于中间值从前往后)
删除过程
4、修改元素时,代码执行过程。
数组和链表的区别
1、数组长度固定,链表长度不固定。
2、数组的空间是连续的,链表的空间不连续。
3、数组空间连续查询和修改效率高,一次查询一次获得。添加和删除需要移动元素,所以慢。链表空间不连续,查询和修改需要找到相邻的元素,效率低;添加和删除不需要移动元素,效率高。
Collections工具类
注意有个 s
和Arrays类同级别,这个是Collection集合类本身上的方法。此类全部使用的静态方法。如果集合中为null,则会抛出空指针异常。此类中提供了用于操作集合的各种方法。
基本使用
静态方法
swap(list, int i, int j)
作用:交换指定位置的集合中的元素
参数:
第一个参数是List集合对象list;
第二个参数是集合中下标int;
第三个参数是集合中的下标int
返回值:无
示例:
// 利用Integer类中的重写的自然排序
ArrayList<Integer> arrayList = new ArrayList<>();
// 添加元素
arrayList.add(16);
arrayList.add(20);
arrayList.add(18);
arrayList.add(15);
// 利用元素对象类中的重写的自然排序
// Collections.sort(arrayList);
// 交换位置
Collections.swap(arrayList,1,0);
// 遍历元素 默认顺序是 元素插入顺序
for (Integer integer : arrayList) {
System.out.println(integer);
}
sort(list,Comparator)
作用:根据指定的比较器引起的顺序对指定的列表进行排序
说明:如果使用自定义的Student类作为List的元素,需要在Student类中实现Comparable接口(详见HashMap章节中Comparable接口的使用介绍)或单独传入一个自定义的比较器类(实现Comparator接口)
参数:
第一个参数是List集合对象list;
第二个参数是比较器对象(自定义比较器类)或无(使用集合中元素类的内部的比较方法)
返回值:无
示例:
// 利用Integer类中的重写的自然排序
ArrayList<Integer> arrayList = new ArrayList<>();
// 添加元素
arrayList.add(16);
arrayList.add(20);
arrayList.add(18);
arrayList.add(15);
// 利用元素对象类中的重写的自然排序
Collections.sort(arrayList);
// 遍历元素 默认顺序是 元素插入顺序,使用sort后,变为升序
for (Integer integer : arrayList) {
System.out.println(integer);
}
自定义类Singer类(自然排序)的使用示例
package com.collectionToolsPart;
import java.util.ArrayList;
import java.util.Collections;
public class TestCollectionTools {
public static void main(String[] args) {
// 创建ArrayList集合对象
ArrayList<Singer> arrayList = new ArrayList<Singer>();
// 创建 Singer对象
Singer s1 = new Singer("Sakuna",26);
Singer s2 = new Singer("冰糖IO",27);
Singer s3 = new Singer("yousa",26);
Singer s4 = new Singer("Akie",25);
// 往集合中添加元素
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
arrayList.add(s4);
// 使用集合工具类,未使用工具类排序,默认是元素的插入顺序。
// 使用工具类 sort方法排序,默认是升序
Collections.sort(arrayList);
// 遍历集合
for (Singer singer : arrayList) {
System.out.println(singer);
}
}
}
package com.collectionToolsPart;
public class Singer implements Comparable<Singer>{
private String name;
private int 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;
}
public Singer(String name, int age) {
this.name = name;
this.age = age;
}
// 重写
@Override
public String toString() {
return "Singer{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
// 在对象类中重写排序方法也叫做自然排序
@Override
public int compareTo(Singer s) {
return this.age - s.age == 0 ? 0 : (this.age - s.age > 0 ? 1 : -1);
}
}
reverse(list)
作用:反转指定列表中元素的顺序
参数:List集合对象list
返回值:无
示例:
// 利用Integer类中的重写的自然排序
ArrayList<Integer> arrayList = new ArrayList<>();
// 添加元素
arrayList.add(16);
arrayList.add(20);
arrayList.add(18);
arrayList.add(15);
// 反转集合顺序
Collections.reverse(arrayList);
// 遍历元素 默认顺序是 元素插入顺序
for (Integer integer : arrayList) {
System.out.println(integer);
}
replaceAll(list,oldVal,newVal)
作用:将列表中一个指定值的所有出现替换为另一个
参数:
第一个参数是List集合对象list;
第二个参数是老值obj;
第三个参数是新值obj;
返回值:布尔值,成功则 true,失败则false
示例:
// 利用Integer类中的重写的自然排序
ArrayList<Integer> arrayList = new ArrayList<>();
// 添加元素
arrayList.add(16);
arrayList.add(20);
arrayList.add(20);
arrayList.add(18);
arrayList.add(15);
// 替换所有元素为指定元素的出现为新值
boolean res = Collections.replaceAll(arrayList, 20, 45);
System.out.println("res = " + res); // res = false
min(list)
作用:根据集合对象list的内的元素的类的自然顺序返回给定集合的最小元素
参数:List集合对象list;
返回值:无
示例:
// 利用Integer类中的重写的自然排序
ArrayList<Integer> arrayList = new ArrayList<>();
// 添加元素
arrayList.add(16);
arrayList.add(20);
arrayList.add(18);
arrayList.add(15);
// 根据集合对象中的元素的类的自然排序找打最小值
Integer min = Collections.min(arrayList);
System.out.println("min = " + min); // min = 15
// 遍历元素 默认顺序是 元素插入顺序
for (Integer integer : arrayList) {
System.out.println(integer);
}
max(list)
作用:根据集合对象list的内的元素的类的自然顺序返回给定集合的最大元素
参数:List集合对象list;
返回值:无
示例:
// 利用Integer类中的重写的自然排序
ArrayList<Integer> arrayList = new ArrayList<>();
// 添加元素
arrayList.add(16);
arrayList.add(20);
arrayList.add(18);
arrayList.add(15);
// 根据集合对象中的元素的类的自然排序找打最小值
Integer max = Collections.max(arrayList);
System.out.println("max = " + max); // min = 20
// 遍历元素 默认顺序是 元素插入顺序
for (Integer integer : arrayList) {
System.out.println(integer);
}
fill(list,obj)
作用:用指定的元素代替指定列表的所有元素
参数:
第一个参数是List集合对象list;
第二个参数是填充的元素Obj
返回值:无
示例:
// 利用Integer类中的重写的自然排序
ArrayList<Integer> arrayList = new ArrayList<>();
// 添加元素
arrayList.add(16);
arrayList.add(20);
arrayList.add(18);
arrayList.add(15);
// 用指定的元素代替指定列表的所有元素
Collections.fill(arrayList,445);
// 遍历元素 默认顺序是 元素插入顺序
for (Integer integer : arrayList) {
System.out.println(integer);
}
binarySearch(list,obj)
作用:二叉搜索List集合对象list中的元素item
参数:
第一个元素是List集合对象list;
第二个参数是list集合对象中的元素Obj
返回值:
若元素找到返回第一个匹配到的元素的下标int类型
若未找到则返回负数 int类型(这个负数是把这个元素存放进入并排序,得到这个元素的位置n,然后再 -(n+1) )
示例:
// 利用Integer类中的重写的自然排序
ArrayList<Integer> arrayList = new ArrayList<>();
// 添加元素
arrayList.add(15);
arrayList.add(20);
arrayList.add(18);
arrayList.add(15);
// 使用二叉搜索算法搜索指定对象的指定列表
int i = Collections.binarySearch(arrayList, 17);
System.out.println("i = " + i);
泛型
泛型的作用:用于统一数据类型;
泛型的使用范围:类、接口、形参、返回值、属性;
基本使用
自定义泛型名称:泛型的名称可以使用任何单词、字母、大小写都可以,但是我们只推荐使用一些有公认的含义的一些大写字母。
- 公认的泛型名称:
K Key 键
V Value 值
T Type 类型
E Element 元素
R Return 返回值
P Parameter 参数
N Number 数值
- 泛型初始化时机:
1.类声明的泛型 是随着当前类创建对象初始化
2.接口声明的泛型 是随着实现类实现接口初始化
目前所学习的泛型达到,看到了知道什么意思即可
示例1:类的泛型使用
// 在类的定义上添加泛型
// 定义一个宠物类,同时在类的定义(声明)上设置泛型
// 在初始化对象时,可以设置泛型的类型T,这样返回值和传入参数的类型就可以确定统一了。(灵活统一)
class Pet<T>{
// 类中的方法的形参上使用泛型
public void m1(T t){
System.out.println("类中的方法的形参上使用泛型" + t);
}
// 类的方法的返回值上使用泛型
public T m2(T t){
return t;
}
// 类的静态方法上不能使用类上定义的泛型,因为初始化时机不同
// 类中的静态方法上设置泛型,可以通过直接在静态方法上设置
public static <E> E m3(E e){
return e;
}
public static <E> E m4(List<E> list){
return list.get(0);
}
public static <E> void m5(E e){
System.out.println("宠物类-静态方法-m5-返回值为空" + e);
}
}
// 定义一个猫类作为泛型
class Cat{
public String name;
public int health;
// 定义方法
public void eatFish(){
System.out.println("猫吃鱼");
}
}
// 测试类
public static void main(String[] args) {
// 定义一个Pet对象,初始化对象时,设置泛型
Pet<Cat> pet = new Pet<>();
// 定义一个Cat对象
Cat cat1 = new Cat();
// 使用pet对象的方法m1
pet.m1(cat1); // com.generic.Cat@4554617c
// 使用Pet类中的m3
String name = Pet.m3("九月"); // name = 九月
// 使用Pet类中的m5
Pet.m5("十一月"); // 宠物类-静态方法-m5-返回值为空十一月
}
示例2:静态方法上的泛型设置
- 不可以使用类上定义的泛型,因为类声明的泛型在创建对象时初始化,初始化的时机不同;
- 直接在静态方法上定义泛型
// 在类的定义上添加泛型
// 定义一个宠物类,同时在类的定义(声明)上设置泛型
// 在初始化对象时,可以设置泛型的类型T,这样返回值和传入参数的类型就可以确定统一了。(灵活统一)
class Pet<T>{
// 类中的方法的形参上使用泛型
public void m1(T t){
System.out.println("类中的方法的形参上使用泛型" + t);
}
// 类的方法的返回值上使用泛型
public T m2(T t){
return t;
}
// 类的静态方法上不能使用类上定义的泛型,因为初始化时机不同
// 类中的静态方法上设置泛型,可以通过直接在静态方法上设置
public static <E> E m3(E e){
return e;
}
public static <E> E m4(List<E> list){
return list.get(0);
}
public static <E> void m5(E e){
System.out.println("宠物类-静态方法-m5-返回值为空" + e);
}
}
// 定义一个猫类作为泛型
class Cat{
public String name;
public int health;
// 定义方法
public void eatFish(){
System.out.println("猫吃鱼");
}
}
// 测试类
public static void main(String[] args) {
// 定义一个Pet对象,初始化对象时,设置泛型
Pet<Cat> pet = new Pet<>();
// 定义一个Cat对象
Cat cat1 = new Cat();
// 使用pet对象的方法m1
pet.m1(cat1); // com.generic.Cat@4554617c
// 使用Pet类中的m3
String name = Pet.m3("九月"); // name = 九月
// 使用Pet类中的m5
Pet.m5("十一月"); // 宠物类-静态方法-m5-返回值为空十一月
}
示例3:接口的泛型使用
// 在接口的定义上添加泛型
// 定义一个接口,同时设置泛型
interface Student<R,P>{
// 定义一个抽象方法,返回值为R类型,参数为P类型
R m1(P p);
}
// 实现这个接口,同时传入泛型,在实现类上,设置泛型的类型
class Pupil implements Student<String,Integer>{
// 重写方法中使用泛型
@Override
public String m1(Integer integer) {
return "实现类-Pupil-m1";
}
}
// 测试类上使用泛型
public static void main(String[] args) {
// 创建学生对象
Pupil p1 = new Pupil();
// 调用m1方法
String res = p1.m1(9); // 实现类-Pupil-m1
}
示例4:集合的泛型使用
// 创建一个静态方法,参数设置为一个List集合,List集合中的元素的类型为Pet类型
// 设置List集合中的元素的泛型为Pet
public static void m1(List<Pet> list){
System.out.println("m1方法执行");
}
// 静态方法
public static void main(String[] args) {
List<Pet> list1 = new ArrayList<>();
List<Pet> list2 = new Vector<>();
List<Pet> list3 = new LinkedList<>();
// 调用m1静态方法
m1(list1); // m1方法执行
m1(list2); // m1方法执行
m1(list3); // m1方法执行
}
class Pet<T>{
// 类中的方法的形参上使用泛型
public void m1(T t){
System.out.println("类中的方法的形参上使用泛型" + t);
}
// 类的方法的返回值上使用泛型
public T m2(T t){
return t;
}
}
class Cat{
public String name;
public int health;
// 定义方法
public void eatFish(){
System.out.println("猫吃鱼");
}
}
示例5:集合的泛型的子类设置使用(泛型是没有类型提升的机制的)
- 泛型是没有类型提升的机制的
- 给泛型设置上限,没有下限,任何子类,间接子类都可以。
- 通过
? extends 父类
设置;
// 要求形参是Pet类型,或是Pet类型的子类
// 泛型的子类如何设置 通过 ? extends 类型 设置
示例6:集合的泛型的父类设置(不可以)
示例7:集合的泛型的子子类设置
public class TestCollectGeniric {
// 创建一个静态方法,参数设置为一个List集合,List集合中的元素的类型为Pet类型
// 设置List集合中的元素的泛型为Pet
public static void m1(List<Pet> list){
System.out.println("m1方法执行");
}
// 要求形参为Pet类型以及Pet类型的任意子类
// ? extends 父类 : 表示泛型可以为父类 以及 父类的任何子类
public static void m2(List<? extends Pet> list){
System.out.println("m2方法执行");
}
// 静态方法
public static void main(String[] args) {
// 泛型为父类
ArrayList<Pet> list1 = new ArrayList<>();
Vector<Pet> list2 = new Vector<>();
LinkedList<Pet> list3 = new LinkedList<>();
// 泛型为子类
ArrayList<Cat> list4 = new ArrayList<>();
// 调用m1静态方法
m1(list1); // m1方法执行
m1(list2); // m1方法执行
m1(list3); // m1方法执行
// 调用m2静态方法
m2(list4);
}
}
class Pet<T>{
// 类中的方法的形参上使用泛型
public void m1(T t){
System.out.println("类中的方法的形参上使用泛型" + t);
}
// 类的方法的返回值上使用泛型
public T m2(T t){
return t;
}
}
class Cat extends Pet{
public String name;
public int health;
// 定义方法
public void eatFish(){
System.out.println("猫吃鱼");
}
}
示例8:集合的泛型的父类设置
- 设置泛型的下限,没有上限,任何父类,间接父类都可以。
- 通过
? super 子类
设置;
// 形参的泛型为Cat 以及 Cat类的任何父类
public class TestCollectGeniric {
// 创建一个静态方法,参数设置为一个List集合,List集合中的元素的类型为Pet类型
// 设置List集合中的元素的泛型为Pet
public static void m1(List<Pet> list){
System.out.println("m1方法执行");
}
// 要求形参为Pet类型以及Pet类型的任意子类
// ? extends 父类 : 表示泛型可以为父类 以及 父类的任何子类
// 设置上限
public static void m2(List<? extends Pet> list){
System.out.println("m2方法执行");
}
// 要求:形参的泛型为Cat 以及 Cat类的任何父类
// ? super 子类: 表示泛型可以为子类 以及 任何子类的父类
// 泛型的父类如何设置 通过 ? super 类型 设置
// 设置下限
public static void m3(List<? super Cat> list){
System.out.println("m3方法执行");
}
// 静态方法
public static void main(String[] args) {
// 泛型为父类
ArrayList<Pet> list1 = new ArrayList<>();
Vector<Pet> list2 = new Vector<>();
LinkedList<Pet> list3 = new LinkedList<>();
// 泛型为子类,设置上限
ArrayList<Cat> list4 = new ArrayList<>();
// 泛型为父类,设置下限
ArrayList<Animal> list5 = new ArrayList<>();
// 调用m1静态方法
m1(list1); // m1方法执行
// 调用m2静态方法
m2(list4);
// 调用m3静态方法
m3(list5);
}
}
class Animal <T>{
}
class Pet<T> extends Animal{
// 类中的方法的形参上使用泛型
public void m1(T t){
System.out.println("类中的方法的形参上使用泛型" + t);
}
// 类的方法的返回值上使用泛型
public T m2(T t){
return t;
}
}
class Cat extends Pet{
public String name;
public int health;
// 定义方法
public void eatFish(){
System.out.println("猫吃鱼");
}
}