2022-8-8第八组---JUnit单元测试、File类

发布于:2023-01-19 ⋅ 阅读:(473) ⋅ 点赞:(0)

今日重点:

目录

一、JUnit单元测试

1、概念

2、JUnit单元测试的好处

3、jar包

4、JUnit单元测试的使用(测试)方法

要求:

(1)不能有返回值

(2)不能有参数列表

(3)必须有Test注解

5、JUnit断言

常用方法

6、JUnit注解

(1) Test注解

(2) Before

(3)After

7、JUnit命名规范

(1)单元测试类的命名

(2)测试方法的命名

二、集合的面试题

1、Hashtable和ConcurrentHashMap性能测试

2、ArrayList和LinkedList性能测试

  (1)按顺序添加元素效率

(2)查询效率 

(3)删除效率

3、测试结果总结

三、Stream流式编程

1、概念

2、使用流的三个步骤

3、Stream的特性

四、Stream流式编程使用示例

1、创建流的几种常见方式

(1)用集合方式创建流

(2)用到静态方法创建流(做个了解即可)

2、具体案例(具体能干什么)

(1)创建一个person类

(2)测试类Ch06

3、具体案例分段解析其使用方法

(1)打印集合元素

(2)查找元素

(3)判断元素

(4)收集元素

(5)统计

(6)归约(reduce)缩减

(7)分组

(8)筛选

(9)映射

(10)排序---sorted

五、JDK8函数式接口

1、Consumer

 2、 Supplier

 3、Function

 4、Predicate

六、 JDK8新增接口

 1.函数式接口 2.箭头函数(lambda表达式),不是java特有的。 3.Optional类 4.断言 5.Stream编程

七、Java---IO 流

1、概念

2、Input、Output

 (1)本地传输:

 (2)网络传输:

 (3) 对象传输:

3、工具类:File操作文件的类

 (1)文件的路径

 (2)File类的构造器

八、文件的操作 

1、创建文件

2、删除文件

3、创建和删除文件夹

4、创建文件夹以及此文件夹下的文件

5、其他常见命令


一、JUnit单元测试

1、概念

JUnit是一个Java语言单元测试框架。JUnit 在测试驱动的开发方面有很重要的发展,是起源于 JUnit 的一个统称为 xUnit 的单元测试框架之一。
 

2、JUnit单元测试的好处

(1)可以书写一些列的测试方法,对项目的所有的(数据)接口或者方法进行单元测试。
(2)启动后,自动化的测试,并且判断执行结果,不需要人为的干预。
(3)只需要查看最后的结果,就可以知道整个项目的方法接口是否通畅。
(4)每个单元测试用例相对独立,由JUnit启动,自动调用,不需要添加额外的调用语句。
(5)添加,删除,屏蔽测试方法,不影响其他的测试方法,开源框架都对JUnit有相应的支持。

3、jar包

如果要引入第三方的插件,其实引入的都是xxx.jar的文件。首先要把这个文件导入到我们的工程目录下,其次要添加到工程的依赖目录中。

比如要使用@Test注解

如果工程中没有导入jar包,程序是不认识@Test注解的。

4、JUnit单元测试的使用(测试)方法

要求:

(1)不能有返回值

(2)不能有参数列表

(3)必须有Test注解

package com.jsoft.morning;

import org.junit.Test;

public class Ch01 {

    @Test
    public void test01(){
        System.out.println("hello junit01");
    }

    @Test
    public void test02() {
        System.out.println("hello junit02");
    }
}

以前一个类中我们只有一个主方法可以运行,现在通过JUnit测试方法,两个方法都可以运行了,再写多个方法也是可以的 。

5、JUnit断言

断言不成功会抛异常(会报错),即使程序正常运行但是结果不正确,也会以失败结束。

JDK1.8新出的功能,用来测试程序功能好不好使的的功能, JUnit断言提供了一些辅助函数,用于帮助开发人员确定某些被测试函数是否工作正常,断言是单元测试最基本的组成部分。JUnit的所有断言都包含在Assert类中,这个类提供了很多有用的断言来编写测试用例,只有失败的断言才会被记录。Assert 类中的一些有用的方法列式如下:

常用方法

① assertEquals:

检查两个变量或等式是否平衡
② assertTrue:

检查条件是否为真


③ assertFalse:

检查条件是否为假
④ assertNotNull:

检查对象是否不为空
⑤ assertNull:

检查对象是否为空

6、JUnit注解

(1) Test注解

这个注释说明依附在 JUnit 的 public void 方法可以作为一个测试案例。

(2) Before

有些测试在运行前需要创造几个相似的对象。在 public void 方法加该注释是因为该方法需要在 test 方法前运行。

(3)After

如果你将外部资源在 Before 方法中分配,那么你需要在测试运行后释放他们。在 public void 方法加该注释是因为该方法需要在 test 方法后运行。

package com.jr.morning;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/*
JUnit注解
1.Test
2.Before
3.After

 */
public class Ch03 {
    @Test
    public void test01(){
        System.out.println("test01方法执行。。。");
    }
    @Test
    public void test02(){
        System.out.println("test02方法执行。。。");
    }
    @Before
    public void testBefore(){
        System.out.println("testBefore方法执行。。。");
    }
    @After
    public void testAfter(){
        System.out.println("testBefore方法执行。。。");
    }
}

7、JUnit命名规范

(1)单元测试类的命名

被测试类的类名 + Test

(2)测试方法的命名

test + 被测试方法的方法名
 

JUnit测试方法参考文章:https://www.jianshu.com/p/a3fa5d208c93

二、集合的面试题

我们尝试开辟50个线程,每个线程向集合中put 100000个元素,测试两个类所需的时间

1、Hashtable和ConcurrentHashMap性能测试

package com.jr.morning;

import org.junit.Test;

import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

/*
集合的好多面试
1. Hashtable和ConcurrentHashMap性能测试

 */
public class Ch04 {

    /* 我们尝试开辟50个线程,每个线程向集合中put100000个元素,
       测试两个类所需的时间
    */
    @Test
    public void hashtableTest() throws InterruptedException {
        final Map<Integer, Integer> map = new Hashtable<>(500000);
        System.out.println("开始测试hashtable-----------------------");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 50; i++) {
            final int j = i;
            new Thread(() -> {
                for (int k = 0; k < 100000; k++) {
                    map.put(j * k, 1);
                }

            }).start();
        }
        long end = System.currentTimeMillis();
        System.out.println("hashtable执行了:" + (end - start));
    }
    @Test
    public void testConcurrentHashMap() throws InterruptedException {
        final Map<Integer,Integer> map = new ConcurrentHashMap<>(500000);
        System.out.println("开始测试ConcurrentHashMap-----------------------");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 50; i++) {
            final int j = i;
            new Thread(()->{
                for (int k = 0;k < 100000;k++){
                    map.put(j*k,1);
                }
            }).start();
        }
        long end = System.currentTimeMillis();
        System.out.println("ConcurrentHashMap执行了:" + (end - start)); // 71ms
    }

}

2、ArrayList和LinkedList性能测试

(1)按顺序添加元素效率

package com.jr.morning;

import org.junit.Test;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

/*
集合的好多面试
1. Hashtable和ConcurrentHashMap性能测试

 */
public class Ch04 {
    @Test
    public void testArrayList() {
        List<Integer> list = new ArrayList<>();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            list.add((int)Math.random()*100);
        }
        long end = System.currentTimeMillis();
        System.out.println("arraylist用时:" + (end - start));
    }

    @Test
    public void testLinkedList() {
        List<Integer> list = new LinkedList<>();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            list.add((int)Math.random()*100);
        }
        long end = System.currentTimeMillis();
        System.out.println("linkedlist用时:" + (end - start));
    }



}

(2)查询效率

 ①for循环实现查询

package com.jr.morning;

import org.junit.Test;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

/*
集合的好多面试
1. Hashtable和ConcurrentHashMap性能测试

 */
public class Ch04 {
    @Test
    public void testArrayList() {
        List<Integer> list = new ArrayList<>();

        for (int i = 0; i < 10000000; i++) {
            list.add((int)Math.random()*100);
        }
        long start = System.currentTimeMillis();
        for (int i = 0; i < list.size(); i++) {
            list.get(i);//千万别打印,电脑可能会崩
        }
        long end = System.currentTimeMillis();
        System.out.println("arraylist用时:" + (end - start));
    }

