2022-08-08 第二小组 张明旭 Java学习记录

目录

心情日记

重点归纳

知识点记录

JUnit单元测试

 JUnit单元测试的好处

 jar包

 测试方法

JUnit断言:assert

JUnit注解

命名规范

集合的好多面试题

JDK8新增法Stream编程(流式编程)

Stream具体能干什么

JDK8新增的函数式接口

JDK8之后

JDK8新增

Java的IO流

工具类:File----操作文件的类

1.文件的路径

2.File类的构造器

3.文件的操作

练习


心情日记

又是新的一周,上周日考试分还是低,平常觉得自己写的代码还挺好,一到考试就不行,继续努力!!

重点归纳

1.JUnit单元测试

2.jar包、Test注解

3.集合的好多面试题

4.Stream编程(流式编程)

5.Stream具体能干什么

6.工具类:File----操作文件的类

(1)文件的路径

(2)File类的构造器

(3)文件的操作

知识点记录

JUnit单元测试

JUnit是一个Java语言单元测试框架
   刚入职可能主要做的就是单元测试,很重要

   以前我们都用主方法测试代码,其实可以用JUnit,以后用JUnit代替主方法

 JUnit单元测试的好处

1.可以书写一系列的测试方法,对项目所有的接口或者方法进行单元测试
2.启动后,自动化测试
3.只需要查看最后的结果
4.每个单元测试的用例相对独立,由JUnit启动
5.添加,删除,屏蔽测试方法

 jar包

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

Test注解是JUnit提供的一个单元测试注解
如果你的工程没有导入JUnit大jar包,Test注解是不认识的
建议用JUnit4jar包。

 测试方法

1.不能有返回值
2.不能有参数列表
3.必须有Test注解
4.JUnit4中必须写public
   JUnit5中可以不写,默认public

    //JUnit单元测试
    //Test注解
    @Test
    //测试方法
    public void  test01(){
        System.out.println("hello junit01");
    }

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

JUnit断言:assert

JUnit所有的断言都包含在一个类中---Assert类
这个类提供了很多有用的断言来编写测试用例


只有失败的断言才会被记录

1.assertEquals():检查两个变量或等式是否向相等
2.assertTrue():检查条件是否为真
3.assertFalse():检查条件是否为假
4.assertNotNull():检查条件是否不是空
5.assertNull():检查条件是否为空

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

    @Test
    public void test01(){
        //类名.静态方法
        Assert.assertTrue(false);
    }

JUnit注解

1.Test
2.Before:在测试方法之前执行的方法
3.After:在测试方法之后执行的方法

命名规范

单元测试类的命名:被测试的类的类名 + Test

测试方法的命名:test + 被测试方法的方法名

    @Test
  public void test01(){
        System.out.println("test01方法执行。。。");
  }

    @Test
    public void test02(){
        System.out.println("test02方法执行。。。");
    }
    @Before
    public void testBefore(){
        System.out.println("before方法执行。。。");
    }

    @After
    public void testAfter(){
        System.out.println("after方法执行。。。");
    }

集合的好多面试题

1.Hashtable和ConcurrentHashMap(单线程)性能测试
    ConcurrentHashMap(单线程):专门应付高并发的类

2.ArrayList和LinkedList性能测试

数组查询快,插入慢;链表插入快,查询慢
1.尾插数组快,链表慢
2.遍历数组快
3.头插,链表快,数组慢
4.随机删除,如果要过滤(查多少个数大于多少)的话,建议用链表linkedlist

开发中,还是arraylist为主

 @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));
    }

测试高并发
    Hashtable和ConcurrentHashMap
    我们测试开辟50个线程,每个线程相机和中put(添加) 100000个元素,
    测试一下两个类所需时间

    @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);
        // 计数器
//        final CountDownLatch countDownLatch = new CountDownLatch(50);
        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);
                }
                // 记录添加的数据次数
//                countDownLatch.countDown();
            }).start();
        }
//        countDownLatch.await();
        long end = System.currentTimeMillis();
        System.out.println("ConcurrentHashMap执行了:" + (end - start));//超快
    }

JDK8新增法
Stream编程(流式编程)

容器对象功能的增强

我们可以先将流看成流水线,这个流水线是处理数据的流水线

当我们使用一个流的时候,通常有三个步骤:
1.获取一个数据源
2.执行操作获取想要的结果
3.每次操作,原有的流对象不改变,返回一个新的Stream对象

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

可以用集合创建流,也可以用Stream.of、Stream.iterate静态方法创建流

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

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

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

Stream具体能干什么

(建立一个Person类为例,在其基础上实验Stream的功能)
对集合的元素进行操作,可以获取指定规则的元素信息(例:判断有无大于35的数)

​
//创建一个复杂的集合

    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);
    }


​

test9:
    规约(reduce)缩减:把一个流缩减成一个值,可以实现求和、求乘积、求最值等
(规约是自己定义的)(了解)

    @Test
    public void test09(){
        Integer result = simpleList.stream().reduce(1, (n1, n2) -> n1 - n2);
        System.out.println(result);
    }

test10:
     Collector.joining("")将元素用”“里的字符分来

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

