JAVA实践记录

  1. LocalDate和LocalDateTime  使用说明

  LocalDateLocalDateTime是Java 8中引入的日期和时间类,用于处理日期和时间相关的操作。它们提供了简洁、易读和线程安全的方法来处理日期和时间。

  1. LocalDate表示日期,包含年、月、日。它没有时区和时间信息。

    • 创建LocalDate对象:可以使用LocalDate.now()获取当前日期,也可以使用LocalDate.of()指定年、月、日创建日期对象。
    • 常用方法:
      • getYear()getMonthValue()getDayOfMonth():获取年、月、日的值。
      • plusDays()minusDays():增加或减少指定天数。
      • isBefore()isAfter():比较日期的先后顺序。
      • format():格式化日期为字符串。
  2. LocalDateTime表示日期和时间,包含年、月、日、时、分、秒。它也没有时区信息。

    • 创建LocalDateTime对象:可以使用LocalDateTime.now()获取当前日期和时间,也可以使用LocalDateTime.of()指定年、月、日、时、分、秒创建日期时间对象。
    • 常用方法:
      • getYear()getMonthValue()getDayOfMonth():获取年、月、日的值。
      • getHour()getMinute()getSecond():获取时、分、秒的值。
      • plusDays()minusDays():增加或减少指定天数。
      • isBefore()isAfter():比较日期时间的先后顺序。
      • format():格式化日期时间为字符串。

下面是使用LocalDateLocalDateTime的示例:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

// 创建 LocalDate 对象
LocalDate currentDate = LocalDate.now();
LocalDate specificDate = LocalDate.of(2023, 9, 27);

// 获取日期的年、月、日
int year = currentDate.getYear();
int month = currentDate.getMonthValue();
int day = currentDate.getDayOfMonth();

// 增加或减少天数
LocalDate futureDate = currentDate.plusDays(7);
LocalDate pastDate = currentDate.minusDays(3);

// 比较日期的先后顺序
boolean isBefore = currentDate.isBefore(specificDate);
boolean isAfter = currentDate.isAfter(specificDate);

// 格式化日期为字符串
String formattedDate = currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

// 创建 LocalDateTime 对象
LocalDateTime currentDateTime = LocalDateTime.now();
LocalDateTime specificDateTime = LocalDateTime.of(2023, 9, 27, 10, 30, 0);

// 获取日期时间的年、月、日、时、分、秒
int year = currentDateTime.getYear();
int month = currentDateTime.getMonthValue();
int day = currentDateTime.getDayOfMonth();
int hour = currentDateTime.getHour();
int minute = currentDateTime.getMinute();
int second = currentDateTime.getSecond();

// 增加或减少天数
LocalDateTime futureDateTime = currentDateTime.plusDays(7);
LocalDateTime pastDateTime = currentDateTime.minusDays(3);

// 比较日期时间的先后顺序
boolean isBefore = currentDateTime.isBefore(specificDateTime);
boolean isAfter = currentDateTime.isAfter(specificDateTime);

// 格式化日期时间为字符串
String formattedDateTime = currentDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

以上示例演示了如何使用LocalDateLocalDateTime进行日期和时间的操作,包括创建对象、获取值、增加或减少天数、比较先后顺序以及格式化为字符串。

DateTimeFormatter使用说明

DateTimeFormatter是Java 8中引入的日期时间格式化类,用于将日期时间对象格式化为字符串,或者将字符串解析为日期时间对象。

DateTimeFormatter提供了一系列预定义的格式化模式,可以根据需要选择合适的模式进行格式化。以下是一些常用的格式化模式:

  • yyyy:四位数的年份,如:2023
  • MM:两位数的月份,如:09
  • dd:两位数的日期,如:27
  • HH:24小时制的小时,如:10
  • mm:分钟,如:30
  • ss:秒,如:00
  • S:毫秒,如:123
  • E:星期几的缩写,如:Wed
  • EEE:星期几的简写,如:Wed
  • EEEE:星期几的全称,如:Wednesday

以下是使用DateTimeFormatter的示例:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

LocalDateTime currentDateTime = LocalDateTime.now();

// 格式化为字符串
String formattedDateTime = currentDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(formattedDateTime); // 输出:2023-09-27 10:30:00

