回忆
- java.util.Date
- new Date()
- new Date(long )
- java.util.Calender
- Calender.getInstance();
- get
- set
- add
- java.text.DateFormat
- SimpleDateFormat
- yyyy-MM-dd HH:mm:ss
- parse
- format
- 包装类型
- 首字母大写
- Character
- Integer
- parseXxx的方法将字符串转换为对应的类型
- String.valueOf()方法将对应的类型转换为字符串
- System类
- exit 退出程序
- gc 垃圾回收
- 当前毫秒数
- copyArray 高效数组复制
- Arrays工具类
- toString 打印数组的内容
- sort
- binarySearch
- 截取
- 复制到一个新的长度
- 批量填充
集合(很重要)
它比数组还要常用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Juv008Yc-1593268055637)(imges/image-20200627092825930.png)]
Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。
- 一些 collection 允许有重复的元素,而另一些则不允许。
- 一些 collection 是有序的,而另一些则是无序的。
- JDK 不提供此接口的任何直接 实现:它提供更具体的子接口(如
Set
和List
)实现。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iYmyBx1T-1593268055642)(imges/image-20200627093137930.png)]
跟数组的对比
- 数组:长度确定,类型确定。
- 类型可以是基本类型、引用类型
- 集合:长度不固定(最大的优势)
- 元素类型只能是引用类型。
Collection接口的使用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jjggq7gL-1593268055645)(imges/image-20200627093608992.png)]
//1. 我如何得到Collection接口的实例呢?
创建一个Collection接口的实现类。比如:ArrayList
集合的遍历-迭代器
Iterator<E> iterator()
返回在此 collection 的元素上进行迭代的迭代器。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RYdrTgJG-1593268055650)(imges/image-20200627100115131.png)]
注意:如果hashNext()返回了false的情况下,再继续调用next()方法会抛出异常:
java.util.NoSuchElementException
//重点:关于集合的遍历,Java专门提供了一种迭代器
Iterator iterator = cc.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
List接口
有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。允许重复的元素。
List集合的特点:有序、可重复。
void add(int index, E element)
在列表的指定位置插入指定元素(可选操作)。
boolean addAll(int index, Collection<? extends E> c)
将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。
E get(int index)
返回列表中指定位置的元素。
int indexOf(Object o)
返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
int lastIndexOf(Object o)
返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。
ListIterator<E> listIterator()
返回此列表元素的列表迭代器(按适当顺序)。
ListIterator<E> listIterator(int index)
返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。
E remove(int index)
移除列表中指定位置的元素(可选操作)。
E set(int index, E element)
用指定元素替换列表中指定位置的元素(可选操作)。
List<E> subList(int fromIndex, int toIndex)
返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
/*
需求: 定义包含 1 2 3 4 5 的集合
遍历它,如果发现集合元素可以被2整除,在此元素的后面添加一个 -1.
*/
迭代器的异常
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tXAICLKp-1593268055653)(imges/image-20200627112151496.png)]
本质原因:
- 是使用迭代器进行迭代的过程中,未通过迭代器修改了集合的长度(一般就是插入的新的元素),迭代器并不知道。就会抛出并发修改异常。
解决方案有两种:
- 用for循环实现。
- 添加或删除操作必须通过迭代器来进行。
//1. 优先考虑迭代器
// 注意: nextIndex 要在next之前调用。
ListIterator iterator = cc.listIterator();
while (iterator.hasNext()){
int i = iterator.nextIndex(); //当前迭代的位置
Object next = iterator.next();
Integer n = (Integer)next;
if(n % 2 ==0){
System.out.println(i+"发现了元素:"+n);
//add
// cc.add(i, -1);
// cc.remove(i);
//注意:改变长度的时候,不要直接调用集合的方法,而应该使用迭代器的方法
iterator.add(-1);
}
}
常见的数据结构
程序 = 数据结构 +算法;
- 栈结构: 后进先出。
- 队列:先进先出。
- 数组: 特点是检索快,增删慢。
- 链表:检索慢,增删快。
- 单向链表
- 双向链表
- 循环链表
- 双向循环链表
- 树
- 二叉树: 最多两个子节点
List常见实现类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z73Mg5Mt-1593268055655)(imges/image-20200627114321784.png)]
-
Vector 是旧的List集合。 线程安全,效率低。
-
旧的集合体系,就是API命名上多少有些差异,使用上没差异。
-
void addElement(E obj) 将指定的组件添加到此向量的末尾,将其大小增加 1。 int capacity() 返回此向量的当前容量。 void copyInto(Object[] anArray) 将此向量的组件复制到指定的数组中。 E elementAt(int index) 返回指定索引处的组件。 Enumeration<E> elements() 迭代 返回此向量的组件的枚举。 E firstElement() 返回此向量的第一个组件(位于索引 0) 处的项)。 void insertElementAt(E obj, int index) 将指定对象作为此向量中的组件插入到指定的 index 处。 E lastElement() 返回此向量的最后一个组件。 void removeAllElements() 从此向量中移除全部组件,并将其大小设置为零。 boolean removeElement(Object obj) 从此向量中移除变量的第一个(索引最小的)匹配项。 void removeElementAt(int index) 删除指定索引处的组件。 protected void removeRange(int fromIndex, int toIndex) 从此 List 中移除其索引位于 fromIndex(包括)与 toIndex(不包括)之间的所有元素。 void setElementAt(E obj, int index) 将此向量指定 index 处的组件设置为指定的对象。
-
Enumeration elements = v.elements(); while(elements.hasMoreElements()){ System.out.println(elements.nextElement()); }
-
被ArrayList取代。线程不安全,效率高。
-
-
ArrayList 底层使用的是数组。【日常开发用的多】
-
LinkedList 底层使用的是链表。
-
void addFirst(E e) 将指定元素插入此列表的开头。 void addLast(E e) 将指定元素添加到此列表的结尾。 Iterator<E> descendingIterator() 返回以逆向顺序在此双端队列的元素上进行迭代的迭代器。 E element() 获取但不移除此列表的头(第一个元素)。 E getFirst() 返回此列表的第一个元素。 E getLast() 返回此列表的最后一个元素。 boolean offer(E e) 将指定元素添加到此列表的末尾(最后一个元素)。 boolean offerFirst(E e) 在此列表的开头插入指定的元素。 boolean offerLast(E e) 在此列表末尾插入指定的元素。 E peek() 获取但不移除此列表的头(第一个元素)。 E peekFirst() 获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。 E peekLast() 获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。 E poll() 获取并移除此列表的头(第一个元素) E pollFirst() 获取并移除此列表的第一个元素;如果此列表为空,则返回 null。 E pollLast() 获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。 E pop() 从此列表所表示的堆栈处弹出一个元素。 void push(E e) 将元素推入此列表所表示的堆栈。 E remove() 获取并移除此列表的头(第一个元素)。 E removeFirst() 移除并返回此列表的第一个元素。 boolean removeFirstOccurrence(Object o) 从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表时)。 E removeLast() 移除并返回此列表的最后一个元素。 boolean removeLastOccurrence(Object o) 从此列表中移除最后一次出现的指定元素(从头部到尾部遍历列表时)。
练习:
- 去除集合中重复的字符串的值。(“hello”,“java”,“world”,“hello”,“java”,“test”) -> (“hello”,“java”,“world”,“test”)
- 去除集合中重复的学生(name,age)。(new st1,st2,st3,st3,st4,st5)
- 集合中的
indexof
也好contains
方法也好,底层都是调用元素对象的equals
方法。- 如果不满足需求,需要按需重写
equals
方法。
- 如果不满足需求,需要按需重写
- 集合中的
-
泛型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m1QiINsA-1593268055656)(imges/image-20200627162914791.png)]
当不写泛型的时候,认为是Object。
ArrayList arrayList = new ArrayList();
//不写泛型的时候(为了先下兼容),认为元素类型就是Object,
//等价于 ArrayList<Object>
arrayList.add("hello");
arrayList.add("world");
arrayList.add(10);//Integer -> 装箱操作
//问题就在于消费集合元素时,无法确定元素的类型。只能在运行时暴露异常信息。
//为了解决此问题,Java语言就提供了泛型的技术,用来约束集合中元素的类型。
// 并且它会将异常提前到编译期。
泛型的定义很简单,只要在原来的 接口 、类 上使用 <>
的语法就可以产生 泛型接口、泛型类。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vxjzsJio-1593268055657)(imges/image-20200627164317357.png)]
/*
演示自己定义一个泛型类
*/
public class Demo2 {
public static void main(String[] args) {
//即使你是一个泛型类,也可以不指定泛型类型(默认就是Object)
Class2 class2 = new Class2();
class2.setAge("hello");
Object age = class2.getAge();
class2.method1("hello");
//当在代码中提供了泛型以后,就可以使用泛型带来的好处
// 类型绑定,将对应的类型确定下来
Class2<Integer,String> clazz2 = new Class2<Integer, String>();
//jdk 1.7 支持泛型推断
Class2<Integer,String> clazz3 = new Class2<>();
// clazz2.setAge("hello");//报错,编译期错误.
clazz2.setAge(10);
System.out.println(clazz2.getAge());
clazz2.method1("hhhh");
}
}
//尖括号中的标识符是自己起的,数量没有限制,用逗号分隔就行.
//只是从实践中,大家会使用一些见名知意的泛型标识:
//E-----element
//T----- type
//Pk---- 主键
//有了泛型定义以后,所有类中出现类型的地方(成员类型、方法返回值、方法参数)可以直接使用泛型标识
class Class<T>{
}
class Class2<T,M>{
private T age;
public T getAge() {
return age;
}
public void setAge(T age) {
this.age = age;
}
public void method1(M m){
System.out.println(m);
}
}
/*
其实即使是一个普通的Java类(非泛型类),也支持在类中定义泛型方法。
语法格式:
修饰符 <T> 返回值类型 方法名(参数类型 参数名,.....){
}
具体T的绑定,可以出现在: 返回值类型、参数类型上。
*/
public class Demo3 {
public static void main(String[] args) {
DemoMethod.eq("aaa", 10);
Object o = DemoMethod.m2(2, 3);
}
}
class DemoMethod{
public static <T> boolean eq(T a,T b){
return a==b;
}
public static <T> T m2(Integer a,Integer b ){
return (T)null;
}
}
增强型for循环
//经典的for循环
for(初始化部分;条件判断部分;条件更新){
循环体;
}
//增强型for循环的语法
for(元素类型 变量名:可增强迭代的内容){
访问变量名;
}
// 可增强迭代的内容: 数组、集合。
int[] arr = {1,2,3,4,5};
for(int item :arr){
//特点: 在循环体中无法访问位置信息。
System.out.println(item);
}
//Arrays工具类中,存在一个方法来进行数组转集合。
List<int[]> ints = Arrays.asList(arr);
//集合的元素类型是: int数组。
for(int[] item:ints){
System.out.println(Arrays.toString(item));
}
注意事项:
-
本质是使用迭代器来进行
-
迭代前需要人为判断null的问题,否则报空指针异常。
-
//所以,增强型for循环一般会配合一个if检查一起使用。 if(arr!=null) { for (int item : arr) { //特点: 在循环体中无法访问位置信息。 System.out.println(item); } }
-
-
在迭代过程中,不能改变集合的长度。
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6VrG40mV-1593268055659)(imges/image-20200627171500638.png)]
可变参数(1.7)
方法声明中的参数类型后面跟 ...
从语法层面跟数组类似,但比数组灵活。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vjnsJKik-1593268055660)(imges/image-20200627172152467.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e5cb05QR-1593268055661)(imges/image-20200627172251782.png)]
注意事项:Arrays.asList的返回值类型不是我们学过的某个实现类,而是它自己的。
不能add等修改。
要想正常处理,必须再重新构造:
- new ArrayList(Arrays.asList(…));
。