Java 8学习笔记随记

一、Dos命令

1、打开方式:

        ①、打开快捷键:Windows+R键输入cmd

        ②、任意文件夹下,按住shift键+鼠标右键点击打开命令行窗口

        ③、资源管理器的地址栏加上cmd路径

        ④、管理员方式运行

2、Dos命令

       ①、 #盘符切换:  输入想要进入的盘符+冒号;如:E:回车

       ②、查看当前目录下的所有文件:dir

        ③、切换目录:cd /d f:

        ④、返回上一级:cd..

二、日常学习

1.XML和YAML的区别

        xml:可扩展性标记语言,用来标记数据,定义数据类型,适合web传输,仅仅存储数据;通过JavaScript读写xml数据;特点:1.区分大小写2.所有的标签成对出现

        yaml:比xml更易读懂的序列化语言,Structure通过空格来展示。Sequence里的项用"-"来代表,Map里的键值对用":"分隔.

        yaml相比xml优点:1.脚本语言交互性好;2.可读性好;3.实现语言的数据类型;4.有一个一致的信息模型;5.易于实现。

2.在maven项目中对于端口、数据驱动类的配置在application.yml配置文件中。对于redis、数据库等数据源在application-dev.yml中配置;

3.数据库连接池:Durid(最好的数据库连接池)、DBCP、C3P0、BoneCP、Proxool、JBoss、DateSource。

        Durid:是一个JDBC组件,包含三部分:基于Filter(过滤器)——Chain模式的插件体系、DuridSource(高效可管理的数据库连接池)、SQLParser;Durid功能:1.提供一个高效、功能强大、可扩展性好的数据库连接池;2.可以监控数据库访问性能,Durid内部提供StatFilter插件,能够详细统计SQL的执行性能,对于线上数据库访问性能有帮助。3.数据库密码加密。直接把数据库密码写在配置文件中是不好的行为,容易导致安全问题。DuridDriver和DuridDataSource都支持PassWordCallback。4.SQL执行日志,Durid提供了不同的LogFilter,能够支持Common-Logging、Log4j狠人JDKLog,可以按需要选择相应的LogFilter,监控数据库的访问情况。5.扩展JDBC,如果要对JDBC层有编程的需求,可以通过Druid提供的Filter机制,很方便JDBC层的扩展插件。

4.knife4j:Java MVC框架集成Swagger生成API文档解决

5.Lamda

        定义:一种简洁、可传递的匿名函数,虽不属于某个特定的类,但具备参数列表,函数主体,返回类型,甚至能够报出异常。允许把函数作为一个方法的参数进行传递。可以把函数作为一个方法的参数。

        格式:参数列表 ->表达式 、参数列表 ->{表达式集}。当为单个表达式时不需要加return,隐含return关键字,当为表达式集时需要加return关键字。

        例如:返回字符串长度:

(String str)->str.length();

                返回233的无参方法:

()-> 233;

                返回当前用户的年龄是否大于20岁,返回一个boolean值:

(User user)-> user.getAge()>20;

                包含多行表达式,需要return的关键字返回:

(int x,int y)->{
     int z = x*y;
     return z+x;
}

          关于Lambda的异常抛出问题:

                1.添加FunctionInterface,用于对函数式接口的检查,非函数式接口使用回报错,但是函数式接口可使用,也可不适用,不会报错,只是不会检查。     

具体操作如下:定义一个Try类:       

public class Try {
 
    public static <T, R> Function<T, R> of(UncheckedFunction<T, R> mapper) {
        Objects.requireNonNull(mapper);
        return t -> {
            try {
                return mapper.apply(t);
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        };
    }
 
    @FunctionalInterface
    public static interface UncheckedFunction<T, R> {
 
        R apply(T t) throws Exception;
    }
}

例如:对于一个数字集合进行依次除法,当除到0时就不回报出异常

List<Integer>integers=Arrays.asList(1,2,3,4,5,6,0);
integers.forEach(Try.of(i->System.out.println(50/i)));

6.Stream(流)

作用:用于对于集合的处理,如对于集合的筛选,投影等

特点:1.只遍历一次,一旦结束,无法对于流进行操作,可以新建流进行遍历;2.采用内部迭代,写代码进行处理属于外部迭代,流处理,只需要告诉想要的结果,流去处理,属于内部迭代。

流的两个操作:1.中间操作:一旦把数据源放到流水线上,之后对于流水线的操作都属于中间操作,也就是说,一个流水线可以有多个中间操作串和起来。2.终端操作:终端操作指的是流水线的中间操作都结束,你想要获得这个数据,则需要将数据将流水线上拿下来,则需要这个终端操作返回一个执行过程,拿到数据。

流的操作过程:1.准备数据源 2.进行中间操作(可多个,组成一个流水线)3.终端操作(执行终端操作之后,流结束,而你会获得一个执行结果)。

Stream API转换:

1.list的转换

//转Stream
list.stream();
//并发处理
list.parallelStream();

