目录
二.String流:可以lambda表达式简化集合与数组的操作
一.不可变集合:这个集合一旦创建之后无法被修改,只能查询
1.如何创建不可变的List类型的集合?创建的集合是什么类型的? 2.如何创建Set类型的不可变集合? 3.如何创建不可变的Map类型的集合?传入的参数有限制吗? 4.当Map中的键值对元素大于10个时,应该如何创建不可变集合呢(具体步骤)? 5.简化的不可变Map方法?
public class Demo261 {
public static void main(String[] args) {
System.out.println("1.使用List中的of方法创建不可变集合,这里是list,set,map接口");
List<String> list = List.of("zhang", "li", "wang", "zhao");
System.out.println(list);
System.out.println("2.使用Set中的of方法创建不可变集合,set中内容不能重复,否则报错");
Set<String> set = Set.of("zhang", "li", "wang", "zhao");
System.out.println(set);
System.out.println("3.使用Map中的of方法创建不可变集合,键不能重复,且传递有上限,最多只能传10个键值对对象");
Map<String, Integer> map = Map.of("张三", 23, "李四", 24);
System.out.println(map);
System.out.println("4.如果键值对对象大于10个,就需要先创建一个可变的Map存储数据,再使用ofEntries方法来传入不可变参数");
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("zhangsan", 23);
hashMap.put("lisi", 24);
System.out.println("(1)entrySet对象返回一个Set集合");
Set<Map.Entry<String, Integer>> entries = hashMap.entrySet();
System.out.println("(2)使用entries的toArray方法转换成字符串,传入的IntFunction对象,指定返回数组的对象,不指定默认返回Object类型");
Map.Entry[] array = entries.toArray(value->new Map.Entry[value]);
System.out.println("(3)可变参数底层就是数组,故需要把set集合转变为数组");
map = Map.ofEntries(array);
System.out.println("(4)链式编程写法(这里传入长度0.Java底层自动扩容)");
map = Map.ofEntries(hashMap.entrySet().toArray(new Map.Entry[0]));
System.out.println("5.使用Map.copyOf方法创建不可变集合,极简写方法(JDK10版本出现)");
map = Map.copyOf(hashMap);
System.out.println(map);
}
}
二.String流:可以lambda表达式简化集合与数组的操作
1.如何获取数组的stream流? 2.单列集合如何获取steam流? 3.双列集合如何获取键的stream流与entrySet的stream流? 4.不定量的数据如何获取Stream流? 5.再获取数组的stream流时,如果数组中的数据是基本数据类型,获取的stream流是什么?
public class Demo262 {
public static void main(String[] args) {
Collection<String> col = new ArrayList<>();
String[] str = {"张xx", "王i", "张y", "张zz", "赵m"};
Collections.addAll(col, str);
System.out.println("1.使用数组帮助类的stream方法,获取数组的Stream流,这里遍历依然是使用的Consumer");
Arrays.stream(str)
.filter(name -> name.startsWith("张"))
.filter(name -> name.length() == 3)
.forEach(System.out::println);
System.out.println("2.使用对象的stream方法获取单列集合的stream流");
col.stream();
System.out.println("3.先获取双列集合Key对象与Entry对象,再使用stream方法获取Map对象的stream流");
HashMap<String, Integer> hm = new HashMap<>();
hm.put("zhang", 23);
hm.put("li", 24);
hm.keySet().stream().forEach(System.out::println);
hm.entrySet().stream().map(Map.Entry::getValue).forEach(System.out::println);
System.out.println("4.使用Stream流的of方法获取不定量的数据的Stream流,需要保证数据类型相同,本质上也是传数组。");
Stream.of(1, 2, 3).forEach(System.out::println);
System.out.println("5.注意传基本数据类型的数组的时候出问题,会把整个数组当成一个元素");
int[] arr = {1, 2, 3};
Stream.of(arr).forEach(System.out::println);
}
}
三.Stream流中间方法
1.由这种方法产生的stream流对使用有什么限制? 2.过滤数据使用什么方法?这个方法里面的接口中返回的数据代表什么意思? 3.如何留下stream流的前几个数据与跳过前几个数据? 4.如何去除元素?根据什么方法去除元素呢(如自定义对象) 5.何合并两个流?
public class Demo263 {
public static void main(String[] args) {
System.out.println("1.使用stream流中间方法产生的stream流只能使用一次");
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"zhangsan","lisi","wangwu","wangwu");
System.out.println("2.使用filter方法过滤数据,filter里面为predicate接口,返回数据表示当前数据留下与否");
list.stream().filter(s->s.length()==8).forEach(System.out::println);
System.out.println("3.使用limit方法与skip方法限制数据");
list.stream().limit(1).forEach(System.out::println);
list.stream().skip(1).forEach(System.out::println);
System.out.println("4.使用distinct方法元素去重,依赖hashcode和equals方法(底层用的是hashSet)");
list.stream().distinct().forEach(System.out::println);
System.out.println("5.使用contact方法合并流,尽可能使两个流的类型一致(可以多态)");
Stream.concat(list.stream(),Stream.of("1","2","3")).forEach(System.out::println);
}
}
四.转换数据流中的数据类型
1.转换数据流中的数据类型使用什么方法? 2.在这个方法里实现的接口是什么? 3.接口方法中形参是什么? 4.返回的数据是什么?
public class Demo264 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"zhangsan-23","lisi-24","wangwu-25","zhaoliu-26");
System.out.println("1.使用map方法转换数据类型");
System.out.println("2.传入Function对象,转换数据," +
"第一个参数代表原本(流里面的)的类型," +
"第二个参数代表需要变成的类型");
System.out.println("3.形参表示流里面的每一个数据");
System.out.println("4.返回的数据代表需要转换的数据的类型");
list.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s.split("-")[1]);
}
}).forEach(System.out::println);
//lambda简化
list.stream().map(s->Integer.parseInt(s.split("-")[1])).forEach(System.out::println);
}
}
五.Stream流的终结方法
1.如何统计流中的数据数量? 2.如何把流变成数组?传入的接口是什么?接口中返回的数据代表什么?
public class Demo265 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"zhangsan-23","lisi-24","wangwu-25","zhaoliu-26");
System.out.println("1.使用count方法统计流中的数量");
long l = list.stream().count();
System.out.println("2.使用toArray方法变成数组,传入的参数是IntFunction对象,和上面的Map.Entry一样,返回数据代表指定大小的数组");
String[] str = list.stream().toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
});
//简写
str = list.toArray(s->new String[s]);
System.out.println(Arrays.toString(str));
}
}
六.Stream流转换成List,Set,Map
1.使用什么去接收stream转成的List? 2.如何转换成List?方法中需要传递什么参数? 3.如何转换成Set?转换成Set数据有什么变化吗? 4.如何转换成Map?传入的接口的数量? 5.返回的参数是?
public class Demo266 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "zhangsan-男-23", "zhangsan-男-23", "lisi-女-24", "lisi-女-24");
System.out.println("1.使用List接口接收stream流转换的List对象,Set,Map皆如此");
System.out.println("2.在collect终结方法里面传递Collectors工具类,使用toList方法转换为List");
List<String> newList = list.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toList());
System.out.println("3.collect方法里面传递toSet方法转换成Set,传递toSet方法能够去重");
Set<String> newSet = list.stream().filter(s -> "女".equals(s.split("-")[1]))
.collect(Collectors.toSet());
System.out.println(newList + "" + newSet);
list = new ArrayList<>();
Collections.addAll(list, "zhangsan-男-23", "lisi-女-24");
System.out.println("4.转换成Map依然使用collect方法,要先传入Collectors工具类的toMap方法," +
"再传递两个Function对象确定返回参数,键不能够重复傲,不会像Set那样给你自动删除");
System.out.println("5.返回的参数分别代表键和值的对象");
Map<String, Integer> newMap = list.stream().collect(Collectors.toMap(
s -> s.split("-")[0],
s -> Integer.parseInt(s.split("-")[2])
));
System.out.println(newMap);
}
}
七.方法引用
把已经有的方法当作函数式接口中抽象方法的方法体 也就是说替代了接口类的对象(函数式接口) 方法形参和返回值请保持一致 mybatis-plus大量引用 1.方法引用符号为? 2.使用类名调用静态方法 类名::方法名 3.使用对象调用成员方法 对象名::方法名 如何调用父类与本类对象的方法? 4.使用类名调用构造方法 类名::new 5.使用数组调用构造方法 int[]::new 6.使用类名调用成员方法 相当于用接口中的第一个参数调用其它类中的函数
public class Demo267 {
public static void main(String[] args) {
System.out.println("1.方法引用符号为双冒号::");
System.out.println("2.使用类名调用静态方法");
//arrayList转类型
ArrayList<String> arrayList = new ArrayList<>();
Collections.addAll(arrayList, "1", "2", "3", "4");
//在格式转换里面使用ParseInt方法转换类型
arrayList.stream().map(Integer::parseInt).forEach(System.out::println);
arrayList.clear();
System.out.println("3.使用对象调用成员方法");
System.out.println("调用本类的成员方法使用this:: 父类使用super::");
Collections.addAll(arrayList,"zhangsan","lisi","wangwu");
arrayList.stream().filter(new StringJudge()::test).forEach(System.out::println);
arrayList.clear();
System.out.println("4.引用构造方法:为了创建对象,这里的学生对象额外加了一个构造方法");
System.out.println("在这里需要加一个Student里面的构造方法,使得其接收一个字符串,并转换成相应属性");
Collections.addAll(arrayList,"zhangsan,23","lisi,24","wangwu,25");
List<Student> students = arrayList.stream().
map(Student::new).
collect(Collectors.toList());
System.out.println(students);
arrayList.clear();
System.out.println("5.使用数组名调用构造方法");
ArrayList<Integer> integers = new ArrayList<>();
Collections.addAll(integers,1,2,3,4,5,6);
integers.stream().toArray(Integer[]::new);
System.out.println("6.使用类名调用成员方法");
System.out.println("在抽象方法中的第一个参数(这里是String)代表了能引用哪个类中的方法,其他类的方法用不了(限制类)");
System.out.println("第二个参数到最后的参数要和调用的成员方法中的形参一致");
System.out.println("如果抽象方法中那个没有参数,调用的成员方法就是无参方法");
System.out.println("相当于拿第一个参数去调用其他的函数");
arrayList.stream().map(String::toUpperCase).forEach(System.out::println);
}
}
class StringJudge {
public boolean test(String s){
return s.startsWith("z")&&s.length()==8;
}
}
public class Student {
private String name;
private int age;
public Student() {
}
//添加方法
public Student(String s) {
this.name = s.split(",")[0];
this.age = Integer.parseInt(s.split(",")[1]);
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return name + "-" + age;
}
}