test11:
       分组将集合分为多个map,比如员工按性别分组,按薪水是否大于8000分组
       (Boolean类型:true一组、false一组)

    @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);
    }   

test12:(重要)
       过滤、筛选:filter

    @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);
    }

test13:(重要)
    映射:将一个流的元素,按照一定的映射规则映射到另一个流中

@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);
    }

test14:(重要)
     排序:sorted,只要见到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);
    }

test15:
    peek操作:调试。
    在Stream中调试,Stream不支持debug

  @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);
    }

test16:
    其他操作:合并、去重、限制、跳过。。。。。。
     去重:distinct
     跳过:skip,跳过几个数据
     限制:限制使用几个数据

@Test
    public void test16() {
        simpleList
                .stream()
                .distinct()
                .skip(2)
                .limit(6)
                .forEach(System.out::println);

    }

Person类:

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 + '\'' +
                '}';
    }
}

JDK8新增的函数式接口

1.Consumer<>消费者:void accept(T t)
2.Supplier<>供应商:给东西get()
3.Function:R apply(T t),将一个数据转化成另一个数据
4.Predicate断言:boolean test(T t),判断返回值是boolean

JDK8之后

Optional类:解决null问题

    @Test
    public void test01() {
        String str = null;

        // 返回一个对象值为空的Optional对象
        Optional<String> empty = Optional.empty();

        Optional<String> hello = Optional.of(str);

        Optional<String> o = Optional.ofNullable(null);

        System.out.println(o.get());
    }

JDK8新增

1.函数是接口(必须会)
2.箭头函数(必须会)lambda表达式,不是Java特有的,Java里的只是阉割版
3.Optional类
4.断言
5.Stream编程

IO流的前提知识:一些工具类

Java的IO流

IO:(Input、Output)
Input流:把数据从物理内存加载到 运行内存(读文件)
Output流:把数据从运行文件写到物理内存(写文件)

用Java.IO包下的类实现输入输出

计算机的输入输出都是通过二进制完成
   0/1

工具类:File----操作文件的类


1.文件的路径

路径分隔符:
    正斜杠:左斜杠 /
    反斜杠:右斜杠 \

  在Unix/Linux,路径的分隔采用正斜杠
  在windows中,路径分隔采用反斜杠 \
  在Java中正反斜杠都好使

  在Java中 \ 具有另一种意义:转义
  所以如果想要写路径,要写两个 \\

  在File类中定义了路径分隔符常量,自动识别操作系统
  File.separator = \
  File.pathSeparator = ;

    public static void main(String[] args) {
//        System.out.println("\t");
//        System.out.println("E:\\");
//        System.out.println("E:/workspace");
        System.out.println(File.separator);
        System.out.println("e:" + File.separator + "workspace");
        System.out.println(File.pathSeparator);
    }

2.File类的构造器

文件的路径不要拼接,看实际场景选择构造器

    public static void main(String[] args) {
        // file就代表了当前的目录
        File file1 = new File("E:\\workspace\\idea");
        System.out.println("file1 = " + file1);
        File file2 = new File("E:\\workspace\\idea","aaa");
        System.out.println("file2 = " + file2);
        File file3 = new File(file1,"aaa");
        System.out.println("file3 = " + file3);
    }

3.文件的操作

test01

创建文件时要抛异常(未找到目录异常)

createNewFile:创建新的文件,返回值boolean类型 */

@Test

public void test01() {

// 创建一个文件

File file1 = new File("e:\\aaa.txt");

try {

file1.createNewFile();

System.out.println("文件创建成功...");

} catch (IOException e) {

e.printStackTrace();

}

}

test02

delete 删除文件时File类的删除不走回收站,直接删除

@Test

public void test02(){

File file = new File("e:\\aaa.txt");

// 如果存在就删除,如果不存在就拉倒

// file类的删除是不走回收站

boolean delete = file.delete();

System.out.println(delete); }

test03

文件夹(目录) mkdir:创建新的文件夹。返回值boolean类型

mkdirs:创建多级文件夹。返回值boolean类型

mkdirs也可以创建一层,所以开发中一般用mkdirs

@Test

public void test03(){

File file = new File("e:/hello");

boolean mkdir = file.mkdir();

// file.delete();

// 删除文件夹

// delete:不走回收站

boolean b = file.mkdirs();

System.out.println(b);

try {

file.createNewFile();

System.out.println("创建成功...");

} catch (IOException e) {

throw new RuntimeException(e);

}

}

test04

新建某一个路径下的某一个文件,且这个路径不存在,没有这个方法,需要我们封装工具类

思想1:

创建工具类里全是静态方法

思想2:

创建实体类

@Test

public void test04() throws IOException {

File file = new File("e:/hello/abc.txt");

// file.mkdirs();

// file.mkdir();

file.createNewFile(); }

封装类FileUtil:

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

