学习目标
- Lambda表达式
- 函数式思想
- 函数式接口
- Lambda表达式的使用前提
- Lambda表达式的操作案例
- Stream流
- Stream流的优势
- Stream流-获取功能
- Stream流-中间功能
- Stream流-终结功能
多线程入门
前提:
- 必须有一个函数式接口
- 接口中有且只有一个抽象方法
- 格式:
- (形式参数)->{代码块}
- 函数式接口
- 标志性注解@FunctionalInterface
1.3 Lambda代码实现(有参有返回值)
public class LambdaTest4 {
public static void main(String[] args) {
//Lambda表达式,参数与接口匹配
useCalculator((int a,int b) -> {return a+b;});
}
//useCalculator方法,实现接口
public static void useCalculator(Calculator calculator){
int i = calculator.calc(10, 20);
System.out.println(i);
}
}
//定义一个函数式接口
@FunctionalInterface
interface Calculator{
//抽象方法
public abstract int calc(int a,int b);
}
1.4 Lambda表达式和匿名内部类的区别
| | Lambda表达式 | 匿名内部类 | | —- | —- | —- | | 所需类型 | 只能是函数式接口 | 接口,抽象类,具体类 | | 使用限制 | 只作用在有且仅有一个抽象方法需要重写 | 一个或多个抽象方法需要重写 | | 实现原理 | 编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成 | 编译之后,产生一个单独的.class字节码文件 |
- 标志性注解@FunctionalInterface
2. Stream流
2.1 Stream流存在的优势 , 什么时候使用Stream流 ?
对集合,数组当中的元素做筛选和过滤使用。更加方便,更加简洁。
2.2 Stream流获取方法
//获取单列集合
ArrayList<String> list = new ArrayList<>();
list.stream().forEach(s -> System.out.println(s));
//获取双列集合(双列集合的键和值需要分开获取)
HashMap<String, String> map = new HashMap<>();
map.keySet().stream().forEach(s -> System.out.println(s));
map.entrySet().stream().forEach(s -> System.out.println(s));
//获取数组
int[] arr={1, 2, 3, 4, 5, 6};
Arrays.stream(arr).forEach(s -> System.out.println(s));
2.3 Stream流中间方法
//filter用于对流中的数据进行过滤
list.stream().filter(s -> s.length()==2).forEach(s -> System.out.println(s));
//limit截取指定参数个数的数据
list.stream().limit(3).forEach(s -> System.out.println(s));
//skip跳过指定参数个数的数据
//distinct()去除流中重复的元素。依赖(hashCode和equals方法)
//concat(Stream a, Stream b)合并a和b两个流为一个流
//Stream.concat(list1.stream(),list2.stream()).forEach(s -> System.out.println(s));
//sorted()将流中元素按照自然排序的规则排序
//Stream<T> sorted (Comparator<? super T> comparator) : 将流中元素按照自定义比较器规则排序
list.stream().sorted(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length()-o2.length();
}
}).forEach(s -> System.out.println(s));
2.4 Stream流终结方法
//1.long count():返回此流中的元素数
long count = list.stream().count();
//2.void forEach(Consumer action):对此流的每个元素执行操作
Consumer接口中的方法 void accept(T t):对给定的参数执行此操作
list.stream().forEach( (String s) -> {
System.out.println(s);
});
2.5 Stream流的获取功能
public class StreamDemo6 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
//Stream流的收集方法
//R collect(Collector collector) : 此方法只负责收集流中的数据 , 创建集合添加数据动作需要依赖于参数
//public static <T> Collector toList():把元素收集到List集合中
List<Integer> l = list.stream().limit(3).collect(Collectors.toList());
System.out.println(l);
//public static <T> Collector toSet():把元素收集到Set集合中
Set<Integer> set = list.stream().filter(num -> num % 2 == 0).collect(Collectors.toSet());
System.out.println(set);
//public static Collector toMap(Function keyMapper,Function valueMapper):把元素收集到Map集合中
ArrayList<String> list2 = new ArrayList<>();
list2.add("zhangsan,23");
list2.add("lisi,24");
list2.add("wangwu,25");
Map<String, String> map = list2.stream().filter(s -> Integer.parseInt(s.split(",")[1]) > 23).collect(Collectors.toMap((String s) -> {
return s.split(",")[0];
},
(String s) -> {
return s.split(",")[1];
}));
System.out.println(map);
}
}
3. 多线程实现的方式
3.1 多线程实现方式区别 ?
3.1.1 继承Thread类
public class MyThread01 {
public static void main(String[] args) {
//创建线程对象,调用线程的start方法开启线程
MyThread th = new MyThread();
th.start();
for (int i = 0; i < 1000; i++) {
System.out.println(i);
}
}
}
//创建一个类继承Thread类
class MyThread extends Thread{
//在类中重写run方法(线程执行的任务放在这里)
@Override
public void run(){
for (int i = 0; i < 1000; i++) {
System.out.println(getName()+".."+i);
}
}
}
3.1.2 实现Runnable接口
public class MyThread02 {
public static void main(String[] args) {
//创建任务对象
MyRunnable myRunnable = new MyRunnable();
//使用含有Runnable参数的构造方法,创建线程对象并指定任务
Thread thread = new Thread(myRunnable);
//调用线程的start方法,开启线程
thread.start();
for (int i = 0; i < 1000; i++) {
System.out.println(i);
}
}
}
//定义任务类实现Runnable
class MyRunnable implements Runnable{
//重写run方法
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
3.1.3 Thread类中常用方法
- String getName():返回此线程的名称
- void setName(String name):将此线程的名称更改为等于参数 name
- public static Thread currentThread() :返回对当前正在执行的线程对象的引用
- public static void sleep(long time):让线程休眠指定的时间,单位为毫秒。
public void join() : 具备阻塞作用 , 等待这个线程死亡,才会执行其他线程
4. Optional类API
public static
Optional of(T value) : 通过非null值构建一个Optional容器,注意value不能不为null否则抛出异常 - public static
Optional ofNullable(T value) : 通过指定值构建一个Optional容器,如果值为null则返回Optional.empty - public T orElse(T other) : 返回值如果存在,否则返回 other 。
- public boolean isPresent() : 如果对象为null返回的是false , 如果对象不为null返回的是true
- public T get() : 如果 Optional中存在值,则返回值,否则抛出 NoSuchElementException