文章目录
一、Arrays
是一个数组常用的工具类,大多是静态的方法可以直接调用
以下是常见的方法:
public static void main(String[] args) {
//该类中多数方法都是静态的,可用类名直接调用
//1.将数组变成字符串
int[] arry={1,2,3,4,5,6,7,8,9};
System.out.println(Arrays.toString(arry)); //可以直接打印
//2.二分查找法查找元素
//数组中元素是升序排列
//查找的元素存在返回索引
//查找元素不存在时,插入的数值去负号-1,并返回
System.out.println(Arrays.binarySearch(arry,5));
System.out.println(Arrays.binarySearch(arry,10));
//3.数组拷贝
//若新数组的长度大于老数组,会在后面补上默认初始化值
int[] newArry=Arrays.copyOf(arry,10);
//4.数组填充
Arrays.fill(arry,100);
System.out.println(Arrays.toString(arry));
//5.排序
//底层是快拍
int[] arry2={6,1,5,84,8,6,3,4};
Arrays.sort(arry2);
System.out.println(Arrays.toString(arry2));
//6.按照指定的规则排序
//此时只能针对引用类型的数据排序,基本类型要转为包装类
Integer[] arry3={1,5,9,8,6,3,4,7,2};
//Arrays.sort(arry3,规则); 第二个参数是一个接口,但此时只用使用一次,采取匿名内部类的形式
//比较器会根据两参数的差值运算结果来确定是否颠倒顺序
//o2-o1降序
//o1-o2升序
Arrays.sort(arry3, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
System.out.println(Arrays.toString(arry3));
}
二、Lambda表达式
2.1 Lambda表达式的简介
用于简化匿名内部类代码的书写
函数式编程思想,忽略面向对象的复杂语法,强调做什么而不是谁去做。
固定格式:
(被重写方法的形参列表) -> {
被重写方法的方法体代码;
}
注意:只能用于函数式接口(有且仅有一个抽象方法的接口),接口中可以加上@FunctionalInterface做校验
2.2 Lambda表达式的使用
public class LambdaTest2 {
public static void main(String[] args) {
double[] prices = {99.8, 128, 100};
//1.把所有元素*0.8: 先用匿名内部类写法
Arrays.setAll(prices, new IntToDoubleFunction() {
@Override
public double applyAsDouble(int value) {
// value = 0 1 2
return prices[value] * 0.8;
}
});
//2.把所有元素*0.8: 改用Lamdba表达式写法
Arrays.setAll(prices, (int value) -> {
return prices[value] * 0.8;
});
//--------------------------------------
Student[] students = new Student[4];
students[0] = new Student("蜘蛛精", 169.5, 23);
students[1] = new Student("紫霞", 163.8, 26);
students[2] = new Student("紫霞", 163.8, 26);
students[3] = new Student("至尊宝", 167.5, 24);
//3.对数组中的元素按照年龄升序排列: 先用匿名内部类写法
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return Double.compare(o1.getHeight(), o2.getHeight()); // 升序
}
});
//4.对数组中的元素按照年龄升序排列: 改用Lambda写法
Arrays.sort(students, (Student o1, Student o2) -> {
return Double.compare(o1.getHeight(), o2.getHeight()); // 升序
});
System.out.println(Arrays.toString(students));
}
}
2.3 更进一步地省略
1.Lambda的标准格式
(参数类型1 参数名1, 参数类型2 参数名2)->{
...方法体的代码...
return 返回值;
}
Arrays.sort(arry3, (Integer o1, Integer o2)-> {
return o2-o1;
}
);
2.在标准格式的基础上()中的参数类型可以直接省略
(参数名1, 参数名2)->{
...方法体的代码...
return 返回值;
}
Arrays.sort(arry3, (o1, o2)-> {
return o2-o1;
}
);
3.如果{}总的语句只有一条语句,则{}可以省略、return关键字、以及最后的“;”都可以省略
(参数名1, 参数名2)-> 结果
Arrays.sort(arry3, (o1, o2)-> o2-o1);
4.如果()里面只有一个参数,则()可以省略
(参数名)->结果
Arrays.sort(arry3, o1-> o2-o1);
三、集合的进阶
3.1集合的体系结构
主要分为两类:
- 单列集合:以Collection为主,每次添加一个数据
- 双列集合:以Map为主,每次添加一对数据
3.2 单列集合Collection
Collection是单列集合的根接口,Collection接口下面又有两个子接口List接口、Set接口,List和Set下面分别有不同的实现类,如下图所示:
其中的特点为:
注意:有序指的是存取的顺序一致,不是排序
3.3 Collection集合的常用方法
该集合的常用方法为:
Collection是一个接口,不能直接创建对象,可以用多态方式创建对象
Collection<String> c = new ArrayList<>();
//1.public boolean add(E e): 添加元素到集合
//往List集合中添加数据方法永远返回true(元素可重复)
c.add("java1");
c.add("java1");
c.add("java2");
c.add("java2");
c.add("java3");
System.out.println(c); //打印: [java1, java1, java2, java2, java3]
//2.public int size(): 获取集合的大小
System.out.println(c.size()); //5
//3.public boolean contains(Object obj): 判断集合中是否包含某个元素
System.out.println(c.contains("java1")); //true
System.out.println(c.contains("Java1")); //false
//在底层是通过equals方法实现,对于自定义对象的判断需要重写该方法
//4.pubilc boolean remove(E e): 删除某个元素,如果有多个重复元素只能删除第一个
System.out.println(c.remove("java1")); //true
System.out.println(c); //打印: [java1,java2, java2, java3]
//注意:此时定义的方法是共性的,不能通过索引删除,只能用对象
//5.public void clear(): 清空集合的元素
c.clear();
System.out.println(c); //打印:[]
//6.public boolean isEmpty(): 判断集合是否为空 是空返回true 反之返回false
System.out.println(c.isEmpty()); //true
//7.public Object[] toArray(): 把集合转换为数组
Object[] array = c.toArray();
System.out.println(Arrays.toString(array)); //[java1,java2, java2, java3]
//8.如果想把集合转换为指定类型的数组,可以使用下面的代码
String[] array1 = c.toArray(new String[c.size()]);
System.out.println(Arrays.toString(array1)); //[java1,java2, java2, java3]
//9.还可以把一个集合中的元素,添加到另一个集合中
Collection<String> c1 = new ArrayList<>();
c1.add("java1");
c1.add("java2");
Collection<String> c2 = new ArrayList<>();
c2.add("java3");
c2.add("java4");
c1.addAll(c2); //把c2集合中的全部元素,添加到c1集合中去
System.out.println(c1); //[java1, java2, java3, java4]
3.4 Collection遍历方式
我们要学习更加通用的遍历方法,旧的for遍历是通过索引进行,只能遍历List集合
3.4.1 迭代器遍历
迭代器的常用方法:
代码演示:
Collection<String> c = new ArrayList<>();
c.add("aaa");
c.add("bbb");
c.add("ccc");
c.add("ddd");
System.out.println(c); //[aaa,bbb,ccc,ddd]
//第一步:先获取迭代器对象
//解释:Iterator就是迭代器对象,用于遍历集合的工具
Iterator<String> it = c.iterator();
//该对象是针对于集合c的
//第二步:用于判断当前位置是否有元素可以获取
//解释:hasNext()方法返回true,说明有元素可以获取;反之没有
while(it.hasNext()){
//第三步:获取当前位置的元素,然后自动指向下一个元素.
String e = it.next(); //如果该位置没有元素会报NoSuchElementException的错
System.out.println(s);
}
注意:
- 迭代器遍历完指针不会复位,若果要二次遍历集合,只能获取一个新的迭代器对象
- 在上述的演示代码中,一次循环只能使用一次next方法
- 在迭代器遍历时不能用集合的方法删除或添加元素,应该用迭代器的remove方法删除
3.4.2 增强for遍历
- 增强for的底层就是迭代器,为了简化迭代器的代码书写
- 所有的单列集合和数组才能用增强for
基本格式:
Collection<String> c = new ArrayList<>();
c.add("aaa");
c.add("bbb");
c.add("ccc");
c.add("ddd");
//1.使用增强for遍历集合
for(String s: c){
System.out.println(s);
//s="eee"; 不会改变集合中的对象
}
//s是一个临时变量,保存每次从集合中抽取出来的对象
//2.再尝试使用增强for遍历数组
String[] arr = {"aaa", "bbb", "ccc"};
for(String name: arr){
System.out.println(name);
}
快速生成方式
:集合名.for
3.4.3 forEach遍历集合
其中,forEach方法的参数是一个Consumer接口,而Consumer是一个函数式接口,所以可以传递Lambda表达式,源码如下图:
可见在源码中函数的参数定义了一个Consumer类的对象并命名为action,然后用Object.requireNonNull进行参数有效性检查。检查为有效后
其中Consumer接口是一个函数式:
代码举例:
Collection<String> c = new ArrayList<>();
c.add("aaa");
c.add("bbb");
c.add("ccc");
c.add("ddd");
//调用forEach方法
//由于参数是一个Consumer接口,所以可以传递匿名内部类
c.forEach(new Consumer<String>{
@Override
public void accept(String s){
System.out.println(s);
}
});
//也可以使用lambda表达式对匿名内部类进行简化
c.forEach(s->System.out.println(s)); //[aaa,bbb,ccc,ddd ]