前言
b站java课程学习笔记整理。
b站视频: 黑马程序员全套Java教程_Java基础入门视频教程,零基础小白自学Java必备教程
385. 体验Stream流
直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:生成流、过滤姓张、过滤长度为3、逐一打印。
真正的使用了函数式的编程思想。
386. Stream流常见生成方式
Stream流的使用
生成流
通过数据源(集合,数组等生成流)
list.stream()
中间操作
一个流后面可以跟随零个或者多个中间操作,其主要目的是打开流,做出某种程度的数据过滤、映射,然后返回一个新的流,交给下一个操作使用
filter()
终结操作
一个流只能有一个终结操作,当操作执行后,流就被用光了。所以必定是最后一个流执行forEach()
Stream流的生成方式
Collection
体系的集合可以使用默认方法stream()
生成流
default Stream<E> stream()
Map
体系的集合间接的生成流
数组可以通过Stream
接口的静态方法of(T...values)
生成流
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package StreamDemo;import java.util.*;import java.util.stream.Stream;public class StreamDemo { public static void main (String[] args) { List<String> list = new ArrayList<>(); Stream<String> listStream = list.stream(); Set<String> set = new HashSet<>(); Stream<String> setStream = set.stream(); Map<String,Integer>map = new HashMap<>(); Stream<String> keyStream = map.keySet().stream(); Stream<Integer> valueStream = map.values().stream(); Stream<Map.Entry<String,Integer>>entryStream = map.entrySet().stream(); String[] strArray = {"hello" ,"world" }; Stream<String> strArrayStream = Stream.of(strArray); Stream<String> stringStream2 = Stream.of("hello" ,"world" ); Stream<Integer> intStream = Stream.of(10 ,20 ,30 ); } }
387. Steam流之filter
用于对流中的数据进行过滤
Stream<T> filter(Predicate predicate)
: 用于对流中的数据进行过滤。
使用的是Predicate接口中的方法 boolean test(T t)
用法举例:
1 list.stream.filter(s->s.startsWith("张" )).forEach(System.out::println)
可以多个filter"串联"。
388. Steam流中间操作limit&skip
Stream<T> limit(long maxSize)
:返回此流中的元素组成的流,截取前指定参数个数的数据。(取前几个)
Stream<T> skip(long n)
:跳过指定参数个数的数据,返回由该流的剩余元素组成的流。(跳过几个)
389. Steam流中间操作concat&distinct
static <T> Stream <T> concat(Stream a,Stream b)
:将两个流合并。
用法:
1 Stream.concat(s1,s2).forEach(System.out::println);
Stream<T>distinct()
:返回由该流的不同元素(根据object.equals(Object)
)组成的流。(去掉重复的)
390.Steam流中间操作之sorted
Stream<T> sorted()
:返回由此流的元素组成的流,根据自然顺序排序。
Stream<T> sorted(Comparator comparator)
:返回由该流的元素组成的流,根据提供的Comparator
进行排序。
比较器举例:
1 2 3 4 5 list.stream().sorted((s1,s2)->{ int num = s1.length()-s2.length(); int num2 = num ==0 ?s1.compareTo(s2):num; return num2 }).forEach(System.out::println);
391. Steam流中间操作之map&mapToInt
<R> Stream<R> map(Function mapper)
:返回由给定函数应用于此流的元素的结果组成的流。
IntStream mapToInt(ToIntFunction mapper)
:返回一个IntStream
其中包括将给定函数应用于此流的元素的结果。
392. Steam流终结操作forEach&count
void forEach(Consumer action)
: 对此流的每个元素执行操作。
long count()
:返回流元素个数。
393. Stream流综合练习
现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下操作:
男演员取名字为3个字的前三个人
女演员只要姓林的,不要第一个
把过滤后的男演员姓名和女演员姓名合并到一起
把上一步操作后的元素作为构造方法的参数创建演员对象,并遍历。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package Stream案例;import java.util.ArrayList;import java.util.stream.Stream;public class StreamTest { public static void main (String[] args) { ArrayList<String>manList = new ArrayList<>(); manList.add("周润发" ); manList.add("成龙" ); manList.add("刘德华" ); manList.add("吴京" ); manList.add("周星驰" ); manList.add("李连杰" ); ArrayList<String>womanList = new ArrayList<>(); womanList.add("林心如" ); womanList.add("张曼玉" ); womanList.add("林青霞" ); womanList.add("柳岩" ); womanList.add("林志玲" ); womanList.add("王祖贤" ); Stream<String> manStream = manList.stream().filter(s->s.length()==3 ).limit(3 ); Stream<String> womenStream = womanList.stream().filter(s->s.startsWith("林" )).skip(1 ); Stream<String> stream = Stream.concat(manStream,womenStream); stream.map(Actor::new ).forEach(p->System.out.println(p.getName())); } }
394. Stream流的收集操作
Stream流的收集方法
R collect(Collector collector)
但是这个收集方法的参数是一个Collector接口
工具类Collectors提供了具体的收集方式
public static <T> Collector toList()
: 把元素收集到List集合中
Public static <T> Collector toSet()
: 把元素收集到Set集合中
public static Collector toMap(Function keyMapper, Function valueMapper)
: 把元素收集到Map集合中
395. 类加载
当程序要使用某个类时,如果该类还未被加载到内存中,系统就会通过类的加载,类的链接,类的初始化这三个步骤来对类进行初始化。
类的加载
类的连接
验证阶段: 用于检验被加载的类是否有正确的内部结构,并和其他类协调一致。
准备阶段: 负责为类的类变量分配内存,并设置默认初始化值。
解析阶段: 将类的二进制数据中的符号引用替换为直接引用。
类的初始化:
类初始化的步骤
假如类还没有被加载和连接,则程序被加载并连接该类
假如该类的直接父类还未被初始化,则先初始化其直接父类
假如类中有初始化语句,则系统依次执行这些初始化语句。
注意: 在执行第二个步骤的时候,系统对直接父类的初始化步骤也遵循初始化步骤1-3.
396.类加载器
Bootstrap class loader
Platform class loader
System class loader
方法:
static ClassLoader getSystemClassLoader()
:返回用于委派的系统类加载器
ClassLoader getParent()
: 返回父类加载器进行委派。
1 2 3 4 5 6 Classloader c = ClassLoader.getSystemClassLoader(); System.out.println(c); Classloader c2 = c.getParent(); System.out.println(c2); Classloader c3 = c2.getParent(); System.out.println(c3);
397. 反射概述
反射机制: 是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大地增强程序的灵活性。程序不用在编译期就完成确定,在运行期仍然可以扩展。
398. 获取class类的对象
我们想要通过反射去使用一个类,首先要获取到该类的字节码文件对象,也就是类型为class类型的对象。
三种方式:
使用类的class属性来获取该类对应的class对象。
调用对象的getClass()
方法
使用Class类中的静态方法forName(String className)
三种方式的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package 反射;public class test { public static void main (String[] args) throws ClassNotFoundException { Class<Student> c1 = Student.class; System.out.println(c1); Class<Student> c2 = Student.class; System.out.println(c1 == c2); System.out.println("---------" ); Student s = new Student(); Class<? extends Student> c3 = s.getClass(); System.out.println(c1==c3); System.out.println("---------" ); Class<?> c4 = Class.forName("反射.Student" ); System.out.println(c4 == c1); } }
399. 反射获取构造方法并使用
Constructor<?> [] getConstructors()
:返回所有公共构造方法对象的数组
Constructor<?> [] getDeclaredConstructors()
:返回所有构造方法对象的数组
Constructor<?> [] getConstructor(Class<?>...parameterTypes)
:返回单个公共构造方法对象
Constructor<?> [] getDeclaredConstructor(Class<?>...parameterTypes)
返回单个构造方法对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package 反射;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class test { public static void main (String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { Class<?> c = Class.forName("反射.Student" ); Constructor<?>[] constructors1 = c.getConstructors(); for (Constructor constructor: constructors1){ System.out.println(constructor); } Constructor<?>[] constructors2 = c.getDeclaredConstructors(); for (Constructor constructor: constructors2){ System.out.println(constructor); } Constructor<?> con = c.getConstructor(); Object obj = con.newInstance(); System.out.println(obj); } }
400. 反射获取构造方法并使用练习1
通过反射实现:
Student s = new Student("林青霞",30)
;
System.out.println(s)
;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package 反射;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class test { public static void main (String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { Class<?> c = Class.forName("反射.Student" ); Constructor<?> constructor = c.getConstructor(String.class, int .class); Object obj = constructor.newInstance("林青霞" ,30 ); System.out.println(obj); } }
401. 反射获取构造方法并使用练习2
通过反射实现:
Student s = new Student("林青霞")
;
System.out.println(s)
;
注意,只以名字的构造方法是private的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package 反射;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class test { public static void main (String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { Class<?> c = Class.forName("反射.Student" ); Constructor<?> constructor = c.getDeclaredConstructor(String.class); constructor.setAccessible(true ); Object obj = constructor.newInstance("林青霞" ); System.out.println(obj); } }
402. 反射获取成员变量并使用
Field[] getField()
:返回所有公共成员变量对象的数组
Field[] getDeclaredField()
:返回所有成员变量对象的数组
Field[] getField(String name)
:返回单个公共成员变量对象
Field getDeclaredField(String name)
:返回单个成员变量对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package 反射;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;public class test { public static void main (String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException { Class<?> c = Class.forName("反射.Student" ); Field[] fields = c.getFields(); for (Field field: fields){ System.out.println(field); } Field[] fields2 = c.getDeclaredFields(); for (Field field: fields2){ System.out.println(field); } Field nameField = c.getField("name" ); Constructor<?> constructor = c.getConstructor(); Object obj = constructor.newInstance(); nameField.set(obj,"好人" ); System.out.println(obj); } }
403. 反射获取成员变量并使用练习
跟上集一样
404. 反射获取成员方法并使用
Method[] getMethods()
:返回所有公共成员方法对象的数组,包括继承的
Method[] gerDeclaredMethods()
:返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?>... parameterTypes)
:返回单个公共成员方法对象
Method getDeclaredMethod(String name,Class<?> ... parameterTypes)
: 返回单个成员方法对象
invoke(obj)
在具有指定参数的指定对象上调用上述得到的method。
405. 反射获取成员方法并使用练习
和前面一样
406. 反射练习:越过泛型检查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package 反射;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;public class test { public static void main (String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException { ArrayList<Integer> array = new ArrayList<>(); array.add(10 ); array.add(20 ); Class<? extends ArrayList> c = array.getClass(); Method m = c.getMethod("add" , Object.class); m.invoke(array,"hello" ); System.out.println(array); } }
407. 通过配置文件运行指定方法
1 2 3 4 5 6 7 8 package 反射配置练习;public class Student { public void study () { System.out.println("好好学习" ); } }
1 2 3 4 5 6 7 8 package 反射配置练习;public class Teacher { public void teach () { System.out.println("教书" ); } }
1 2 3 className=反射配置练习.Student methodName=study
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package 反射配置练习;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Properties;public class test { public static void main (String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { Properties prop = new Properties(); FileReader fr = new FileReader("java.txt" ); prop.load(fr); fr.close(); String className = prop.getProperty("className" ); String methodName = prop.getProperty("methodName" ); Class<?> aClass = Class.forName(className); Constructor<?> constructor = aClass.getConstructor(); Object obj = constructor.newInstance(); Method m = aClass.getMethod(methodName); m.invoke(obj); } }
408. 模块化
可以加载指定模块(就是模块下新建好一个包,包下新建好一个类的那个模块),而不是整个虚拟机。
409. 模块的基本使用
在模块的src目录下新建一个名为module-info.java的描述性文件,该文件专门定义模块名,访问权限,模块依赖等信息,描述性文件中使用模块导出和模块依赖来进行配置使用。
某个包的导出:
1 2 3 module idea.test { exports 集合到文件; }
1 2 3 module imp.test { requires idea.test; }
410. 模块服务的使用
步骤
在X模块下创建一个包a,在包a下提供一个接口,接口中定义了一个抽象方法
1 2 3 public interface MyService { void service () ; }
在包a下创建一个包impl,在该包impl下提供接口的两个实现类b和c
在X模块下的描述文件中添加如下配置
模块导出: exports a
服务提供:provides Myservice with b //指定服务的实现类是服务b
总结:源码
完结了!作业源码地址是:这里