回顾接口
可存放:
常量
抽象方法
default方法
static方法
匿名内部类:接口和抽象类对象只使用一次,就可以使用匿名内部类
当使用匿名内部类创建一个函数式接口的时候,可以使用lambda来简化匿名内部类
public class ReviewLambdaDemo {
public static void main(String[] args) {
// 1、通过Runnable接口来创建线程对象
new Thread(() -> System.out.println("2023要结束了")).start();
// 2、在一个list集合里面放入5个数字,将按数字的降序排列
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,1,60,3,12,56);
TreeSet<Integer> ts = new TreeSet<>((a,b) -> b - a);
ts.addAll(list);
System.out.println(ts);
// 3、将一个指定文件夹里面所有ppt文件拿到
File file = new File("e:/pp");
File[] files = file.listFiles(f -> f.isFile() && f.getName().endsWith(".ppt"));
// 遍历数组
for (File f : files) {
System.out.println(f);
}
// 4、随机产生10个不重复的随机偶数,遍历
HashSet<Integer> set = new HashSet<>();
while (set.size() < 10) {
int num = (int)(Math.random() * 20 + 1);
if(num % 2 != 0) continue;
set.add(num);
}
set.forEach(a -> System.out.println(a));
}
}
语法结构 简化使用匿名内部类创建对象的
方法引用:简化特殊lambda
构造方法引用:类名::new
实例的方法的引用:对象名::方法名
类方法的方法引用:类名::方法名
讲解方法引用
方法引用:对特殊的lambda简化的一种语法
()-> {lambda体}
特殊的lambda:当lambda体只有1句代码,并且这句代码是在调用一个方法
java中的方法:
构造方法:new 构造方法()
实例方法:对象名.方法名()
类方法(静态方法):类名.方法名()
构造方法的方法引用的语法:类名::方法名(简化lambda调用构造方法)
public class LambdaDemo1 {
public static void main(String[] args) {
// 创建IFacotryDog对象
IFacotryDog ifd = (name,age) -> new Dog(name,age); // 创建函数接口对象
Dog d = ifd.create("小可爱", 3);
System.out.println(d);
// 上面代码中lambda,可以使用构造方法的引用来简化
// 创建IFacotryDog对象
IFacotryDog ifd2 = Dog::new; // 类名:调用构造方法的类名::new
Dog d2 = ifd2.create("老可爱", 3);
System.out.println(d2);
}
}
public class Dog {
private String name;
private Integer age;
public Dog() {
}
public Dog(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
/**
* 创建Dog对象的接口
*/
public interface IFacotryDog {
Dog create(String name,Integer age);
}
类方法引用:类名(调用方法存放的类)::方法名(要调用的方法名)
public interface IChangeStringNumber {
int change(String number);
}
/**
* 讲解类方法引用:类名(调用方法存放的类)::方法名(要调用的方法名)
*/
public class LambdaDemo2 {
public static void main(String[] args) {
// 创建函数式接口IChangeStringNumber对象
IChangeStringNumber icsn = n -> Integer.parseInt(n);
int num = icsn.change("123");
System.out.println(num);
// 上面代码中lambda是在调用一个类方法,使用类方法引用来简化:类名::方法
IChangeStringNumber icsn2 = Integer::parseInt;
icsn2.change("123");
}
}
实例方法的引用:对象::实例方法名
/**
* 设计一个函数式接口
*/
public interface IIsAvi {
boolean isAvi(String filename);
}
/**
* 讲解实例方法的引用
*/
public class LmbdaDemo3 {
public static void main(String[] args) {
// 创建IIsAvi对象
IIsAvi avi = fn -> fn.endsWith(".avi"); // 创建函数式接口的对象
boolean temp = avi.isAvi("蘋蘋在某酒店学习外语.png");
System.out.println(temp);
// lambda在调用一个实例方法,用实例方法引用来简化:对象::方法名
String f = "xxxx.txt";
IIsAvi avi2 = f::endsWith; // 实例方法的引用
boolean avi1 = avi2.isAvi(f);
System.out.println(avi1);
// 遍历集合
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
// PrintStream ps = System.out;
// list.forEach(a -> ps.println(a));
list.forEach(System.out::println);
}
}
特殊:类名.方法名()
引用类的实例方法是一种引用特定对象的实例方法。它通常用于将对象的方法作为Lambda表达式的一部分引用。
注意:仅限于对象的get()或)set()方法
stream.map(Person::getName); // 把对象转为对象的name
IO流是操作文件流
Stream操作数组或者集合的流
注意:Stream只操作数据,不保存数据
通过arrs数组创建Stream
int[] arrs = {1,3,5,7,9};
IntStream sm = Arrays.stream(arrs);
通过集合对象创建Stream
List list = Arrays.asList(1, 2, 3, 4, 56);
Stream sm2 = list.stream();
/**
* 讲解Stream流
* IO流是操作文件流
* Stream操作数组或者集合的流
* 注意:Stream只操作数据,不保存数据
*
*/
public class StreamDemo {
public static void main(String[] args) {
// 1、创建Stream
// 1)、通过Arrays
int[] arrs = {1,3,5,7,9};
IntStream sm = Arrays.stream(arrs);// 通过arrs数组创建Stream
// sm是Stream流对象,sm操作的数据源是arrs
// 2)、通过集合对象
List<Integer> list = Arrays.asList(1, 2, 3, 4, 56);
Stream<Integer> sm2 = list.stream(); // 创建Stream对象
// 3)、Stream里面的of方法
Stream.of(1, 2, 3, 4, 5, 6);
}
}
Stream流(重点)
把数组和集合作为操作数据源
操作流的方法
操作流方法:
filter(过滤的条件:函数式接口):将不满足条件的数据过滤掉 (Predicate:断言型的接口)
limit(long 数字):截取流里面多个数据
limit(3)
.limit(3L) // 限制流里面显示的条数
skip():跳过几条
.skip(2L) // 跳过前两条
.limit(4L) // 限制显示4条
.distinct():去除重复
.sorted():排序,进行排序数据必须实现Comparable
.sorted() // 排序(升序)
.sorted(Comparator):根据定制排序
.map():切片(给你一种类型,变为另一种类型)
结束流方法:注意:(结束流方法只能三选一)
public class StreamDemo2 {
public static void main(String[] args) {
// 1、创建流
// IntStream stream = Arrays.stream(new int[]{1,8,6,8,10,12,14,16, 2, 3, 4, 5, 8,6,8,10,12,14,16});// 调用一个方法
// List list = Arrays.asList(1, 8, 6, 8, 10, 12, 14, 16, 2, 3, 4, 5, 8, 6, 8, 10, 12, 14, 16);
// Stream stream = list.stream();
// // 2、操作流
// stream
// .filter(a -> a % 2 == 0) // Predicate:断言型的接口
// filter(a -> a >= 4)
// .distinct() // 去除重复数据
// .sorted((o1,o2) -> o2 - o1) // 降序排列
// .forEach(System.out::println); // Consumer:消费型的接口
// 将字符串里面数字降序输出,去重
String str = "12,34,67,5,90,23,4,67,8,9";
String[] split = str.split(",");
Stream<String> stream = Arrays.stream(split); // 创建流
// 将字符串变成int
long count = stream
.map(Integer::parseInt) // Function,将a由String转换int
.distinct() // 去重
.sorted((o1, o2) -> o2 - o1)
.count();// 统计流里面个数
System.out.println(count);
}
}
小结Stream流
Stream流的分类
1、串行流:单线程使用(使用最多)
2、并行流:多线程使用
1、创建流
Arrays.stream(数组)
集合对象.stream()
Stream.of(可变参数)
2、流操作的方法:
filter()
limit()
skip()
sorted()
distinct()
map()
forEach()
collect()
count();
public static void main(String[] args) {
// 创建一个串行流
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
// Stream stream = list.stream();// 创建的串行流
// stream.forEach(System.out::println);
// 并行流
Stream<Integer> integerStream = list.parallelStream();
integerStream.forEach(System.out::println);
}
}
public class StreamDemo4 {
public static void main(String[] args) {
// 1.有如下7个元素黄药师,冯蘅,郭靖,黄蓉,郭芙,郭襄,郭破虏,使用Stream将以郭字开头的元素存入新数组
// String[] names = new String[]{"黄药师", "冯蘅", "郭靖", "黄蓉", "郭芙", "郭襄", "郭破虏"};
// Stream stream = Arrays.stream(names);
// Object[] array = stream.filter(a -> a.startsWith("郭")).toArray();
// Arrays.stream(array).forEach(System.out::println);
// 2.已知ArrayList集合中有如下元素{陈玄风、梅超风、陆乘风、曲灵风、武眠风、冯默风、罗玉风},使用Stream
// ArrayList arrayList = new ArrayList<>();
// arrayList.add("陈玄风");
// arrayList.add("梅超风");
// arrayList.add("陆乘风");
// arrayList.add("曲灵风");
// arrayList.add("武眠风");
// arrayList.add("冯默风");
// arrayList.add("罗玉风");
// Stream stream1 = arrayList.stream();
//1、取出前2个元素并在控制台打印输出。
// stream1.limit(2).forEach(System.out::println);
//2、取出后2个元素并在控制台打印输出。
// stream1.skip(arrayList.size() - 2).forEach(System.out::println);
// Collections.reverse(arrayList);
// arrayList.stream().limit(2).forEach(System.out::println);
ArrayList<String> manArray = new ArrayList<>();
manArray.add("刘德华");
manArray.add("成龙");
manArray.add("吴彦祖");
manArray.add("周润发");
manArray.add("周星驰");
manArray.add("吴京");
ArrayList<String> womanList = new ArrayList<>();
womanList.add("林心如");
womanList.add("孙俪");
womanList.add("柳岩");
womanList.add("林青霞");
womanList.add("王祖贤");
womanList.add("张曼玉");
//1、筛选出前一个姓林的女演员
// womanList.stream().filter(a -> a.startsWith("林")).limit(1).forEach(System.out::println);
//2、男演员只要名字为3个字的前三人;
// manArray.stream().filter(a -> a.length() == 3).limit(3).forEach(System.out::println);
// 3、把上述过滤后的男演员姓名和女演员姓名合并到一起
List<String> collect = manArray.stream().filter(a -> a.length() == 3).limit(3).collect(Collectors.toList());
List<String> collect1 = Stream.concat(collect.stream(), womanList.stream()).collect(Collectors.toList());
collect1.stream().forEach(System.out::println);
// 4、把上一步操作后的元素作为构造方法的参数创建演员对象,遍
}
}
测试:检查代码有没有bug
黑盒测试:不看代码结构,只看结果
白盒测试:必须要看代码
灰盒测试:能看一部分代码
**注:**上面的测试是专业人员操作的
单元测试:测试自己写方法,程序员自己测
使用main方法来做,每一个只有一个main,测试很不方便
使用单元测试来代替main
public class TestCase {
@Test // 单元测试的注解
// 单元测试的方法,不能有返回值,可以抛出Exception
public void testDemo1() throws Exception {
System.out.println("这个单元测试1");
}
@Test
public void testDemo2() throws Exception {
System.out.println("这个单元测试2");
}
@Test
public void testDemo3() throws Exception {
System.out.println("这个单元测试3");
}
// 在测试方法代码冗余(重复的代码)
@Before // 在每个测试方法执行之前要执行方法
public void before() throws Exception {
System.out.println("hello");
}
@After
public void after() throws Exception {
System.out.println("用来释放锁,关闭流");
}
}
一个类就是只有一个对象,那么就是单例
将一个类设计成单例的方式就是单例模式
怎样将一个类设计为单例
1、私有构造方法
2、在当前类创建对象
3、在该类设计一个类方法,返回这个对象
package cn.itsource.singleton;
/**
* 将Dog设计为单例:饿汉模式
*/
public class Dog {
// 2、创建对象
private static Dog d = new Dog(); // 不管这个对象用不用,在内存中存在
// 省略属性
// 1、私有化构造方法
private Dog() {}
// 3、设计一个类方法,返回创建的对象
public static Dog getInstance() {
return d;
}
}
public class SingletonDemo {
public static void main(String[] args) {
Dog d1 = Dog.getInstance();
System.out.println(d1);
Dog d2 = Dog.getInstance();
System.out.println(d2);
Dog d3 = Dog.getInstance();
System.out.println(d3);
}
}