    @Test
    public void testLinkedList() {
        List<Integer> list = new LinkedList<>();

        for (int i = 0; i < 10000000; i++) {
            list.add((int)Math.random()*100);
        }
        long start = System.currentTimeMillis();
        for (int i = 0; i < list.size(); i++) {
            list.get(i);//千万别打印,电脑可能会崩
        }
        long end = System.currentTimeMillis();
        System.out.println("linkedlist用时:" + (end - start));
    }


}

②用迭代器实现查询

package com.jr.morning;

import org.junit.Test;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

/*
集合的好多面试
1. Hashtable和ConcurrentHashMap性能测试

 */
public class Ch04 {
    @Test
    public void testArrayList() {
        List<Integer> list = new ArrayList<>();

        for (int i = 0; i < 10000000; i++) {
            list.add((int)Math.random()*100);
        }
        long start = System.currentTimeMillis();
        // 用迭代器实现查询
        Iterator<Integer>iterator=list.iterator();
        while (iterator.hasNext()){
            iterator.next();
        }
        long end = System.currentTimeMillis();
        System.out.println("arraylist用时:" + (end - start));
    }

    @Test
    public void testLinkedList() {
        List<Integer> list = new LinkedList<>();

        for (int i = 0; i < 10000000; i++) {
            list.add((int)Math.random()*100);
        }
        long start = System.currentTimeMillis();

        // 用迭代器实现查询
        Iterator<Integer>iterator=list.iterator();
        while (iterator.hasNext()){
            iterator.next();
        }
        long end = System.currentTimeMillis();
        System.out.println("linkedlist用时:" + (end - start));
    }



}

根据上面的结果, 说明数组非常适合进行元素的查询,但是链表就不适合,因为它会从头一个个看,看10000000次,时间就会非常久。

(3)删除效率

package com.jr.morning;

import org.junit.Test;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

/*
集合的好多面试
1. Hashtable和ConcurrentHashMap性能测试

 */
