文章目录
- stream流
- 中间方法
- 终结方法
- 方法引用
- 引用静态方法
- 引用其他类的成员方法
- 引用构造方法
- 使用类名引用成员方法
- 引用数组的构造方法
stream流
Stream 是一个数据管道,可以用来从集合或其他数据源中获取数据
要求筛选出姓张的三个字的名字
List<String> list1 = new ArrayList<String>();
list1.add("张无忌");
list1.add("周芷若");
list1.add("赵敏");
list1.add("张强");
list1.add("张三丰");
//结合了lambda表达式
//再次强调只有函数式接口(仅有一个抽象方法的接口)才能用lambda表达式简化书写定义
//链式编程
list1.stream().filter(name->name.startsWith("张")).filter(name->name.length()==3).forEach(name->System.out.println(name));
//单列集合
List<String> list = new ArrayList<>();
Collections.addAll(list, "a", "b", "c", "d", "e", "f", "g", "h");
list.stream().forEach(s->System.out.println(s));
//双列集合
HashMap<String, Integer> map = new HashMap<>();
map.put("aaa", 111);
map.put("bbb", 2222);
map.put("ccc", 333);
map.put("ddd", 444);
map.put("eee", 555);
map.keySet().stream().forEach(s->System.out.println(s));//先获取键
//数组
int[] arr = {1,2,3,4,5};
Arrays.stream(arr).forEach(s->System.out.println(s));
//零散数据
Stream.of(1,2,3,4,5).forEach(s->System.out.println(s));
中间方法
- filter()//过滤
- limit()//获取前几个元素
- skip()//跳过前几个元素
- distinct()//元素去重
- concat()//合并两个流为一个流
- map()//转换流中的数据类型
List<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌-11", "周芷若-12", "和头-13", "萨哈-14", "撒都-15", "范德萨-16","张无忌-11");
List<String> list2 = new ArrayList<>();
Collections.addAll(list2,"a","b");//获取三个元素之后的数据
list.stream().skip(3).limit(3).forEach(System.out::println);
//去重
list.stream().distinct().forEach(System.out::println);
//合并流
Stream.concat(list.stream(), list2.stream()).forEach(System.out::println);
//只提取出年龄
list.stream().map(s->Integer.parseInt(s.split("-")[1])).forEach(System.out::println);
终结方法
- forEach()//遍历
- count()//计数
- toArray()//转为数组
- collect()//收集到集合
List<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌-11", "周芷若-12", "和头-13", "萨哈-14", "撒都-15", "范德萨-16","张无忌-11");
list.stream().forEach(System.out::println);
Long count = list.stream().count();
System.out.println(count);
String[] arr2 = list.stream().toArray(value -> new String[value]);
System.out.println(Arrays.toString(arr2));
List<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌-男-11", "周芷若-女-12", "和头-男-13", "萨哈-男-14", "撒都-男-15", "范德萨-男-16");
//收集到list集合中
List<String> collectList = list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toList());
//收集到Set集合中
list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toSet());
//收集到map集合中
list.stream().filter(s -> "男".equals(s.split("-")[1])).collect(Collectors.toMap(s->s.split("-")[0],s->Integer.parseInt(s.split("-")[2])));
方法引用
将已经存在的方法拿过来用,当做函数式接口中抽象方法的方法体
引用的原则,
- 需要是函数式接口
- 被引用方法必须存在
- 参数和返回值要对应上,
- 还有功能要对应
- 引用静态方法
- 引用成员方法
-
- 其他类对象::方法名
-
- 本类:this::方法名
-
- 父类:super::方法名
- 引用构造方法
使用类名引用成员方法
引用数组的构造方法
public class stream {public static void main(String[] args) {//倒叙排列Integer[] arr = {3,5,7,2,1,6};//匿名内部类Arrays.sort(arr, new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2-o1;}});//lambda表达式Arrays.sort(arr,(Integer o1, Integer o2) ->{return o2-o1;});//lambda表达式简化格式Arrays.sort(arr,((o1, o2) -> o2-o1));//方法引用//stream::subtraction中::为引用符Arrays.sort(arr,stream::subtraction);}//一般这种方法引用的方法是第三方已经写好的,自己懒得写了public static int subtraction(int num1, int num2) {return num2 - num1;}
}
引用静态方法
List<String> list = new ArrayList<>();
Collections.addAll(list, "1", "2", "3", "4", "5", "6");
//装换为整数类型
list.stream().map(Integer::parseInt).forEach(System.out::println);
引用其他类的成员方法
其他类对象::方法名
本类:this::方法名
父类:super::方法名
引用构造方法
//一个标准的javabean
public class Student {private String name;private int age;public Student() {}public Student(String str) {String[] split = str.split("-");this.name = split[0];this.age = Integer.parseInt(split[1]);}public Student(String name, int age) {this.name = name;this.age = age;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return age*/public int getAge() {return age;}/*** 设置* @param age*/public void setAge(int age) {this.age = age;}//要想println不显示地址值,要重写tostring方法public String toString() {return "Student{name = " + name + ", age = " + age + "}";}
}
public class stream {public static void main(String[] args) {List<String> list = new ArrayList<>();Collections.addAll(list, "张无忌-11", "周芷若-12", "和头-13", "萨哈-14", "撒都-15", "范德萨-16", "张无忌-11");list.stream().map(new Function<String,Student>(){@Overridepublic Student apply(String s) {String[] split = s.split("-");String name = split[0];int age = Integer.parseInt(split[1]);return new Student(name,age);}}).forEach(System.out::println);//引用构造方法list.stream().map(Student::new).forEach(System.out::println);}}
使用类名引用成员方法
类名引用的特殊之处是
调用者的抽象方法的第二个形参之后应该与被引用的方法的一致
调用者的抽象方法的第一个形参是流中数据的类型
List<String> list = new ArrayList<>();
Collections.addAll(list, "a", "b", "c", "d", "e");
//拿着流里面的每一个数据,去调用string类中的toupperCase方法,方法的返回值就是转换之后的结果
list.stream().map(String::toUpperCase).forEach(System.out::println);
引用数组的构造方法
List<Integer> list = new ArrayList<>();
Collections.addAll(list, 1, 2, 3, 4, 5);Integer[] array = list.stream().toArray(Integer[]::new);
Arrays.stream(array).forEach(System.out::println);