# study **Repository Path**: initialed-exchange/study ## Basic Information - **Project Name**: study - **Description**: 实习学习代码 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-08-12 - **Last Updated**: 2025-10-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README Java stream流: ​ Stream不改变原数据 不对数据进行存储管理 具有懒惰执行的特点 ​ 流的使用步骤: ​ 1、创建流 ​ 1)从集合、数组中创建流 ​ 2)Stream.of()方法创建 ​ 3)创建无限流 Stram.iterate() Stream.generate() 必须调用limit()方法 否则程序无限执行 ​ 2、流的中间操作 ​ 过滤、切片 ​ 映射、截断、排序、合并等 ​ 3、流的终止操作: 只有执行终止操作后时 流的中间操作才会全部执行 (流的懒惰执行) 流终止后就不能在使用了 ​ 内部遍历:forEach ​ 收集:将流元素收集到Collection中 ​ reduce: 对流中的元素反复结合 ​ T result = identity; ​ for (T element : this stream) ​ result = accumulator.apply(result, element) return result; ​ 匹配与查找 ​ 2、串行流和并行流 ​ 并行流:对数据块进行拆分、内部使用fork/join机制对流数据进行处理 ```java /** * @author caoqianhuan * @date 2022/8/10 * @desc 从集合中创建流 * @return */ public Stream createStreamFromCollection() { List list = new ArrayList<>(10); list.add("a"); list.add("b"); list.add("c"); return list.stream(); } public IntStream createStreamFromArray() { IntStream stream = Arrays.stream(new int[] {6, 7, 1, 3, 5, 8, 89, -1, 12, 7, 8, 2, 3, 2, 10}); return stream; } public Stream createStream() { return Stream.of(6, 7, 1, 3, 5, 8, 89, -1, 12, 7, 8, 2, 3, 2, 10); } /** * @author caoqianhuan * @date 2022/8/10 * @desc 中间操作 * @return */ @org.junit.Test public void testOperateFilter() { IntStream stream = createStreamFromArray(); stream.filter(item -> (item % 2) == 0).distinct().limit(3).forEach(System.out::println); } public void testOperateMap() { Stream stream = createStreamFromCollection(); stream.map(String::toLowerCase).forEach(System.out::println); } public void testOperateSort() { IntStream stream = createStreamFromArray(); stream.sorted().skip(2).forEach(System.out::println); List linkedStudents = new LinkedList<>(); linkedStudents.add(new Student("caoqianhuan", 20)); linkedStudents.add(new Student("zhangsan", 21)); linkedStudents.stream().sorted((o1, o2) -> o2.getAge() - o1.getAge()).forEach(System.out::println); } /** * @author caoqianhuan * @date 2022/8/10 * @desc 测试reduce操作 * @return */ public void testOperateReduce() { Stream stream = createStreamFromCollection(); // System.out.println(stream.reduce((item1, item2) -> item1 + item2).get()); // 并行流的串行流的切换 不会创建新的流 // System.out.println(stream == stream.parallel()); System.out.println(stream.reduce("", (item1, item2) -> item1 + item2)); } public void testCollect() { Set students = new HashSet<>(); students.add(new Student("a", 12)); students.add(new Student("b", 21)); List list = students.stream().collect(Collectors.toCollection(ArrayList::new)); for (Student stu: list) { System.out.println(stu); } } public void testParallel() { IntStream stream = createStreamFromArray(); // 打印顺序和串行流顺序不一样 进行了数据拆分 多线程并行输出 stream.parallel().forEach(System.out::println); // stream.forEach(System.out::println); } ``` # lambda表达式: 函数式接口: 使用@FunctionalInterface注解标注的接口。接口只能有一个方法(默认方法和静态方法以及继承自Object类的方法除外) 函数式接口的实现类可以用lambda表达式简化 1、lambda表达式 必须和接口进行绑定 2、lambda表达式,可以附带0到n个参数,括号中的参数类型可以不用指定,jvm在运行时,会自动根据绑定的抽象方法中的参数进行推导 3、lambda表达式,如果代码块只有一行,可以省略大括号,和return关键字,单行代码的执行结果会自动返回 4、lambda表达式较传统匿名内部类比较,其this指向表达式所在的类 5、lambda表达式可以很好的定义回调:创建线程时传入 () -> {} 就是很好的例子 除了可以自定义函数式接口使用lambda表达式;jdk的提供了一些函数式接口 ![img](https://img-blog.csdnimg.cn/img_convert/bec9f346571d6ca234857112b88128d7.png) ![img](https://img-blog.csdnimg.cn/img_convert/bd8ee1d012794825987a5189a23700fe.png) # 方法引用及JDK函数式接口 ​ 方法引用实际上时lambda表达式的语法糖:当lambda表达式的实现体 已经有实现的方法 则可以使用方法引用 ​ 要求:lambda表达式的参数和返回值 和 已有实现方法的参数的返回值 一样 ​ 格式:类\对象::方法名 ```java @FunctionalInterface public interface Functional { void doFun(); } public void testLambda() { Random random = new Random(); Supplier supplier = () -> random.nextInt(); System.out.println(supplier.get()); Supplier supplier1 = random::nextInt; System.out.println(supplier1.get()); Consumer consumer = (i) -> { System.out.println(i); }; consumer.accept(1); Consumer consumer1 = System.out::println; consumer1.accept(1); Function function = (str) -> Integer.valueOf(str); System.out.println(function.apply("1")); Function function1 = Integer::valueOf; System.out.println(function1.apply("1")); Predicate predicate = (i) -> Integer.TYPE.isInstance(i); System.out.println(predicate.test(-1)); Predicate predicate1 = Integer.TYPE::isInstance; System.out.println(predicate1.test(-1)); BiFunction biFunction = (str, integer) -> str + Integer.valueOf(integer); System.out.println(biFunction.apply("hello", 520)); UnaryOperator unaryOperator = (i) -> i - 1; System.out.println(unaryOperator.apply(0)); BiConsumer biConsumer = (str, i) -> System.out.println(str + i); biConsumer.accept("Hello", 520); BiPredicate biPredicate = (a, b) -> a && b; System.out.println(biPredicate.test(true, false)); /*执行结果 * testLambda(com.dubbo.AppTest) * com.dubbo.AppTest$1@2077d4de * */ Functional functional = () -> { System.out.println(this); }; functional.doFun(); Functional functional1 = new Functional() { @Override public void doFun() { System.out.println(this); } }; functional1.doFun(); } ``` # Optional类 Optional类是jdk1.8新增的容器类,代表一个值存在或不存在,原来用null表示一个值不存在,现在Optional可以更好的表达这个概念。可以避免空指针异常; 代码中为避免空指针异常常常会使用 i f 语句判空 使用Optional类 能够以更简洁的代码实现 常用方法: `Optional.of(T t):创建一个Optional实例` `Optional.empty():创建一个空的Optional实例` `Optional.ofNullable(T t):若t不为null,创建Optional实列,否则创建空实例` `isPresent():判断是否包含值` `orElse(T t):如果调用对象包含值,返回该值,否则返回t` `orElseGet(Supplier s):如果调用对象包含值,返回该值,否则返回s获取的值` `map(Function f):如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()` `flatMap(Function mapper):与map类似,要求返回值必须是Optional` ```java public void testOptional() { getStudentSchool(new Student("草签换", 21, null)); getStudentSchool(null); } public void getStudentSchool(Student student) { Optional optional = Optional.ofNullable(student); //获取学生的学校名称 System.out.println(optional.orElseGet(() -> new Student("很好", 12, Optional.ofNullable(null))) .getSchool().orElse(new School("石河子大学")).getName()); // student为空抛出NoSuchElementException异常 System.out.println(optional.get()); // student为空则抛出异常 Optional optional1 = Optional.of(student); System.out.println(optional1.get()); } public void testOptional1() { System.out.println(Optional.empty().isPresent()); Optional optional = Optional.ofNullable(new Student("草签换", 21, Optional.ofNullable(new School("qqq")))); System.out.println(optional.map((s) -> s.getAge()).get()); // Optional optional1 = Optional.ofNullable(null); Optional optional1 = Optional.empty(); System.out.println(optional1.isPresent()); System.out.println(optional1.map((stu) -> stu.getName()).get()); } ``` # java8新增时间日期类 LocalDate、LocalTime、LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。 ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法 ```java public class TestNewDate extends TestCase { @Test public void testCreate () { //从当前时间创建日期 LocalDate today = LocalDate.now(); System.out.println(today); //从指定时间创建日期 LocalDate myBirthDay = LocalDate.of(2001, 5, 22); System.out.println(myBirthDay); //从当前事件创建日期时间 LocalTime now = LocalTime.now(); System.out.println(now); //给时间加上指定分钟 LocalTime justNow = now.minusMinutes(1); System.out.println(justNow); //给日期减去指定天数 LocalDate yestoday = today.minusDays(1); System.out.println(yestoday); //给日期加上指定天数 LocalDate tomorrow = today.plusDays(1); System.out.println(tomorrow); System.out.println(today.isLeapYear()); //获取时间的周 MONDAY System.out.println(today.getDayOfWeek()); //获取日期是当前年份的第几天 System.out.println(today.getDayOfYear()); //获取日期是当前月份的第几天 System.out.println(today.getDayOfMonth()); //获取时间的月份 AUGUST System.out.println(today.getMonth()); System.out.println(today.getYear()); System.out.println(today.isBefore(yestoday)); System.out.println(today.isAfter(yestoday)); //获取与指定时间的间隔 并转换为指定单位 System.out.println(now.until(now.plusMinutes(3), ChronoUnit.SECONDS)); // System.out.println(today.until(tomorrow)); } /** * @author caoqianhuan * @date 2022/8/15 * @desc 用于“时间戳”的运算。它是以Unix元年(传统的设定为UTC时区1970年1月1日午夜时分)开始所经历的描述进行运算 * @return */ public void testInstant () { System.out.println(Instant.now()); System.out.println(Instant.now().getEpochSecond()); System.out.println(Instant.now().getNano()); System.out.println(Instant.now().getLong(ChronoField.MILLI_OF_SECOND)); System.out.println(Instant.now().getLong(ChronoField.NANO_OF_SECOND)); } /** * @author caoqianhuan * @date 2022/8/15 * @desc 日期或者时间间隔操作 * @return */ public void testBetween () { LocalDate today = LocalDate.now(); LocalDate oneDay = LocalDate.of(2022, 8, 3); //计算oneDay和today的日期间隔 System.out.println(Period.between(today, oneDay).getDays()); System.out.println(Period.between(oneDay, today).getDays()); LocalTime now = LocalTime.now(); LocalTime afternoon = LocalTime.of(12, 0); //获取两个时间的间隔 返回 Duration Duration获取间隔只 支持seconds 和 nanos 单位 但创建支持其他单位 System.out.println(Duration.between(now, afternoon).get(ChronoUnit.SECONDS)); System.out.println(Duration.between(now, afternoon).get(ChronoUnit.NANOS)); System.out.println(Duration.of(123000, ChronoUnit.MILLIS).get(ChronoUnit.SECONDS)); //会抛出异常 //System.out.println(Duration.between(now, afternoon).get(ChronoUnit.MILLIS)); } /** * @author caoqianhuan * @date 2022/8/15 * @desc 时间矫正器 * @return */ public void testAdjusters () { LocalDateTime now = LocalDateTime.now(); LocalDateTime targetTime = LocalDateTime.of(2022, 8, 16, 12, 0); //TemporalAdjuster提供大量的静态方法来矫正时间 不改变原本时间 //矫正为当前时间月份的第一天 System.out.println(now.with(TemporalAdjusters.firstDayOfMonth())); System.out.println(now); System.out.println(now.with(TemporalAdjusters.firstDayOfYear())); //矫正为下一个或当前指定的周日期 System.out.println(now.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY))); System.out.println(now.with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY))); //矫正为上一个或当前的指定周日期 System.out.println(now.with(TemporalAdjusters.previousOrSame(DayOfWeek.FRIDAY))); //自定义事=时间矫正器 => 矫正为下个工作日 now.with(temporal -> { if (now.getDayOfWeek().equals(DayOfWeek.FRIDAY)) { return now.plusDays(3); } else if (now.getDayOfWeek().equals(DayOfWeek.SATURDAY)) { return now.plusDays(2); } else { return now.plusDays(1); } }); } /** * @author caoqianhuan * @date 2022/8/15 * @desc 格式化时间日期 * @return */ public void testFormatter () { LocalDateTime today = LocalDateTime.now(); //指定格式 格式化对象 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年/MM月/dd日 hh时mm分ss秒"); //指定格式 地区 格式化对象 DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年/MM月/dd日", Locale.CHINA); LocalDate localDate = LocalDate.now(); System.out.println(localDate.format(dateFormatter)); System.out.println(today.format(formatter)); //指定已有的日期时间格式 System.out.println(today.format(DateTimeFormatter.ISO_DATE)); System.out.println(today.format(DateTimeFormatter.BASIC_ISO_DATE)); // DateTimeFormatterBuilder dateTimeFormatterBuilder = new DateTimeFormatterBuilder(); } /** * @author caoqianhuan * @date 2022/8/15 * @desc 新的日期时间 支持时区的设置 * @return */ public void testZone () { //获取所有的失去集合 Set zoneIds = ZoneId.getAvailableZoneIds(); //for (String zoneId : zoneIds) { // System.out.println(zoneId); //} //获取指定时区的时间 LocalDateTime time = LocalDateTime.now(ZoneId.of("Europe/Brussels")); System.out.println(time); } } ```