public class Ch04 {
    @Test
    public void testArrayList() {
        List<Integer> list = new ArrayList<>();

        for (int i = 0; i < 10000000; i++) {
            list.add((int)Math.random()*100);
        }
        long start = System.currentTimeMillis();

        // 用迭代器实现查询
        Iterator<Integer>iterator=list.iterator();
        while (iterator.hasNext()){
            // 随机删除
            if(iterator.next() > 500){
                iterator.remove();
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("arraylist用时:" + (end - start));
    }

    @Test
    public void testLinkedList() {
        List<Integer> list = new LinkedList<>();

        for (int i = 0; i < 10000000; i++) {
            list.add((int)Math.random()*100);
        }
        long start = System.currentTimeMillis();

        // 用迭代器实现查询
        Iterator<Integer>iterator=list.iterator();
        while (iterator.hasNext()){
            // 随机删除
            if(iterator.next() > 500){
                iterator.remove();
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("linkedlist用时:" + (end - start));
    }


}

3、测试结果总结

总结数组查询快,插入慢,链表插入快,查询慢
①尾插数组快,链表慢
②遍历,数据快
③头插,链表快,数组慢
④随机删除,如果要过滤,建议用inkedlist
开发中,还是以ArrayList为主,在开发的场景中用得最多
 

三、Stream流式编程

1、概念

JDK8新增的功能---Stream编程,是容器对象功能的增强

Stream 中文称为 “流”,通过将集合转换为这么一种叫做 “流” 的元素序列,通过声明性方式,能够对集合中的每个元素进行一系列并行或串行的流水线操作。

换句话说,你只需要告诉流你的要求,流便会在背后自行根据要求对元素进行处理,而你只需要 “坐享其成”。

2、使用流的三个步骤

1.获取一个数据源
2.执行操作获取想要的结果
3.每次操作,原有的流对象不改变,返回一个新的Stream对象
 

3、Stream的特性

(1)stream不存储数据,一般会输出结果
(2)stream不会改变数据源,通常情况下会生成一个新的集 合
(3)Stream具有延迟执行的特性,只有调用终端操作时,中间操作才 会执行。

四、Stream流式编程使用示例

1、创建流的几种常见方式

(1)用集合方式创建流

package com.jr.morning;

import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;


public class Ch05 {

    @Test
    public void test01() {
        List<String> list = Arrays.asList("a","b","c");
        // 创建一个顺序流
        Stream<String> stream = list.stream();
        // 创建一个并行流
        Stream<String> parallelStream = list.parallelStream();


    }
}

(2)用到静态方法创建流(做个了解即可)

package com.jr.morning;

import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;


public class Ch05 {

    @Test
    public void test01() {

        Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5, 6);

        Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);


    }
}

2、具体案例(具体能干什么)

(1)创建一个person类

对person类中的属性进行生成构造方法,生成set、get方法,生成toString

package com.jr.morning;

public class Person {

    private String name;      // 名字
    private Integer salary;  // 工资
    private Integer age;     // 年龄
    private String gender;  // 姓名
    private String area;    // 地区

    public Person() {
    }

    public Person(String name, Integer salary, Integer age, String gender, String area) {
        this.name = name;
        this.salary = salary;
        this.age = age;
        this.gender = gender;
        this.area = area;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getSalary() {
        return salary;
    }

    public void setSalary(Integer salary) {
        this.salary = salary;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", salary=" + salary +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                ", area='" + area + '\'' +
                '}';
    }
}

(2)测试类Ch06

package com.jsoft.morning;

import org.junit.Before;
import org.junit.Test;

import java.lang.invoke.VarHandle;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Ch06 {

    // 创建一个复杂的集合
    List<Person> personList = new ArrayList<>();
    // 创建一个简单的集合
    List<Integer> simpleList = Arrays.asList(15,22,15,11,33,52,22,14,33,52);

    @Before
    public void before() {
        personList.add(new Person("张三",3000,23,"男","长春"));
        personList.add(new Person("李四",7000,34,"男","西安"));
        personList.add(new Person("王五",5000,22,"女","长春"));
        personList.add(new Person("小明",1000,33,"女","上海"));
        personList.add(new Person("小红",8000,44,"女","北京"));
        personList.add(new Person("小黑",6000,36,"女","南京"));
    }

    @Test
    public void test01(){
        // 打印集合元素
        // 双冒号语法,方法引用
        simpleList.stream().forEach(System.out::println);
        // 其实还可以简化操作
        simpleList.forEach(System.out::println);
    }

    @Test
    public void test02() {
        // 找到第一个元素
        Optional<Integer> first = simpleList.stream().findFirst();

        // 随便找一个
        // 如果没有并行,any也是第一个
        Optional<Integer> any = simpleList.stream().findAny();

        System.out.println("第一个:" + first.get());
        System.out.println("任意一个:" + any.get());
    }

    @Test
    public void test03() {
        // 判断有没有任意一个人年龄大于35岁
        // 任意匹配
        boolean b = personList.stream()
                .anyMatch(item -> item.getAge() > 35);
        System.out.println(b);

        // 判断是不是所有人年龄都大于35岁
        b = personList.stream().allMatch(item -> item.getAge() > 35);
        System.out.println(b);
    }

    @Test
    public void Ch07() {

        List<Integer> collect = simpleList.stream().collect(Collectors.toList());
        System.out.println(collect);
        Set<Integer> collect1 = simpleList.stream().collect(Collectors.toSet());
        System.out.println(collect1);
        Map<Integer, Integer> map = simpleList.stream()
                .collect(Collectors
                        .toMap(item -> item, item -> item + 1));
        System.out.println(map);
    }

    @Test
    public void Ch08() {
        // 统计
        long count = new Random().ints().limit(50).count();
        System.out.println(count);
        OptionalDouble average = new Random().ints().limit(50).average();
        average.ifPresent(System.out::println);
        int sum = new Random().ints().limit(50).sum();
        System.out.println(sum);
    }

    /*
        归约(reduce)缩减,把一个流缩减成一个值,
        可以实现对集合的求和,求乘积,求最值
     */
    @Test
    public void test09(){
        Integer result = simpleList.stream().reduce(1, (n1, n2) -> n1 - n2);
        System.out.println(result);
    }

    @Test
    public void test10(){
        List<String> list = Arrays.asList("A","B","C");
        String string = list.stream().collect(Collectors.joining("-"));
        System.out.println("拼接后的字符串:" + string);
    }

    /*
        分组将集合分为多个map,
        比如员工按性别分组
        员工按薪资是否高于8000分组
     */
    @Test
    public void test11() {
        // 根据工资分组
        Map<Boolean, List<Person>> collect = personList.stream().collect(Collectors.groupingBy(x -> x.getSalary() > 5000));
        System.out.println(collect);
        // 根据性别分组
        Map<String, List<Person>> collect1 = personList.stream().collect(Collectors.groupingBy(Person::getGender));
        System.out.println(collect1);

        // 将员工根据性别分组,再按地区分组
        Map<String, Map<String, List<Person>>> collect2 = personList.stream()
                .collect(Collectors.groupingBy(Person::getGender, Collectors.groupingBy(Person::getArea)));
        System.out.println(collect2);
    }

    /**
     * 筛选
     */
    @Test
    public void test12() {
//        simpleList.stream().filter(item -> item > 17).forEach(System.out::println);

        // 筛选员工中工资大于8000的人,并形成新的集合
        List<Person> collect = personList
                .stream()
                .filter(item -> item.getSalary() > 5000)
                .collect(Collectors.toList());
        System.out.println(collect);
    }

    /**
     * 映射
     * 将一个流的元素按照一定的映射规则映射到另一个流中。
     */
    @Test
    public void test13(){
        // 将员工的工资全部增加1000
//        personList
//                .stream().map(item -> {
//            item.setSalary(item.getSalary() + 1000);
//            return item;
//        }).forEach(System.out::println);
        List<StringBuilder> collect = simpleList.stream().map(item -> {
            StringBuilder strb = new StringBuilder();
            strb.append(item);
            return strb;
        }).collect(Collectors.toList());
        System.out.println(collect);
    }

    /**
     * 排序:sorted
     * 自然排序:
     * 临时排序:
     */
    @Test
    public void test14() {
        // 将员工按工资由低到高排序(自然排序--升序)
        List<String> collect = personList.stream()
                .sorted(Comparator.comparing(Person::getSalary))
                .map(Person::getName)
                .collect(Collectors.toList());
        System.out.println(collect);
        // 按照员工工资的降序
        List<String> collect1 = personList
                .stream()
                .sorted(Comparator.comparing(Person::getSalary).reversed())
                .map(Person::getName)
                .collect(Collectors.toList());
        System.out.println(collect1);
    }

    /**
     * peek操作,调试
     */
    @Test
    public void test15(){
        // 在stream中调试,stream不支持debug
        List<Person> collect = personList.stream()
                .filter(item -> item.getSalary() > 5000)
                .peek(System.out::println)
                .collect(Collectors.toList());
        System.out.println(collect);
    }

    /**
     * 其他操作:合并、去重、限制、跳过。。。。
     */
    @Test
    public void test16() {
        /*
            distinct:去重
            skip:跳过几个数据
            limit:限制使用几个数据
         */
        simpleList
                .stream()
                .distinct()
                .skip(2)
                .limit(6)
                .forEach(System.out::println);


    }

}

3、具体案例分段解析其使用方法

(1)打印集合元素

其中用到forEach();方法,括号里写的就是我们想要实现的功能,括号里out后面不能用      得用双冒号::语法,进行方法引用。

        simpleList.stream().forEach(System.out::println);

其实还可以简化操作:


   simpleList.forEach(System.out::println);

(2)查找元素

①找到第一个元素


        Optional<Integer> first = simpleList.stream().findFirst();

        System.out.println("第一个:" + first.get());
 

②随便找一个元素
 运行结果显示的也是第一个元素15,因为单线程没有并行,any找到的元素也是第一个元素。


        Optional<Integer> any = simpleList.stream().findAny();
        System.out.println("任意一个:" + any.get());

(3)判断元素

①anyMatch();方法---任意匹配。

括号中应该写什么?函数式接口,传入一个参数,传入的参数代表的就是要判断的类的对象,返回值是Boolean类型。(allMatch();方法也是如此)
比如这里item代表的就是Person类,item.getAge()就是表示调用Person类的年龄属性

        // 判断有没有任意一个人年龄大于35岁,以前的做法是遍历集合然后进行判断
        // anyMatch();方法---任意匹配。
 
        boolean b = personList.stream().anyMatch(item -> item.getAge() > 35);
        System.out.println("有没有任意一个人年龄大于35岁"+b);

   

② allMatch();方法---全部匹配。

     // 判断是不是所有人年龄都大于35岁
        //allMatch();方法---全部匹配。
        b = personList.stream().allMatch(item -> item.getAge() > 35);
        System.out.println("是不是所有人年龄都大于35岁"+b);

(4)收集元素

 ① 判断有没有任意一个人年龄大于35岁,收集起来
  collect();方法---收集


        List<Integer> collect = simpleList.stream().collect(Collectors.toList());
        System.out.println(collect);
        Set<Integer> collect1 = simpleList.stream().collect(Collectors.toSet());
        System.out.println(collect1);
        Map<Integer, Integer> map = simpleList.stream().
        collect(Collectors.toMap(item -> item, item -> item + 1));
        System.out.println(map);

collect();方法收集集合中的元素,想要输出可以用joining(""));分隔元素

 List<String> list = Arrays.asList("A","B","C");
        String string = list.stream().collect(Collectors.joining("-"));
        System.out.println("拼接后的字符串:" + string);

(5)统计

①输出50,表示50这有个随机数

   long count = new Random().ints().limit(50).count();
        System.out.println(count);

②输出50个随机数的平均数

  OptionalDouble average = new Random().ints().limit(50).average();
        average.ifPresent(System.out::println);

③输出50个随机数的总和

 int sum = new Random().ints().limit(50).sum();
        System.out.println(sum);

(6)归约(reduce)缩减

归约(reduce)缩减,把一个流缩减成一个值,可以实现对集合的求和,求乘积,求最值,求减...

  // 求减
        Integer result1 = simpleList.stream().reduce(1, (n1, n2) -> n1 - n2);
        System.out.println(result1);
        // 求乘积
        Integer result2 = simpleList.stream().reduce(1, (n1, n2) -> n1 *n2);
        System.out.println(result2);
        // 求和
        Integer result3 = simpleList.stream().reduce(1, (n1, n2) -> n1 + n2);
        System.out.println(result3);

(7)分组

分组将集合分成多个map, 用到 collect();方法---收集

   // 根据工资分组
        Map<Boolean, List<Person>> collect = personList.stream().collect(Collectors.groupingBy(x -> x.getSalary() > 5000));
        System.out.println(collect);
        // 根据性别分组
        Map<String, List<Person>> collect1 = personList.stream().collect(Collectors.groupingBy(Person::getGender));
        System.out.println(collect1);

        // 将员工根据性别分组,再按地区分组
        Map<String, Map<String, List<Person>>> collect2 = personList.stream()
                .collect(Collectors.groupingBy(Person::getGender, Collectors.groupingBy(Person::getArea)));
        System.out.println(collect2);

(8)筛选

①筛选集合中数大于17的数字,并形成新的集合


 simpleList.stream().filter(item -> item > 17).forEach(System.out::println);

② 筛选员工中工资大于8000的人,并形成新的集合


        List<Person> collect = personList
                .stream()
                .filter(item -> item.getSalary() > 5000)
                .collect(Collectors.toList());
        System.out.println(collect);

(9)映射

将一个流的元素按照一定的映射规则映射到另一 个流中。
将员工的工资全部增加1000


        personList
                .stream().map(item -> {
            item.setSalary(item.getSalary() + 1000);
            return item;
        }).forEach(System.out::println);

(10)排序---sorted

①自然排序,默认就是升序

 将员工按工资由低到高排序

 
        List<String> collect = personList.stream()
                .sorted(Comparator.comparing(Person::getSalary))
                .map(Person::getName)
                .collect(Collectors.toList());
        System.out.println(collect);

②降序

 按照员工工资的降序


        List<String> collect1 = personList
                .stream()
                .sorted(Comparator.comparing(Person::getSalary).reversed())
                .map(Person::getName)
                .collect(Collectors.toList());
        System.out.println(collect1);

知识点补充请参考文章:https://blog.csdn.net/qq_21918021/article/details/88824335

五、JDK8函数式接口

1、Consumer<T>

消费者 void accept(T t)

 2、 Supplier

供应商 T get()

 3、Function

 R apply(T t),将一个数据转化成另一个数据

 4、Predicate

断言,boolean test(T t),判断返回值是boolean

六、 JDK8新增接口

 1.函数式接口
 2.箭头函数(lambda表达式),不是java特有的。
 3.Optional类
 4.断言
 5.Stream编程

七、Java---IO 流

1、概念

IO是Input、Output两个首单词的缩写,输入输出流,是对于文件的操作

2、Input、Output

java.io包下的类是对input输入、output输出的支持。计算机的输入输出都是通过二进制完成,0和1。

input输入:把数据从物理内存加载到运行内存(读文件)

output输出:把数据从运行内存写到物理内存(写文件)

(1)本地传输:

把C盘的文件读出来,读到内存当中。把内存中数据保存到D盘,写到D盘。

 (2)网络传输:

从我的电脑传输文件到你的电脑,从我的C盘中读取数据,先加载到我的内存中,然后通过网络传输(网络IO)传到你的内存里,再从你的内存中通过输出传到你的C盘。

(3) 对象传输:

在我的内存中,有个方法区,方法区里有个张三常量。栈有个对象User。有个推内存,里面有个name属性。name属性会指向方法区的张三常量,推内存的地址会指向User对象。最终传输的过程,会先加载成二进制,然后有两种方式,一种是写进我的C盘,或者通过网络传输传到其他电脑。

3、工具类:File操作文件的类

在真正学IO流之前,先学一个工具类File--操作文件的类。

(1)文件的路径

①文件路径的分隔符:

正斜杠:左斜杠,撇,/
反斜杠:右斜杠,捺,\

Unix或者Linux中,路径的分隔采用正斜杠 /。

windows中,路径分隔采用反斜杠\其实用正斜杠/也是好使的。

在Java中,反斜杠\ 代表转义,如果要打印输出文件地址,用正斜杠/或者得用两个反斜杠\\

 ②在java中除了用斜杠输出打印文件地址,File类中还定义了路径分隔符的常量File.separatorFile.pathSeparator,它们分别对象代表的是\和;

这两个常量会自动识别操作系统,如果是在window系统下生成的就是反斜杠\,如果是Linux系统下生成的就是正斜杠/。

 (2)File类的构造器

 有四种构造方式,常用的是前三种。为什么要整出三个构造器?为的就是尽量不要出现拼接字符串

package com.jr.afternoon;

import java.io.File;

/*
file类的构造器
 */
public class Ch02 {
    public static void main(String[] args) {

        //第一种 是最简单的一种构造器。File就代表了当前的目录
        File file1 = new File("E:\\jiruan\\workplace");
        System.out.println("file1="+file1);
        // 第二种  可以传两个,前面是父级目录,后面是子级目录
        File file2 = new File("E:\\jiruan\\workplace","java");
        System.out.println("file2="+file2);
        //第三种   file1是父级目录
        File file3 = new File(file1,"Java");
        System.out.println("file3="+file3);
    }
}

八、文件的操作 

1、创建文件

创建文件命令----file.createNewFile();

createNewFile--新建文件是不会覆盖已有的文件

使用这个命令的时候会抛出异常,因为程序怕系统没有父级菜单,无法创建后续文件。

package com.jr.afternoon;

import java.io.File;
import java.io.IOException;

/*
文件的操作
createNewFile--新建文件是不会覆盖已有的文件
绝对路径:以盘符开头
相对路径:没有指定的盘符开头
 */
public class Ch03 {
    public static void main(String[] args) {
        File file = new File("e:\\java.txt");
        try {
            file.createNewFile();
            System.out.println("创建文件成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

2、删除文件

删除文件命令--- boolean delete = file.delete();

使用这个命令的时候不会抛出异常,因为如果存在就删除,如果不存在就拉倒。File类的删除是不走回收站。

import java.io.File;


public class Ch03 {
    public static void main(String[] args) {
//删除文件
        File file = new File("e:\\java.txt");
        boolean delete = file.delete();
        System.out.println(delete);
    }

}

3、创建和删除文件夹

创建文件夹的命令

boolean mkdir = file.mkdir();---创建一级文件夹

boolean mkdir = file.mkdirs();---创建多级文件夹(多级的也可以只创建一级)

删除文件夹的命令

file.delete();

package com.jr.afternoon;

import java.io.File;

public class Ch03 {
    public static void main(String[] args) {
        //创建文件夹
        File file = new File("e:/a");
        boolean mkdir = file.mkdir();
        System.out.println(mkdir);

    }

}

4、创建文件夹以及此文件夹下的文件

没有直接的命令,需要封装工具类。

package com.jr.afternoon;


import java.io.File;
import java.io.IOException;
/*
   创建文件夹以及此文件夹下的文件,需要封装工具类

   分析:
   传入可能有三种方式:

  1.传入的路径是一个e:/a/b/c/bbb. txt
  2.传入的路径是一个e:\\a\\bc\\aaa. txt
  3.传入的路径是一个e:\a\b\c\aaa. txt
    */
public class FileUtil {
    public static boolean createDirAndFile(String filepath) throws IOException {
        File file = null;
        if(filepath.contains("/")){
            if(filepath.contains("\\")){
                throw new RuntimeException("路径不合法");
            }else {
                // e:\\a\\b\\c\\a.txt
                int index = filepath.lastIndexOf("/");
                String filename = filepath.substring(index,filepath.length());
                filepath = filepath.substring(0, index+ 1);
                file = new File(filepath);
                file.mkdirs();
                // 创建文件
                File newFile = new File(filepath,filename);
                newFile.createNewFile();
                return true;
            }
        }
        if(filepath.contains("\\")){
            if(filepath.contains("/")){
                throw new RuntimeException("路径不合法");
            }else {
                // e:\\a\\b\\c\\a.txt
                int index = filepath.lastIndexOf("\\");
                String filename = filepath.substring(index,filepath.length());
                filepath = filepath.substring(0, index+ 1);
                file = new File(filepath);
                file.mkdirs();
                // 创建文件
                File newFile = new File(filepath,filename);
                newFile.createNewFile();
                return true;
            }
        }

        throw new RuntimeException("路径不合法");
    }

    public static void main(String[] args) {

        try {
            createDirAndFile("d:\\a\\b\\c\\a.txt"); // 路径
            System.out.println("文件创建成功...");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

5、其他常见命令

①判断文件是否已经存在---file. exists()
②判断是否是文件夹(目录) ---file. isDirectory()
③判断是否是文件---file. isFile()
④判断是否是隐藏文件---file. isHidden()
⑤判断是否是绝对路径---file. isAbsolute()
绝对路径:以盘符开头,比如: e:/aaa. txt是绝对路径,aaa. txt不是绝对路径。
相对路径:相对于当前工程,没有指定的盘符开头

 

package com.jr.afternoon;

import org.junit.Test;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;

public class Ch04 {
    @Test
    // 判断文件是否已经存在---file.exists()
    public void test1() {
        File file = new File("e:/aaa.txt");
        System.out.println(file.exists());
    }

    @Test
    // 判断文件是否已经存在---file.exists()
    //判断是否是文件夹(目录)---file.isDirectory()
    // 判断是否是文件---file.isFile()
    // 判断是否是隐藏文件---file.isHidden()
    // 判断是否是绝对路径---file.isAbsolute()
    // 绝对路径:以盘符开头,比如 :e:/aaa.txt是绝对路径,aaa.txt不是绝对路径。
    //相对路径:相对于当前工程,没有指定的盘符开头
    public void test2() {
        File file = new File("e:/aaa.txt");
        System.out.println(file.isAbsolute());

        System.out.println(file.isDirectory());
        System.out.println(file.isFile());
        System.out.println(file.isHidden());
    }

    // 文件列表的操作
    @Test
    public void test3() {
        File file = new File("E:\\jiruan\\workplace");
        // 拿到当前目录下的所有文件名---file.list();
        String[] fileNames = file.list();
        System.out.println(Arrays.toString(fileNames));
        // 拿到当前目录下的所有对象---file.list();
    }

    @Test
    public void test4() {
        File file = new File("E:\\jiruan\\workplace");
        // 拿到当前目录下的所有对象---file.list();
        File[] files = file.listFiles();
        System.out.println(Arrays.toString(files));

    }
   
}


网站公告

今日签到

点亮在社区的每一天
去签到