 2.filter

Stream<T> filter(Predicate<? super T> predicate);

3.map(元素转换)

<R> Stream<R> map(Function<? super T,? extends R> mapper);
IntStream mapToInt(ToIntFunction<? super T> mapper);
LongStream mapToLong(ToLongFunction<? super T> mapper);
DoubleStream mapToDouble(ToDoubleFunction<? super>T mapper);

4.flatMap(元素转换)

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper); 
IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper); 
LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper); 
DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);

5.distinct(去除重复,对象需要重写 equalshashCode   

Stream<T> distinct();

6.sorted排序

Stream<T> sorted(); 
Stream<T> sorted(Comparator<? super T> comparator);

7.peek(生成新的流:流是单向的,例如用于日志打印) 

Stream<T> peek(Consumer<? super T> action);

8.limit(取前面 n 个元素)

Stream<T> limit(long maxSize);

9.skip(跳过 n 个元素) 

Stream<T> skip(long n);

10.forEach(遍历)

void forEach(Consumer<? super T> action); 
void forEachOrdered(Consumer<? super T> action);

11.toArray(转换成数组) 

Object[] toArray(); 
<A> A[] toArray(IntFunction<A[]> generator);

12.reduce(结果归并)  

T reduce(T identity, BinaryOperator<T> accumulator);
Optional<T> reduce(BinaryOperator<T> accumulator); 
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator
, BinaryOperator<U> combiner);

13.collect(转换成集合)  

<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator
, BiConsumer<R, R> combiner);
<R, A> R collect(Collector<? super T, A, R> collector);

转list

// 转list 
Collectors.toList(); 
// 转set 
Collectors.toSet(); 
// 转map 
List<TestVo> testList = new ArrayList<>(10); 
Map<Long, TestVo> data = releaseList.stream() 
                            .collect(Collectors
                            .toMap(TestVo::getId, x -> x));

count(计数) 

long count();

查找

boolean anyMatch(Predicate<? super T> predicate); 
boolean allMatch(Predicate<? super T> predicate); 
boolean noneMatch(Predicate<? super T> predicate);
Optional<T> findFirst(); 
Optional<T> findAny();

流创建

 1.数据源形式

集合

List<Person> list = new ArrayList<Person>(); 
Stream<Person> stream = list.stream();

数组

String[] names = {"chaimm","peter","john"}; 
Stream<String> stream = Arrays.stream(names);

Stream<String> stream = Stream.of("chaimm","peter","john");

文件