// 解析字符串为日期时间对象
String dateTimeString = "2023-09-27 10:30:00";
LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(parsedDateTime); // 输出:2023-09-27T10:30:00

        在上面的示例中,我们首先使用DateTimeFormatter.ofPattern()方法创建了一个格式化模式,然后通过format()方法将日期时间对象格式化为字符串。接着,我们使用parse()方法将字符串解析为日期时间对象。

        需要注意的是,DateTimeFormatter是线程安全的,可以在多个线程中共享使用。因此,可以将其定义为静态常量,以便在整个应用程序中重复使用。

        Set应用场景说明

   Set是Java中的一种集合类型,它是一种无序、不重复的集合。Set的应用场景和举例如下:

  1. 去重:Set集合中的元素是不重复的,可以用于去除重复的元素。例如,从一个数组中去除重复的元素:

    Integer[] numbers = {1, 2, 3, 4, 5, 2, 3, 1};
    Set<Integer> uniqueNumbers = new HashSet<>(Arrays.asList(numbers));
    System.out.println(uniqueNumbers); // 输出:[1, 2, 3, 4, 5]
    
  2. 集合运算:Set提供了一些集合运算的方法,如并集、交集和差集。例如,求两个集合的交集:

    Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
    Set<Integer> set2 = new HashSet<>(Arrays.asList(4, 5, 6, 7, 8));
    Set<Integer> intersection = new HashSet<>(set1);
    intersection.retainAll(set2);
    System.out.println(intersection); // 输出:[4, 5]
    
  3. 存储无序的元素:Set是无序的,可以用于存储不需要按特定顺序访问的元素。例如,存储一组学生的姓名:

    Set<String> students = new HashSet<>();
    students.add("Alice");
    students.add("Bob");
    students.add("Charlie");
    students.add("Alice");
    System.out.println(students); // 输出:[Alice, Bob, Charlie]
    
  4. 判断元素是否存在:Set提供了高效的元素查找操作,可以快速判断一个元素是否存在于集合中。例如,判断一个数字是否在集合中:

    Set<Integer> numbers = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
    boolean contains = numbers.contains(3);
    System.out.println(contains); // 输出:true
    

总之,Set适用于需要存储无序、不重复元素,并且需要高效地进行元素查找和集合运算的场景。

TreeSet 和 LinkedHashSet 应用场景说明

TreeSetLinkedHashSetSet接口的两个实现类,它们分别具有不同的特点和适用场景。

  1. TreeSet

    • 特点:TreeSet是基于红黑树实现的有序集合,它会对元素进行自然排序或者根据指定的比较器进行排序。因此,TreeSet中的元素是有序的,可以按照特定的顺序进行遍历。
    • 适用场景:当需要对集合中的元素进行排序,并且希望能够按照排序顺序进行遍历时,可以使用TreeSet。它适用于需要有序存储元素的场景。
    • 举例:
      Set<Integer> numbers = new TreeSet<>();
      numbers.add(5);
      numbers.add(3);
      numbers.add(1);
      numbers.add(4);
      numbers.add(2);
      System.out.println(numbers); // 输出:[1, 2, 3, 4, 5]
      
  2. LinkedHashSet

    • 特点:LinkedHashSet是基于哈希表和链表实现的有序集合,它保持了元素插入的顺序。因此,LinkedHashSet中的元素是按照插入顺序进行遍历的。
    • 适用场景:当需要保持元素的插入顺序,并且不需要对元素进行排序时,可以使用LinkedHashSet。它适用于需要保持元素插入顺序的场景。
    • 举例:
      Set<String> names = new LinkedHashSet<>();
      names.add("Alice");
      names.add("Bob");
      names.add("Charlie");
      names.add("Alice");
      System.out.println(names); // 输出:[Alice, Bob, Charlie]
      

        总之,TreeSet适用于需要对元素进行排序的场景,而LinkedHashSet适用于需要保持元素插入顺序的场景。根据具体的需求选择合适的实现类可以提高代码的可读性和性能。

        使用Lambda表达式编写一个程序,自动监控指定文件夹中的文件,当有新文件出现时,自动将文件复制到指定目录,并进行相应的处理。

        当使用Lambda表达式编写一个程序来自动监控指定文件夹中的文件时,可以使用Java的WatchService类来实现。下面是一个简单的示例,说明如何使用Lambda表达式来监控文件夹中的新文件,并将其复制到指定目录:

import java.io.IOException;
import java.nio.file.*;

public class FileWatcher {

