网站标题关键词怎么做,力洋网站建设公司,国外公司建站系统,阿里云做网站送服务器1.Stream流
1.1体验Stream流【理解】 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合#xff0c;存储多个字符串元素把集合中所有以张开头的元素存储到一个新的集合把张开头的集合中的长度为3的元素存储到一个新的集合遍历上一步得到的集…1.Stream流
1.1体验Stream流【理解】 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合存储多个字符串元素把集合中所有以张开头的元素存储到一个新的集合把张开头的集合中的长度为3的元素存储到一个新的集合遍历上一步得到的集合 原始方式示例代码 public class MyStream1 {public static void main(String[] args) {//集合的批量添加ArrayListString list1 new ArrayList(List.of(张三丰,张无忌,张翠山,王二麻子,张良,谢广坤));//遍历list1把以张开头的元素添加到list2中。ArrayListString list2 new ArrayList();for (String s : list1) {if(s.startsWith(张)){list2.add(s);}}//遍历list2集合把其中长度为3的元素再添加到list3中。ArrayListString list3 new ArrayList();for (String s : list2) {if(s.length() 3){list3.add(s);}}for (String s : list3) {System.out.println(s);} }
}使用Stream流示例代码 public class StreamDemo {public static void main(String[] args) {//集合的批量添加ArrayListString list1 new ArrayList(List.of(张三丰,张无忌,张翠山,王二麻子,张良,谢广坤));//Stream流list.stream().filter(name - name.startsWith(张)).filter(name - name.length() 3).forEach(name - System.out.println(name));}
}Stream流的好处 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义获取流、过滤姓张、过滤长度为3、逐一打印Stream流把真正的函数式编程风格引入到Java中代码简洁
1.2Stream流的常见生成方式【应用】 Stream流的思想 Stream流的三类方法 获取Stream流 创建一条流水线,并把数据放到流水线上准备进行操作 中间方法 流水线上的操作一次操作完毕之后,还可以继续进行其他操作 终结方法 一个Stream流只能有一个终结方法是流水线上的最后一个操作 生成Stream流的方式 Collection体系集合 使用默认方法stream()生成流 default StreamE stream() Map体系集合 把Map转成Set集合间接的生成流 数组 通过Arrays中的静态方法stream生成流 同种数据类型的多个数据 通过Stream接口的静态方法of(T... values)生成流 代码演示 public class StreamDemo {public static void main(String[] args) {//Collection体系的集合可以使用默认方法stream()生成流ListString list new ArrayListString();StreamString listStream list.stream();SetString set new HashSetString();StreamString setStream set.stream();//Map体系的集合间接的生成流MapString,Integer map new HashMapString, Integer();StreamString keyStream map.keySet().stream();StreamInteger valueStream map.values().stream();StreamMap.EntryString, Integer entryStream map.entrySet().stream();//数组可以通过Arrays中的静态方法stream生成流String[] strArray {hello,world,java};StreamString strArrayStream Arrays.stream(strArray);//同种数据类型的多个数据可以通过Stream接口的静态方法of(T... values)生成流StreamString strArrayStream2 Stream.of(hello, world, java);StreamInteger intStream Stream.of(10, 20, 30);}
}1.3Stream流中间操作方法【应用】 概念 中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作 常见方法 方法名说明Stream filter(Predicate predicate)用于对流中的数据进行过滤Stream limit(long maxSize)获取前几个元素Stream skip(long n)跳过前几个元素static Stream concat(Stream a, Stream b)合并a和b两个流为一个流Stream distinct()元素去重,依赖(hashCode和equals方法)Stream map(FunctionT,R mapper)转换流中的数据类型 filter代码演示 public class MyStream3 {public static void main(String[] args) {
// StreamT filter(Predicate predicate)过滤
// Predicate接口中的方法 boolean test(T t)对给定的参数进行判断返回一个布尔值ArrayListString list new ArrayList();list.add(张三丰);list.add(张无忌);list.add(张翠山);list.add(王二麻子);list.add(张良);list.add(谢广坤);//filter方法获取流中的 每一个数据.//而test方法中的s,就依次表示流中的每一个数据.//我们只要在test方法中对s进行判断就可以了.//如果判断的结果为true,则当前的数据留下//如果判断的结果为false,则当前数据就不要.list.stream().filter(new PredicateString() {Overridepublic boolean test(String s) {boolean result s.startsWith(张);return result;}}).forEach(s- System.out.println(s));//因为Predicate接口中只有一个抽象方法test所以我们可以使用lambda表达式来简化list.stream().filter(s -s.startsWith(张)).forEach(s- System.out.println(s));}
}limitskip代码演示 public class StreamDemo02 {public static void main(String[] args) {//创建一个集合存储多个字符串元素ArrayListString list new ArrayListString();list.add(林青霞);list.add(张曼玉);list.add(王祖贤);list.add(柳岩);list.add(张敏);list.add(张无忌);//需求1取前3个数据在控制台输出list.stream().limit(3).forEach(s- System.out.println(s));System.out.println(--------);//需求2跳过3个元素把剩下的元素在控制台输出list.stream().skip(3).forEach(s- System.out.println(s));System.out.println(--------);//需求3跳过2个元素把剩下的元素中前2个在控制台输出list.stream().skip(2).limit(2).forEach(s- System.out.println(s));}
}concatdistinct代码演示 public class StreamDemo03 {public static void main(String[] args) {//创建一个集合存储多个字符串元素ArrayListString list new ArrayListString();list.add(林青霞);list.add(张曼玉);list.add(王祖贤);list.add(柳岩);list.add(张敏);list.add(张无忌);//需求1取前4个数据组成一个流StreamString s1 list.stream().limit(4);//需求2跳过2个数据组成一个流StreamString s2 list.stream().skip(2);//需求3合并需求1和需求2得到的流并把结果在控制台输出Stream.concat(s1,s2).forEach(s- System.out.println(s));//需求4合并需求1和需求2得到的流并把结果在控制台输出要求字符串元素不能重复Stream.concat(s1,s2).distinct().forEach(s- System.out.println(s));}
}map代码演示 public class OptionalDemo {public static void main(String[] args) {ListString list new ArrayList();Collections.addAll(list, 张无忌-15, 周芷若-14, 张强-20, 张三丰-100, 张翠山-40, 张良-35, 王二麻子-37, 谢广坤-41);// 只获取集合中的年龄并进行打印 string-int//第一个类型:流中原本的数据类型,这里是指String//第二个类型:要转成的类型,这里是指int//apply的形参s:一次代表流里面的每一个数据//返回值:表示转换之后的数据list.stream().map(new FunctionString, Integer() {Overridepublic Integer apply(String s) {String[] arr s.split(-);String ageString arr[1];int age Integer.parseInt(ageString);return age;}}).forEach(s - System.out.println(s));// Lambda表达式简写list.stream().map(s - Integer.parseInt(s.split(-)[1])).forEach(s - System.out.println(s));}
}1.4Stream流终结操作方法【应用】 概念 终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作 常见方法 方法名说明void forEach(Consumer action)对此流的每个元素执行操作long count()返回此流中的元素数 代码演示 public class MyStream5 {public static void main(String[] args) {ArrayListString list new ArrayList();list.add(张三丰);list.add(张无忌);list.add(张翠山);list.add(王二麻子);list.add(张良);list.add(谢广坤);method1(list);// long count()返回此流中的元素数long count list.stream().count();System.out.println(count);}private static void method1(ArrayListString list) {// void forEach(Consumer action)对此流的每个元素执行操作// Consumer接口中的方法void accept(T t)对给定的参数执行此操作//s就依次表示了流中的每一个数据.//所以,我们只要在accept方法中,写上处理的业务逻辑就可以了.list.stream().forEach(new ConsumerString() {Overridepublic void accept(String s) {System.out.println(s);}});System.out.println();//lambda表达式的简化格式list.stream().forEach(s-System.out.println(s));}
}1.5Stream流的收集操作【应用】 概念 对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中 常用方法 方法名说明R collect(Collector collector)把结果收集到集合中 工具类Collectors提供了具体的收集方式 方法名说明public static Collector toList()把元素收集到List集合中public static Collector toSet()把元素收集到Set集合中public static Collector toMap(Function keyMapper,Function valueMapper)把元素收集到Map集合中 代码演示 // toList和toSet方法演示
public class MyStream7 {public static void main(String[] args) {ArrayListInteger list1 new ArrayList();for (int i 1; i 10; i) {list1.add(i);}list1.add(10);list1.add(10);list1.add(10);list1.add(10);list1.add(10);//filter负责过滤数据的.//collect负责收集数据.//Collectors.toList() : 在底层会创建一个List集合.并把所有的数据添加到List集合中.ListInteger list list1.stream().filter(number - number % 2 0).collect(Collectors.toList());System.out.println(list);SetInteger set list1.stream().filter(number - number % 2 0).collect(Collectors.toSet());System.out.println(set);
}
}
/**
Stream流的收集方法 toMap方法演示
创建一个ArrayList集合并添加以下字符串。字符串中前面是姓名后面是年龄
zhangsan,23
lisi,24
wangwu,25
保留年龄大于等于24岁的人并将结果收集到Map集合中姓名为键年龄为值
*/
public class MyStream8 {public static void main(String[] args) {ArrayListString list new ArrayList();list.add(zhangsan,23);list.add(lisi,24);list.add(wangwu,25);MapString, Integer map list.stream().filter(s - {String[] split s.split(,);int age Integer.parseInt(split[1]);return age 24;}//collect方法只能获取到流中剩余的每一个数据.//Collectors.toMap 创建一个map集合并将数据添加到集合当中//s 依次表示流中的每一个数据//第一个lambda表达式就是如何获取到Map中的键//第二个lambda表达式就是如何获取Map中的值).collect(Collectors.toMap(s - s.split(,)[0],s - Integer.parseInt(s.split(,)[1]) ));System.out.println(map);}
}1.6Stream流综合练习【应用】 案例需求 现在有两个ArrayList集合分别存储6名男演员名称和6名女演员名称要求完成如下的操作 男演员只要名字为3个字的前三人女演员只要姓林的并且不要第一个把过滤后的男演员姓名和女演员姓名合并到一起把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据 演员类Actor已经提供里面有一个成员变量一个带参构造方法以及成员变量对应的get/set方法 代码实现 演员类 public class Actor {private String name;public Actor(String name) {this.name name;}public String getName() {return name;}public void setName(String name) {this.name name;}
}测试类 public class StreamTest{public static void main(String[] args) {//创建集合ArrayListString manList new ArrayListString();Collections.addAll(manList,周润发,成龙,刘德华,吴京,周星驰,李连杰);ArrayListString womanList new ArrayListString();Collections.addAll(womanList,林心如,张曼玉,林青霞,柳岩,林志玲,王祖贤);//男演员只要名字为3个字的前三人StreamString manStream manList.stream().filter(name - name.length() 3).limit(3);//女演员只要姓林的并且不要第一个StreamString womanStream womanList.stream().filter(name - name.startsWith(林)).skip(1);//把过滤后的男演员姓名和女演员姓名合并到一起StreamString stream Stream.concat(manStream, womanStream);// 将流中的数据封装成Actor对象之后打印stream.forEach(name - {Actor actor new Actor(name);System.out.println(actor);});}}2.方法引用
2.1体验方法引用【理解】 方法引用的出现原因 在使用Lambda表达式的时候我们实际上传递进去的代码就是一种解决方案拿参数做操作.那么考虑一种情况如果我们在Lambda中所指定的操作方案已经有地方存在相同方案那是否还有必要再写重复逻辑呢答案肯定是没有必要.那我们又是如何使用已经存在的方案的呢这就是我们要讲解的方法引用我们是通过方法引用来使用已经存在的方案 代码演示 public interface Printable {void printString(String s);
}public class PrintableDemo {public static void main(String[] args) {//在主方法中调用usePrintable方法usePrintable((String s) - {System.out.println(s);});//Lambda简化写法usePrintable(s - System.out.println(s));//方法引用usePrintable(System.out::println);}private static void usePrintable(Printable p) {p.printString(爱生活爱Java);}
}2.2方法引用符【理解】 方法引用符 :: 该符号为引用运算符而它所在的表达式被称为方法引用
2.3引用类方法【应用】
引用类方法其实就是引用类的静态方法 格式 类名::静态方法 范例 Integer::parseInt Integer类的方法public static int parseInt(String s) 将此String转换为int类型数据 练习描述 定义一个接口(Converter)里面定义一个抽象方法 int convert(String s);定义一个测试类(ConverterDemo)在测试类中提供两个方法 一个方法是useConverter(Converter c)一个方法是主方法在主方法中调用useConverter方法 代码演示 public interface Converter {int convert(String s);
}public class ConverterDemo {public static void main(String[] args) {//Lambda写法useConverter(s - Integer.parseInt(s));//引用类方法useConverter(Integer::parseInt);}private static void useConverter(Converter c) {int number c.convert(666);System.out.println(number);}
}使用说明 Lambda表达式被类方法替代的时候它的形式参数全部传递给静态方法作为参数
2.4引用对象的实例方法【应用】
引用对象的实例方法其实就引用类中的成员方法 格式 对象::成员方法 范例 HelloWorld::toUpperCase String类中的方法public String toUpperCase() 将此String所有字符转换为大写 练习描述 定义一个类(PrintString)里面定义一个方法 public void printUpper(String s)把字符串参数变成大写的数据然后在控制台输出 定义一个接口(Printer)里面定义一个抽象方法 void printUpperCase(String s) 定义一个测试类(PrinterDemo)在测试类中提供两个方法 一个方法是usePrinter(Printer p)一个方法是主方法在主方法中调用usePrinter方法 代码演示 public class PrintString {//把字符串参数变成大写的数据然后在控制台输出public void printUpper(String s) {String result s.toUpperCase();System.out.println(result);}
}public interface Printer {void printUpperCase(String s);
}public class PrinterDemo {public static void main(String[] args) {//Lambda简化写法usePrinter(s - System.out.println(s.toUpperCase()));//引用对象的实例方法PrintString ps new PrintString();usePrinter(ps::printUpper);}private static void usePrinter(Printer p) {p.printUpperCase(HelloWorld);}
} 使用说明 Lambda表达式被对象的实例方法替代的时候它的形式参数全部传递给该方法作为参数
2.5引用类的实例方法【应用】
引用类的实例方法其实就是引用类中的成员方法 格式 类名::成员方法 范例 String::substring public String substring(int beginIndex,int endIndex) 从beginIndex开始到endIndex结束截取字符串。返回一个子串子串的长度为endIndex-beginIndex 练习描述 定义一个接口(MyString)里面定义一个抽象方法 String mySubString(String s,int x,int y); 定义一个测试类(MyStringDemo)在测试类中提供两个方法 一个方法是useMyString(MyString my)一个方法是主方法在主方法中调用useMyString方法 代码演示 public interface MyString {String mySubString(String s,int x,int y);
}public class MyStringDemo {public static void main(String[] args) {//Lambda简化写法useMyString((s,x,y) - s.substring(x,y));//引用类的实例方法useMyString(String::substring);}private static void useMyString(MyString my) {String s my.mySubString(HelloWorld, 2, 5);System.out.println(s);}
}使用说明 Lambda表达式被类的实例方法替代的时候 第一个参数作为调用者 后面的参数全部传递给该方法作为参数
2.6引用构造器【应用】
引用构造器其实就是引用构造方法 l格式 类名::new 范例 Student::new 练习描述 定义一个类(Student)里面有两个成员变量(name,age) 并提供无参构造方法和带参构造方法以及成员变量对应的get和set方法 定义一个接口(StudentBuilder)里面定义一个抽象方法 Student build(String name,int age); 定义一个测试类(StudentDemo)在测试类中提供两个方法 一个方法是useStudentBuilder(StudentBuilder s)一个方法是主方法在主方法中调用useStudentBuilder方法 代码演示 public class Student {private String name;private int age;public Student() {}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 interface StudentBuilder {Student build(String name,int age);
}public class StudentDemo {public static void main(String[] args) {//Lambda简化写法useStudentBuilder((name,age) - new Student(name,age));//引用构造器useStudentBuilder(Student::new);}private static void useStudentBuilder(StudentBuilder sb) {Student s sb.build(林青霞, 30);System.out.println(s.getName() , s.getAge());}
}使用说明 Lambda表达式被构造器替代的时候它的形式参数全部传递给构造器作为参数