try(Stream lines = Files.lines(Paths.get(“文件路径名”)
                    ,Charset.defaultCharset())){ //可对lines做一些操作 }
catch(IOException e){ }

iterator (迭代器) 

        创建无限流

Stream.iterate(0, n -> n + 2) 
    .limit(10)
    .forEach(System.out::println);

filter 筛选

filter 函数接收一个 Lambda 表达式作为参数,该表达式返回 boolean ,在执行过程中,流将元素逐一输 送给filter ,并筛选出执行结果为 true 的元素。
如,筛选出所有学生:
List<Person> result = list.stream() 
                          .filter(Person::isStudent) 
                          .collect(toList());

 distinct去重

List<Person> result = list.stream() 
                          .distinct() 
                          .collect(toList());

截取流的前N个元素: 

List<Person> result = list.stream()
                         .limit(3) 
                         .collect(toList());

跳过流的前N个元素:

List<Person> result = list.stream() 
                          .skip(3) 
                          .collect(toList());
映射
对流中的每个元素执行一个函数,使得元素转换成另一种类型输出。流会将每一个元素输送给 map 函 数,并执行map 中的 Lambda 表达式,最后将执行结果存入一个新的流中。
如,获取每个人的姓名 ( 实则是将 Perosn 类型转换成 String 类型 )
List<Person> result = list.stream() 
                        .map(Person::getName) 
                        .collect(toList());

 合并多个流

例:列出 List 中各不相同的单词, List 集合如下:
List<String> list = new ArrayList<String>(); 
list.add("I am a boy"); 
list.add("I love the girl"); 
list.add("But the girl loves another girl");

解决代码:

list.stream() //将list变成流
    .map(line->line.split(" ")) //将各个单词以空格分开,变成String[],成为各个String[]
    .flatMap(Arrays::stream) //将各个String[]变成小流并合并,将map转换成flatmap
    .distinct() //去重
    .collect(toList());//获得结果集
是否匹配任一元素: anyMatch
anyMatch 用于判断流中是否存在至少一个元素满足指定的条件,这个判断条件通过 Lambda 表达式传递 给anyMatch ,执行结果为 boolean 类型。
如,判断 list 中是否有学生:
boolean result = list.stream() 
                    .anyMatch(Person::isStudent);
是否匹配所有元素: allMatch
allMatch 用于判断流中的所有元素是否都满足指定条件,这个判断条件通过 Lambda 表达式传递给
anyMatch ,执行结果为 boolean 类型。
如,判断是否所有人都是学生:
boolean result = list.stream() 
                     .allMatch(Person::isStudent);
是否未匹配所有元素: noneMatch
noneMatch allMatch 恰恰相反,它用于判断流中的所有元素是否都不满足指定条件:
例如:判断是否都不满足是学生这个条件:
boolean result = list.stream() 
                    .noneMatch(Person::isStudent);
获取任一元素 findAny
findAny 能够从流中随便选一个元素出来,它返回一个 Optional 类型的元素。
Optional<Person> person = list.stream().findAny();
归约
归约是将集合中的所有元素经过指定运算,折叠成一个元素输出,如:求最值、平均数等,这些操作都 是将一个集合的元素折叠成一个元素输出。 在流中,reduce 函数能实现归约。
reduce 函数接收两个参数:
1. 初始值
2. 进行归约操作的 Lambda 表达式

        元素求和:自定义Lambda表达式实现求和        

例如:计算所有人的年龄总和

@Test 
public void contextLoads() { 
    List<Person> list = new ArrayList<>(); 
    list.add(new Person().setAge(20)); 
    list.add(new Person().setAge(25)); 
    int age = list.stream().map(Person::getAge).reduce(0, Integer::sum);                                 
    System.out.println(age); 
}
@Data 
@Accessors(chain = true) 
class Person { 
    int age; 
}
        1. reduce的第一个参数表示初试值为 0
        2. reduce的第二个参数为需要进行的归约操作,它接收一个拥有两个参数的Lambda表达式,reduce,会把流中的元素两两输给Lambda表达式,最后将计算出累加之和
int age = list.stream().reduce(0, Integer::sum);

数值流的使用:

       采用用reduce进行数值操作会涉及到基本数值类型和引用数值类型之间的装箱、拆箱操作,因此效率较低。 当流操作为纯数值操作时,使用数值流能获得较高的效率。 将普通流转换成数值流 StreamAPI提供了三种数值流:IntStreamDoubleStreamLongStream,也提供了将普通流转换成数值流的三种方法:mapToIntmapToDoublemapToLong

如,将Person中的age转换成数值流:

IntStream stream=list.stream().mapToInt(Person::getAge);

数值计算: 

每种数值流都提供max、min、sum等一系列数值操作,当流中元素为数值类型时可以直接使用。 

如:找出最大年龄:

OptionalInt maxAge = list.stream()
                        .mapToInt(Person::getAge)
                        .max();
由于数值流可能为空,并且给空的数值流计算最大值是没有意义的,因此 max 函数返回 OptionalInt ,它是Optional 的一个子类,能够判断流是否为空,并对流为空的情况作相应的处理。
此外, mapToInt mapToDouble mapToLong 进行数值操作后的返回结果分别为: OptionalInt OptionalDouble OptionalLong。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值