    public static void main(String[] args) throws IOException {
        // 指定要监控的文件夹路径
        String folderPath = "path/to/folder";

        // 指定要复制到的目标文件夹路径
        String destinationPath = "path/to/destination";

        // 创建WatchService实例
        WatchService watchService = FileSystems.getDefault().newWatchService();

        // 注册文件夹路径到WatchService
        Path folder = Paths.get(folderPath);
        folder.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);

        // 启动一个线程来处理文件变化事件
        Thread thread = new Thread(() -> {
            while (true) {
                WatchKey key;
                try {
                    // 获取下一个文件变化事件
                    key = watchService.take();
                } catch (InterruptedException e) {
                    return;
                }

                // 处理文件变化事件
                for (WatchEvent<?> event : key.pollEvents()) {
                    WatchEvent.Kind<?> kind = event.kind();

                    // 如果是新文件创建事件
                    if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
                        // 获取新文件的路径
                        Path filePath = folder.resolve((Path) event.context());

                        // 复制文件到目标文件夹
                        try {
                            Files.copy(filePath, Paths.get(destinationPath).resolve(filePath.getFileName()), StandardCopyOption.REPLACE_EXISTING);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        // 进行其他处理
                        System.out.println("New file created: " + filePath);
                    }
                }

                // 重置WatchKey以接收更多文件变化事件
                key.reset();
            }
        });

        // 启动线程
        thread.start();
    }
}

        在上面的示例中,我们首先指定要监控的文件夹路径和要复制到的目标文件夹路径。然后,我们创建一个WatchService实例,并将文件夹路径注册到WatchService中,以便监听新文件的创建事件。

        接下来,我们启动一个线程来处理文件变化事件。在这个线程中,我们使用一个无限循环来获取下一个文件变化事件,并处理每个事件。如果事件的类型是新文件创建事件,我们获取新文件的路径,并将其复制到目标文件夹中。然后,我们可以进行其他处理,例如打印新文件的路径。

        最后,我们重置WatchKey以接收更多的文件变化事件,并启动线程。

        数据处理和转换:使用Lambda表达式和Stream API可以方便地对数据进行处理和转换。例如,可以使用Lambda表达式编写一个数据清洗程序,将输入数据进行过滤、排序、去重等操作,然后输出处理后的数据。

        当使用Lambda表达式和Stream API进行数据处理和转换时,可以方便地对数据进行过滤、排序、去重等操作。下面是一个简单的示例,说明如何使用Lambda表达式和Stream API来对输入数据进行清洗:

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

public class DataCleaner {

    public static void main(String[] args) {
        // 输入数据
        List<String> inputData = Arrays.asList("apple", "banana", "apple", "orange", "grape", "banana");

        // 过滤掉长度小于等于5的元素
        List<String> filteredData = inputData.stream()
                .filter(s -> s.length() > 5)
                .collect(Collectors.toList());

        // 对数据进行排序
        List<String> sortedData = filteredData.stream()
                .sorted()
                .collect(Collectors.toList());

        // 去重
        List<String> distinctData = sortedData.stream()
                .distinct()
                .collect(Collectors.toList());

        // 输出处理后的数据
        distinctData.forEach(System.out::println);
    }
}

在上面的示例中,我们首先定义了一个输入数据列表,其中包含了一些水果的名称。然后,我们使用Stream API对数据进行处理和转换。

首先,我们使用filter方法过滤掉长度小于等于5的元素。在Lambda表达式中,我们使用s -> s.length() > 5来指定过滤条件。

接下来,我们使用sorted方法对数据进行排序。默认情况下,它会按照元素的自然顺序进行排序。

然后,我们使用distinct方法对数据进行去重,确保每个元素只出现一次。

最后,我们使用forEach方法遍历处理后的数据,并使用System.out.println打印每个元素。

数据抓取和爬虫:使用Java 8的并发特性和Lambda表达式,可以编写高效的数据抓取和爬虫程序。例如,可以使用Lambda表达式编写一个多线程的爬虫程序,自动从指定网站上抓取数据,并进行相应的处理和存储。

