文章目录
- JDK8新特性:Lambda表达式
- 认识Lambda表达式
- Lambda表达式的省略规则
- JDK8新特性:方法引用
- 静态方法的引用
- 实例方法的引用
- 特定类型方法的引用
- 构造器的应用
- 集合
- ➡️Collection单列集合体系
- Collection的常用方法
- Collection的遍历方法
- 迭代器
- 增强for循环
- lambda表达式
- 案例
- List集合
- List特点、特有方法
- List的遍历方式
- ArrayList集合的底层原理
- ArrayList集合的底层原理
- ArrayList集合适合的应用场景
- LinkedList集合的底层原理
- LinkedList集合的底层原理
- **LinkedList**新增特有方法
- **LinkedList**集合适合的应用场景
- 场景一:可以用来设计队列
- 场景二:可以用来设计栈
- Set集合
- Set集合的特点
- HashSet集合的底层逻辑
- 前导知识
- 哈希值
- 对象哈希值的特点
- 哈希表
- 数据结构(树)
- HashSet集合底层原理
- HashSet集合去重复的机制
- LinkedHashSet集合的底层逻辑
- TreeSet集合
- ✅总结(场景选择)
- 注意事项:集合的并发修改异常问题
- Collection的其他相关知识
- 可变参数
- Collections工具类
- 综合案例
- ➡️Map集合
- 概述
- 常用方法
- 遍历方法
- 方法1:键找值
- 方法2:键值对
- 方法3:Lambda
- 案例 Map集合-统计投票人数
- HashMap
- HashMap底层原理
- LinkedHashMap
- LinkedHashMap底层原理
- TreeMap
- 补充知识:集合的嵌套
- Stream流
- 认识Stream
- Stream流的使用步骤
- Stream的常用方法
- 1、获取Stream流
- 2、Stream流常见的中间方法
- 3、Stream流常见的终结方法
JDK8新特性:Lambda表达式
认识Lambda表达式
-
Lambda表达式是DK8开始新增的一种语法形式,作用:用于简化匿名内部类的代码写法。
-
格式:
-
注意:Lambda表达式并不能简化全部匿名内部类的写法,只能简化函数式接口(有且只有一个抽象方法的接口)的匿名内部类。
package lambda;
public class LambdaTest1 {
public static void main(String[] args) {
Swimming s = new Swimming() {
@Override
public void swim() {
System.out.println("学生游泳");
}
};
s.swim();
}
}
interface Swimming{
void swim();
}
简化后:
package lambda;
public class LambdaTest1 {
public static void main(String[] args) {
// Swimming s = new Swimming() {
// @Override
// public void swim() {
// System.out.println("学生游泳");
// }
// };
// s.swim();
//简化后:
Swimming s = () -> {
System.out.println("学生游泳");
};
s.swim();
}
}
interface Swimming{
void swim();
}
- 将来我们见到的大部分函数式接口,上面都可能会有一个@FunctionalInterface的注解,有该注解的接口就必定是函数式接口。
Lambda表达式的省略规则
Lambda表达式的省略写法(进一步简化Lambda表达式的写法)
- 参数类型可以省略不写。
- 如果只有一个参数,参数类型可以省略,同时()也可以省略。
- 如果Lambda表达式中的方法体代码只有一行代码,可以省略大括号不写,同时要省略分号!此时,如果这行代码是return语句,也必须去掉return不写。
Arrays.setAll(prices, (int value) ->{
return prices[value] * 0.8;
});
//可以简化为:
Arrays.setAll(prices, (value) ->{
return prices[value] * 0.8;
});
//接着简化:
Arrays.setAll(prices, value ->{
return prices[value] * 0.8;
});
//接着简化:
Arrays.setAll(prices, value -> prices[value] * 0.8);
再或者:
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2){
return Double.compare(o1.getHeight)
}
});
//可以简化为:
Arrays.sort(students, (Student o1, Student o2) -> {
return Double.compare(o1.getHeight(), o2.getHeight()); //升序
});
//接着简化:
Arrays.sort(students, (o1, o2) -> {
return Double.compare(o1.getHeight(), o2.getHeight()); //升序
});
//接着简化:
Arrays.sort(students, (o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight()) );
用来简化函数式接口的匿名内部类
JDK8新特性:方法引用
用于进一步简化Lambda表达式的
方法引用的标志性符号 “ :: ”
静态方法的引用
- 类名 :: 静态方法
- 使用场景:如果某个Lambda表达式里只是调用一个静态方法,并且前后参数的形式一致,就可以使用静态方法引用
实例方法的引用
-
对象名 :: 实例方法
-
使用场景:如果某个Lambda表达式里只是调用一个实例方法,并且前后参数的形式一致,就可以使用实例方法引用
特定类型方法的引用
-
类型 :: 方法
-
使用场景:如果某个Lambda表达式里只是调用一个实例方法,并且前面参数列表中的第一个参数是作为方法的主调,后面的所有参数都是作为该实例方法入参的,则此时就可以使用特定类型的方法引用。
构造器的应用
- 类名 :: new
- 使用场景:如果某个Lambda表达式里只是在创建对象,并且前后参数的情况一致,就可以使用构造器引用
集合
集合是一种容器,用来装数据的,类似于数组,但集合的大小可变,开发中也非常常用
- 集合的体系结构
集合分为:Collection单列集合,Map双列集合
➡️Collection单列集合体系
Collection集合特点:
- List系列集合:添加的元素是有序(取时的顺序和拿时的顺序是一致的)、可重复(可以往集合中加一模一样的数据)、有索引。
- ArrayList:有序、可重复、有索引
- LinkedList:有序、可重复、有索引
- Set系列集合:添加的元素是无序、不重复、无索引。
- HashSet:无序、不重复、无索引
- LinkedHashSet:有序、不重复、无索引
- TreeSet:按照大小默认升序排序、不重复、无索引
package collection;
import java.util.ArrayList;
import java.util.HashSet;
public class CollectionTest1 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>(); //List:有序 可重复 有索引
list.add("java1");
list.add("java2");
list.add("java3");
list.add("java4");
list.add("java5");
System.out.println(list);
HashSet<String> set = new HashSet<>(); //Set: 无序 无重复 无索引
set.add("java1");
set.add("java2");
set.add("java3");
set.add("java2");
set.add("java1");
System.out.println(set);
}
}
//Out:
[java1, java2, java3, java4, java5]
[java3, java2, java1]
集合的存储对象存的并不是元素本身,而是元素的地址,通过元素地址到栈里面获取元素
Collection的常用方法
Collection是单列集合的祖宗,它规定的方法(功能)是全部单列集合都会继承的。
- Collection的常见方法:(单列集合都能用)
package collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class CollectionTest2API {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
//1.public boolean add(E e):添加元素,添加成功返回true。
c.add("java1");
c.add("java1");
c.add("java2");
c.add("java2");
c.add("java3");
System.out.println(c);
//2.public void clear():清空集合的元素。
// c.clear();
// System.out.println(c);
//3.public boolean isEmpty():判断集合是否为空是空返回true,反之。
System.out.println(c.isEmpty());
//4.public int size():获取集合的大小。
System.out.println(c.size());
//5.public boolean contains(object obj):判断集合中是否包含某个元素。
System.out.println(c.contains("java3"));
System.out.println(c.contains("Java3")); //精确匹配,所以是false
//6.public boolean remove(E e):删除某个元素:如果有多个重复元素默认删除前面的第一个!
System.out.println(c.remove("java1")); //true
System.out.println(c);
//7.public Object[] toArray():把集合转换成数组
Object[] arr = c.toArray();
System.out.println(Arrays.toString(arr));
String[] arr2 = c.toArray(new String[c.size()]); //指定一个String类型的数组
System.out.println(Arrays.toString(arr2));
System.out.println("==============================");
//把一个集合里的全部数据倒入到另一个集合中去
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);
System.out.println(c2); //不空,相当于拷贝
}
}
//Out:
[java1, java1, java2, java2, java3]
false
5
true
false
true
[java1, java2, java2, java3]
[java1, java2, java2, java3]
[java1, java2, java2, java3]
==============================
[java1, java2, java3, java4]
[java3, java4]
Collection的遍历方法
迭代器
迭代器是用来遍历集合的专用方式(数组没有选代器),在java中选代器的代表是Iterator。
- Collection集合获取迭代器的方法
- Iterator迭代器中的常用方法
package collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo1 {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("aaa");
c.add("sss");
c.add("ddd");
c.add("fff");
System.out.println(c);
// c = [aaa,sss,ddd,fff]
// it it的位置,it会把数据取出来,然后往后移动一位
//使用迭代器遍历集合
//1、从集合对象中获取迭代器对象
Iterator<String> it = c.iterator();
// System.out.println(it.next());
// System.out.println(it.next());
// System.out.println(it.next());
// System.out.println(it.next());
// System.out.println(it.next()); //出现异常:NoSuchElementException
//2、我们应该使用循环结合迭代器遍历集合
while (it.hasNext()){
String ele = it.next();
System.out.println(ele);
}
}
}
//Out:
[aaa, sss, ddd, fff]
aaa
sss
ddd
fff
增强for循环
- 增强for可以用来遍历集合或者数组。
- 增强for遍历集合,本质就是迭代器遍历集合的简化写法。
package collection;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo2 {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("aaa");
c.add("sss");
c.add("ddd");
c.add("fff");
System.out.println(c);
// c = [aaa,sss,ddd,fff]
// ele ele类似游标
//使用增强for遍历集合或者数组
//快捷键:c.for 然后回车,改变量名就行
for (String ele : c){
System.out.println(ele);
}
String[] names = {"11","22","33"};
for (String name : names){
System.out.println(name);
}
}
}
//Out:
[aaa, sss, ddd, fff]
aaa
sss
ddd
fff
11
22
33
lambda表达式
- Lambda表达式遍历集合:
得益于JDK8开始的新技术Lambda表达式,提供了一种更简单、更直接的方式来遍历集合。
- 需要使用Collection的如下方法来完成
package collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class CollectionDemo3 {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("aaa");
c.add("sss");
c.add("ddd");
c.add("fff");
System.out.println(c);
// c = [aaa,sss,ddd,fff]
// s
c.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
}
}
//Out:
[aaa, sss, ddd, fff]
aaa
sss
ddd
fff
可以用Lambda进行简化: