1. Arrays
1.1 操作数组的工具类
方法名 | 说明 |
public static String toString(数组) | 把数组拼接成一个字符串 |
public static int binarySearch(数组,查找的元素) | 二分查找法查找元素 |
public static int[] copyOf(原数组,新数组长度) | 拷贝数组 |
public static int[] copyOfRange(原数组,起始索引,结束索引) | 拷贝数组(指定范围) |
public static void fill(数组,元素) | 填充数组 |
public static void sort(El) | 按照默认方式进行数组排序 |
public static void sort(数组,排序规则) | 按照指定的规则排序 |
import java.util.Arrays;
public class MyArraysDemo1 {
public static void main(String[] args) {
/*
public static String toString(数组) 把数组拼接成一个字符串
public static int binarySearch(数组,查找的元素) 二分查找法查找元素
public static int[] copyof(原数组,新数组长度) 拷贝数组
public static int[] copyOfRange(原数组,起始索引,结束索引) 拷贝数组(指定范围)
public static void fill(数组,元素) 填充数组
public static void sort(数组) 按照默认方式进行数组排序
public static void sort(数组,排序规则) 按照指定的规则排序
*/
//toString:将数组变成字符串
System.out.println("---------------toString--------------------");
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
System.out.println(Arrays.toString(arr));
//binarySearch:二分查找法查找元素
//binarySearch:二分查找法查找元素
//细节1:二分查找的前提:数组中的元素必须是有序,数组中的元素必须是升序的
//细节2:如果要查找的元素是存在的,那么返回的是真实的索引
//但是,如果要查找的元素是不存在的,返回的是 -插入点-1
//疑问:为什么要减1呢?
//解释:如果此时,我现在要查找数字0,那么如果返回的值是-插入点,就会出现问题了。
//如果要查找数字0,此时0是不存在的,但是按照上面的规则-插入点,应该就是-0。
//为了避免这样的情况,Java在这个基础上又减一。
System.out.println("-------------------binarySearch---------------");
System.out.println(Arrays.binarySearch(arr, 10));
System.out.println(Arrays.binarySearch(arr, 2));
System.out.println(Arrays.binarySearch(arr, 20));
//copyOf:拷贝数组
//copyOf:拷贝数组
//参数一:老数组
//参数二:新数组的长度
//方法的底层会根据第二个参数来创建新的数组
//如果新数组的长度是小于老数组的长度,会部分拷贝
//如果新数组的长度是等于老数组的长度,会完全拷贝
//如果新数组的长度是大于老数组的长度,会补上默认初始值
System.out.println("--------------copyof------------------------");
int[] newArr1 = Arrays.copyOf(arr, 20);
System.out.println(Arrays.toString(newArr1));
//copyOfRange:拷贝数组(指定范围)
//细节:包头不包尾,包左不包右
System.out.println("-----------------copyOfRange----------------");
int[] newArr2 = Arrays.copyOfRange(arr, 0, 9);
System.out.println(Arrays.toString(newArr2));
//fill:填充数组
System.out.println("---------------Fill--------------------");
Arrays.fill(arr, 100);
System.out.println(Arrays.toString(arr));
//sort:排序。默认情况下,给基本数据类型进行升序排列。底层使用的是快速排序。
System.out.println("--------------sort------------------------");
int[] arr2 = {10, 2, 3, 5, 6, 1, 7, 8, 4, 9};
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
}
1.2 重载的sort方法
import java.util.Arrays;
import java.util.Comparator;
public class MyArraysDemo1 {
public static void main(String[] args) {
/*
public static void sort(数组,排序规则) 按照指定的规则排序
参数一:要排序的数组
参数二:排序的规则
细节:
只能给引用数据类型的数组进行排序
如果数组是基本数据类型的,需要变成其对于的包装类
*/
Integer[] arr = {2, 3, 1, 5, 6, 7, 8, 4, 9};
//第二个参数是一个接口,所以我们在调用方法的时候,需要传递这个接口的实现类对象,作为排序的规则。
//但是这个实现类,我只要使用一次,所以就没有必要单独的去写一个类,直接采取匿名内部类的方式就可以了
//底层原理:
//利用插入排序+二分查找的方式进行排序的。
//默认把0索引的数据当做是有序的序列,1索引到最后认为是无序的序列。
//遍历无序的序列得到里面的每一个元素,假设当前遍历得到的元素是A元素
//把A往有序序列中进行插入,在插入的时候,是利用二分查找确定A元素的插入点。
//拿着A元素,跟插入点的元素进行比较,比较的规则就是cpmpare方法的方法体
//如果方法的返回值是负数,拿着A继续跟前面的数据进行比较
//如果方法的返回值是正数,拿着A继续跟后面的数据进行比较
//如果方法的返回值是0,也拿着A跟后面的数据进行比较
//直到能确定A的最终位置为止。
//compare方法的形式参数:
//参数一 01:表示在无序序列中,遍历得到的每一个元素
//参数二 o2:有序序列中的元素
//返回值:
//负数:表示当前要插入的元素是小的,放在前面
//正数:表示当前要插入的元素是大的,放在后面
//e:表示当前要插入的元素跟现在的元素比是一样的们也会放在后面
//简单理解:
//o1 - o2:升序排列
//o2 - o1:降序排序
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
System.out.println("---------------");
System.out.println("o1 : " + o1);
System.out.println("o2 : " + o2);
return o1-o2;
}
});
System.out.println(Arrays.toString(arr));
}
}
2. Lambda表达式
2.1 函数式编程
函数式编程(Functional programming)是一种思想特点。
函数式编程思想,忽略面向对象的复杂语法,强调做什么,而不是谁去做。
而我们要学习的Lambda表达式就是函数式思想的体现。
2.2 Lambda表达式的标准格式
Lambda表达式是JDK 8开始后的一种新语法形式。
- ()对应着方法的形参
- -> 固定格式
- {} 对应着方法的方法体
注意点:
● Lambda表达式可以用来简化匿名内部类的书写
● Lambda表达式只能简化函数式接口的匿名内部类的写法
● 函数式接口:有且仅有一个抽象方法的接口叫做函数式接口,接口上方可以加@Functionallnterface注解
public class MyArraysDemo1 {
public static void main(String[] args) {
//1.利用匿名内部类的形式去调用下面的方法
//调用一个方法的时候,如果方法的形参是一个接口,那么我们要传递这个接口的实现类对象
//如果实现类对象只要用到一次,就可以用匿名内部类的形式进行书写
/* method(new Swim() {
@Override
public void swimming() {
}
});*/
//2.利用1ambda表达式进行改写
method(()->System.out.println("正在游泳 ~~~ ")
);
}
public static void method(Swim s){
s.swimming();
}
interface Swim{
public abstract void swimming();
}
}
2.3 Lambda表达式的省略写法
● 参数类型可以省略不写。
● 如果只有一个参数,参数类型可以省略,同时()也可以省略。
●如果Lambda表达式的方法体只有一行,大括号,分号,return可以省略不写,需要同时省略。
3. Collection集合
3.1 数组和集合的区别
-
相同点
都是容器,可以存储多个数据
-
不同点
数组的长度是不可变的,集合的长度是可变的
数组可以存基本数据类型和引用数据类型
集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类
3.2 Collection 集合概述和使用
-
Collection集合概述
- 是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
- JDK 不提供此接口的任何直接实现.它提供更具体的子接口(如Set和List)实现
-
创建Collection集合的对象
- 多态的方式
- 具体的实现类ArrayList
-
Collection集合常用方法
方法名 说明 boolean add(E e) 添加元素 boolean remove(Object o) 从集合中移除指定的元素 boolean removeIf(Object o) 根据条件进行移除 void clear() 清空集合中的元素 boolean contains(Object o) 判断集合中是否存在指定的元素 boolean isEmpty() 判断集合是否为空 int size() 集合的长度,也就是集合中元素的个数
3.3 Collection集合的遍历
3.3.1 迭代器遍历
-
迭代器介绍
- 迭代器,集合的专用遍历方式。
- Iterator<E> iterator(): 返回此集合中元素的迭代器,通过集合对象的iterator()方法得到。
- Iterator中的常用方法
- boolean hasNext(): 判断当前位置是否有元素可以被取出 E next(): 获取当前位置的元素,将迭代器对象移向下一个索引位置.
-
Collection集合的遍历
public class IteratorDemo1 { public static void main(String[] args) { //创建集合对象 Collection<String> c = new ArrayList<>(); //添加元素 c.add("hello"); c.add("world"); c.add("java"); c.add("javaee"); //Iterator<E> iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到 Iterator<String> it = c.iterator(); //用while循环改进元素的判断和获取 while (it.hasNext()) { String s = it.next(); System.out.println(s); } } }
-
迭代器中删除的方法
void remove(): 删除迭代器对象当前指向的元素。
public class IteratorDemo2 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("b"); list.add("c"); list.add("d"); Iterator<String> it = list.iterator(); while(it.hasNext()){ String s = it.next(); if("b".equals(s)){ //指向谁,那么此时就删除谁. it.remove(); } } System.out.println(list); } }
3.3.2 增强for
-
介绍
- 它是JDK5之后出现的,其内部原理是一个Iterator迭代器
- 实现Iterable接口的类才可以使用迭代器和增强for
- 简化数组和Collection集合的遍历
-
格式
for(集合/数组中元素的数据类型 变量名 : 集合/数组名) {
// 已经将当前遍历到的元素封装到变量中了,直接使用变量即可
}
-
代码
public class MyCollectonDemo1 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); list.add("e"); list.add("f"); //1,数据类型一定是集合或者数组中元素的类型 //2,str仅仅是一个变量名而已,在循环的过程中,依次表示集合或者数组中的每一个元素 //3,list就是要遍历的集合或者数组 for(String str : list){ System.out.println(str); } } }
-
细节点注意:
1.报错NoSuchElementException
2.迭代器遍历完毕,指针不会复位
3.循环中只能用一次next方法
4.迭代器遍历时,不能用集合的方法进行增加或者删除
public class A04_CollectionDemo4 {
public static void main(String[] args) {
/*
迭代器的细节注意点:
1.报错NoSuchElementException
2.迭代器遍历完毕,指针不会复位
3.循环中只能用一次next方法
4.迭代器遍历时,不能用集合的方法进行增加或者删除
暂时当做一个结论先行记忆,在今天我们会讲解源码详细的再来分析。
如果我实在要删除:那么可以用迭代器提供的remove方法进行删除。
如果我要添加,暂时没有办法。(只是暂时)
*/
//1.创建集合并添加元素
Collection<String> coll = new ArrayList<>();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
coll.add("ddd");
//2.获取迭代器对象
//迭代器就好比是一个箭头,默认指向集合的0索引处
Iterator<String> it = coll.iterator();
//3.利用循环不断的去获取集合中的每一个元素
while(it.hasNext()){
//4.next方法的两件事情:获取元素并移动指针
String str = it.next();
System.out.println(str);
}
//当上面循环结束之后,迭代器的指针已经指向了最后没有元素的位置
//System.out.println(it.next());//NoSuchElementException
//迭代器遍历完毕,指针不会复位
System.out.println(it.hasNext());
//如果我们要继续第二次遍历集合,只能再次获取一个新的迭代器对象
Iterator<String> it2 = coll.iterator();
while(it2.hasNext()){
String str = it2.next();
System.out.println(str);
}
}
}
3.3.3 lambda表达式
利用forEach方法,再结合lambda表达式的方式进行遍历
public class A07_CollectionDemo7 {
public static void main(String[] args) {
/*
lambda表达式遍历:
default void forEach(Consumer<? super T> action):
*/
//1.创建集合并添加元素
Collection<String> coll = new ArrayList<>();
coll.add("zhangsan");
coll.add("lisi");
coll.add("wangwu");
//2.利用匿名内部类的形式
//底层原理:
//其实也会自己遍历集合,依次得到每一个元素
//把得到的每一个元素,传递给下面的accept方法
//s依次表示集合中的每一个数据
/* coll.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});*/
//lambda表达式
coll.forEach(s -> System.out.println(s));
}
}