使用Java 8的并发特性和Lambda表达式,可以编写高效的数据抓取和爬虫程序。下面是一个简单的示例,说明如何使用Lambda表达式和多线程来实现一个简单的爬虫程序:

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class WebCrawler {

    public static void main(String[] args) {
        // 创建一个线程池
        ExecutorService executor = Executors.newFixedThreadPool(10);

        // 定义要抓取的网站URL列表
        String[] urls = {"https://www.example.com/page1", "https://www.example.com/page2", "https://www.example.com/page3"};

        // 遍历URL列表,提交任务到线程池
        for (String url : urls) {
            executor.submit(() -> {
                try {
                    // 抓取数据
                    String data = fetchData(url);

                    // 处理数据
                    processData(data);

                    // 存储数据
                    saveData(data);

                    // 输出处理完成的URL
                    System.out.println("Processed URL: " + url);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }

        // 关闭线程池
        executor.shutdown();

        try {
            // 等待所有任务完成
            executor.awaitTermination(1, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("All tasks completed.");
    }

    private static String fetchData(String url) throws IOException {
        // 实现数据抓取逻辑
        // ...
        return "data";
    }

    private static void processData(String data) {
        // 实现数据处理逻辑
        // ...
    }

    private static void saveData(String data) {
        // 实现数据存储逻辑
        // ...
    }
}

在上面的示例中,我们首先创建了一个线程池,使用Executors.newFixedThreadPool(10)创建了一个固定大小为10的线程池。

然后,我们定义了要抓取的网站URL列表,并使用Lambda表达式遍历URL列表,将每个URL提交到线程池中。

在每个任务中,我们使用fetchData方法抓取数据,processData方法处理数据,saveData方法存储数据,并在处理完成后输出处理完成的URL。

最后,我们关闭线程池,并使用executor.awaitTermination(1, TimeUnit.MINUTES)等待所有任务完成。

自动化报表生成:使用Java 8的Stream API和Lambda表达式,可以方便地对数据进行聚合和计算,然后生成自动化报表。例如,可以使用Lambda表达式编写一个程序,自动从数据库中读取数据,进行统计和分析,然后生成报表并发送给相关人员。

自动化报表生成是一个常见的需求,可以使用Java 8的Stream API和Lambda表达式来实现。下面是一个简单的示例,说明如何使用Lambda表达式和Stream API来生成报表:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ReportGenerator {

    public static void main(String[] args) {
        // 模拟从数据库中读取数据
        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee("John", "Sales", 5000));
        employees.add(new Employee("Alice", "Marketing", 6000));
        employees.add(new Employee("Bob", "Sales", 4500));
        employees.add(new Employee("David", "Marketing", 5500));

        // 使用Stream API进行数据处理和统计
        Map<String, Long> departmentCount = employees.stream()
                .collect(Collectors.groupingBy(Employee::getDepartment, Collectors.counting()));

        Map<String, Double> departmentAverageSalary = employees.stream()
                .collect(Collectors.groupingBy(Employee::getDepartment, Collectors.averagingDouble(Employee::getSalary)));

        // 生成报表
        StringBuilder report = new StringBuilder();
        report.append("Department Count:\n");
        departmentCount.forEach((department, count) -> report.append(department + ": " + count + "\n"));

        report.append("\nDepartment Average Salary:\n");
        departmentAverageSalary.forEach((department, averageSalary) -> report.append(department + ": " + averageSalary + "\n"));

        // 发送报表给相关人员
        sendReport(report.toString());
    }

    private static void sendReport(String report) {
        // 实现发送报表的逻辑
        // ...
        System.out.println("Report sent:\n" + report);
    }

    static class Employee {
        private String name;
        private String department;
        private double salary;

        public Employee(String name, String department, double salary) {
            this.name = name;
            this.department = department;
            this.salary = salary;
        }

        public String getName() {
            return name;
        }

        public String getDepartment() {
            return department;
        }

        public double getSalary() {
            return salary;
        }
    }
}

在上面的示例中,我们首先模拟从数据库中读取数据,创建了一个包含员工信息的列表。

然后,我们使用Stream API对员工列表进行处理和统计。首先,我们使用Collectors.groupingBy方法按照部门进行分组,并使用Collectors.counting方法计算每个部门的人数,得到一个部门人数的统计结果。

接着,我们使用Collectors.groupingBy方法再次按照部门进行分组,并使用Collectors.averagingDouble方法计算每个部门的平均工资,得到一个部门平均工资的统计结果。

然后,我们使用StringBuilder来生成报表,将部门人数和部门平均工资的统计结果添加到报表中。

最后,我们调用sendReport方法发送报表给相关人员。在示例中,我们只是简单地使用System.out.println来打印报表,实际应用中可以根据需求来实现发送报表的逻辑。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值