public class FileUtil {
    public static void createFile(File file){
        if (file.exists()){
            System.out.println("文件存在");
        } else {
            System.out.println("文件不存在,创建它");
            if (!file.getParentFile().exists()){
                file.getParentFile().mkdirs();
                System.out.println("创建完成!");
            }
            try {
                file.createNewFile();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

//    public void Creat(String pathname){
//        createFile(new File(pathname));
//    }

    public static void main(String[] args) {
        String pathName = "D:/hello/abc.txt";
        createFile(new File(pathName));
    }
}

test05

File类中判断方法:

1.exists:判断文件是否存在

2.isAbsolute:判断文件是不是绝对路径

绝对路径:以盘符开头的路径

相对路径:没有指定的盘符的路径。

创建时直接创建在当前工程目录下

3.isDirectory:判断是不是目录

4.isFile:是不是文件

5.isHidden:判断是不是隐藏文件

@Test

public void test05() throws IOException {

File file = new File("e:/aaa.txt");

File file2 = new File("E:\\idea");

System.out.println(file.isHidden());

System.out.println(file.isFile());

System.out.println(file2.isDirectory());

System.out.println(file.isAbsolute());

// 判断文件是否存在

System.out.println(file.exists());

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

System.out.println(file.createNewFile());

System.out.println(file2.mkdirs());

}

test06

File类中的方法:

1.getAbsolutePath:

2.getAbsoluteFile:

3.getParent:

4.getParentFile:

5.getName

6.getPath

7.lastModified

8.length

@Test

public void test06() {

File file = new File("d:/123.txt");

File file1 = new File("bbb.txt");

System.out.println(file.getAbsolutePath());

System.out.println(file1.getAbsolutePath());

// 获取对应的相对路径的那个对象

File absoluteFile = file1.getAbsoluteFile();

// System.out.println(file.getParent());

File parentFile = file.getParentFile();

System.out.println(file.getName());

System.out.println(file1.getPath());

System.out.println(new Date(file.lastModified()));

System.out.println(file.length());

// 剪切粘贴 移动 file.renameTo(new File("d:\\aaa.txt"));

}

test07

文件夹列表的操作方法

1.list:获取当前文件夹下所有的文件夹的名,数组形式

2.listFiles:获取File形式,数组形式

@Test

public void test07() {

File file = new File("E:\\workspace");

String[] fileNames = file.list();

// System.out.println(Arrays.toString(fileNames));

File[] files = file.listFiles();

System.out.println(Arrays.toString(files));

}

 @Test
    public void test08() {
        File file = new File("D:\\QQ");
        File[] files = file.listFiles((f) -> {
            if (f.isFile()) {
                return true;
            }
            return false;
        });
        System.out.println(Arrays.toString(files));
        String[] list = file.list((dir, name) -> {
            if(dir.isDirectory()){
                return true;
            }
//            if (name.endsWith("xml")) {
//                return true;
//            }
            return false;
        });
        System.out.println(Arrays.toString(list));
    }

练习

输入指定的磁盘名:直接进入到磁盘,
输入mkdir,创建目录
输入rd,删除文件
输入cnf:创建文件
输入dir:遍历当前目录的文件

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Scanner;

public class CMD {

    //定义一个静态变量储存目录的路径
    private static String M;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        main:
        while (true) {
            M = null;
            System.out.println("请输入磁盘:");
            String Pan = sc.next();

            //以路径的方式存储盘
            String Pan1 = Pan + ":\\";

            File file = new File(Pan1);
            if (file.exists()) {
                System.out.println(file.getPath());
                System.out.println("磁盘打开成功!");
            }else {
                System.out.println("没有此盘符重新输入:");
                continue main;
            }
            CMD:while (true) {
                System.out.println("请输入要进行的操作:1.mkdirs(创建目录)/t2.cnf(创建文件)/t3.rd(删除文件)/t4.dir(遍历当前目录的文件)/t5.cd(换磁盘)");
                String flag = sc.next();
                //重新打开磁盘时,清空目录路径,便于创建新的目录
                switch (flag) {
                    case "mkdirs":
                        System.out.println("请输入目录名:");
                        //盘符加目录的路径
                        M = Pan1 + sc.next();
                        File file1 = new File(M);
                        //创建目录
                        if (!file1.exists()) {
                            file1.mkdirs();
                        } else {
                            System.out.println("当前目录已存在!");
                        }
                        continue CMD;
                    case "cnf":
                        System.out.println("请输入文件名:");
                        //目录加文件的路径
                        File file2 = new File(M + "\\" + sc.next());
                        //创建文件
                        try {
                            file2.createNewFile();
                            System.out.println("创建成功!");
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        continue CMD;
                    case "rd":
                        System.out.println("请输入要删除文件名:");
                        //目录加文件的路径
                        File file3 = new File(M + "\\" + sc.next());
                        //删除文件
                        if (file3.exists()) {
                            file3.delete();
                            System.out.println("删除成功!");
                        } else {
                            System.out.println("没有找到文件!");
                        }
                        continue CMD;
                    case "dir":
                        //遍历目录所有文件
                        File file4 = new File(M);
                        String[] list = file4.list();
                        if (list.length != 0) {
                            System.out.println(Arrays.toString(list));
                        }else {
                            System.out.println("文件夹为空!");
                        }
                        continue CMD;
                    case "cd":
                        continue main;
                    default:
                        break;
                }
            }
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值