Java高级(不可变集合、Stream流、日志框架)

不可变集合

什么是不可变集合

就是不可修改的集合。集合的数据在创建的时候提供,并且在整个生命周期都不可改变,否则报错。

问:为什么需要创建不可变集合
答:如果某个数据不能被修改。

public class Demo1 {
    public static void main(String[] args) {
        List<Double> lists = List.of(23.2,53.6,36.1);
        //.lists.set(1,99.9);UnsupportedOperationException
        System.out.println(lists);
        System.out.println(lists.get(2));
        Set<String> sets= Set.of("da","sad","dw");
        //sets.add("html");
        System.out.println(sets);
        Map<String,Integer> map =Map.of("shouji",53,"shoubiao",1);
        System.out.println(map);
    }
}
上述方法同样存在set和map集合中
public static void main(String[] args) {
// 1 创建不可变集合
List<Double> lists = List.of(23.2,53.6,36.1);
//集合创建之后 不允许添加和修改元素 但是可以通过获取的方式 获取其中的元素
//lists.add(78.9);
//lists.set(1,99.9);//UnsupportedOperationException
System.out.println(lists);
System.out.println(lists.get(2));
Set<String> sets = Set.of("java","mysql","css");
//sets.add("html");
System.out.println(sets);
Map<String,Integer> map = Map.of("手机",1,"手表",5);
System.out.println(map.get("手表"));
}

Stream流

什么是Stram流

在Java8中,引入lambda表达式,带来函数式编程,引入了一个全新的Stream流概念。

问:为什么要存在呢?
答:简化集合和数组的操作。

public class StreamDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张三丰");
list.add("张强");
// 把集合中所有以”张“开头的元素存储到一个新的集合。
//把张开头的集合中的长度为3的元素存储到一个新的集合
//遍历上一步得到的集合中的元素
List<String> zhangList = new ArrayList<>();
for (String name:list){
if(name.startsWith("张")){
zhangList.add(name);
}
}
System.out.println(zhangList);
List<String> zhang3List = new ArrayList<>();
for (String n:zhangList){
if(n.length() == 3){
zhang3List.add(n);
}
}
System.out.println(zhang3List);
System.out.println("-----------------------------");
//使用Stream实现
// list.stream().filter(new Predicate<String>() {
// @Override
// public boolean test(String s) {
// return s.startsWith("张");
// }
// }).forEach(s -> System.out.println(s));
list.stream().filter(s->s.startsWith("张")).filter(s-

>s.length()==3).forEach(s->System.out.println(s));
}
}

Stream的核心思想:
1 先得到集合或者数组的Stream流对象。
2 把元素放进去
3 然后用Stream流简化的ApI来操作元素

Stream流的获取

Straem流的三类方法
  1. 获取Straem流
  2. 中间方法
  3. 终结方法
    获取Straem流方式:
可以使用Collection接口中的默认方法 stream()获取

default Stream stream() 返回以此集合为源的顺序 Stream 。

数组获取方式:

通过Arrays工具类中提供的方法

Map集合

是间接的通过keySet 或者entitySet来进行流的操作。

public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
Stream<String> s= c.stream();
Map<String,Integer> map = new HashMap<>();
// 键的stream流
Stream<String> keyStream = map.keySet().stream();
//值流
Stream<Integer> valStream = map.values().stream();
// 键值对流
Stream<Map.Entry<String,Integer>> entryStream = map.entrySet().stream();
String[] names = {"张三","里斯"};
Stream<String> arrStream = Arrays.stream(names);
Stream<String> arrStream2 = Stream.of(names);
}

##2.3常用API
API
API1

Stream的综合应用需求: 某公司的研发部门,分为研发一部和二部,现在需要进行年终数据结算

要求:
1 员工信息至少包含(名称 性别 工资 奖金 处罚记录)
2 开发一部有4个员工,二部有5个员工
3 分别筛选2个部门的最高工资的员工信息,封装成优秀员工对象
4 分别统计2个部门的平均月收入,要求去掉最高工资和最低工资
5 统计2个部门的整体的平均工资,去掉最高工资和最低工资

public class Employee {
private String name;
private char sex;
private double salary;
private double bonus;
private String punish;
public Employee() {
}
public Employee(String name, char sex, double salary, double bonus, String
punish) {
this.name = name;
this.sex = sex;
this.salary = salary;
this.bonus = bonus;
this.punish = punish;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
public String getPunish() {
return punish;
}
public void setPunish(String punish) {
this.punish = punish;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return sex == employee.sex && Double.compare(employee.salary, salary) ==
0 && Double.compare(employee.bonus, bonus) == 0 && Objects.equals(name,
employee.name) && Objects.equals(punish, employee.punish);
}
@Override
public int hashCode() {
return Objects.hash(name, sex, salary, bonus, punish);
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", sex=" + sex +
", salary=" + salary +
", bonus=" + bonus +
", punish='" + punish + '\'' +
'}';
}
}
//优秀员工
public class TopperEmp {
private String name;
private double money;
public TopperEmp() {
}
public TopperEmp(String name, double money) {
this.name = name;
this.money = money;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TopperEmp topperEmp = (TopperEmp) o;
return Double.compare(topperEmp.money, money) == 0 &&
Objects.equals(name, topperEmp.name);
}
@Override
public int hashCode() {
return Objects.hash(name, money);
}
@Override
public String toString() {
return "TopperEmp{" +
"name='" + name + '\'' +
", money=" + money +
'}';
}
}
public class StreamDemo3 {
private static double allMoney1;
private static double allMoney2;
public static void main(String[] args) {
List<Employee> oneEmps = new ArrayList<>();
oneEmps.add(new Employee("孙悟空",'男',5000,1000,null));
oneEmps.add(new Employee("八戒",'男',3000,100,"顶撞上司"));
oneEmps.add(new Employee("沙僧",'男',2000,50,"迟到早退"));
oneEmps.add(new Employee("唐僧",'男',10000,3000,null));
List<Employee> twoEmps = new ArrayList<>();

收集Stream流

收集Stream流的作用:就是把Stream流操作后的结果转回到集合或者数组中去。
Stream流:操作集合/数组的手段
集合/数组:才是目的。
Stream流的收集的方法:

<R,A>R
collect(Collector<? super T,A,R>collector)
开始收集Stream流,指定收集器

Collectors工具类 提供了收集的方式
收集方式

public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张三丰");
list.add("张三丰");
list.add("张强");
Stream<String> s1 = list.stream().filter((s->s.startsWith("张")));
// 将处理之后的流收集成一个集合
List<String> zhangList = s1.collect(Collectors.toList());//可变集合
zhangList.add("java");
System.out.println(zhangList);
// 注意 “流只能使用一次”
Stream<String> s2 = list.stream().filter((s->s.startsWith("张")));
Set<String > zhagSet = s2.collect(Collectors.toSet());
System.out.println(zhagSet);
// Object[] arr = s2.toArray();
// System.out.println(arr);
}

Java中的Stream是一种用于处理集合数据的API,它提供了一种函数式编程的方式来处理数据。Stream可以对集合中的元素进行过滤、映射、排序、聚合等操作,而这些操作都可以通过链式调用来实现。Stream的使用可以大大简化代码,提高代码的可读性和可维护性。

日志框架

日志框架概述

作用:记录程序运行过程中的信息,并可以永久进行保存输出打印到控制台:

弊端:

  • 信息只能展示在控制台不能记录到其他位置
  • 想要取消记录的信息需要修改代码才可以完成

日志技术的体系结构

日志规范接口: Commons loging (gcl)/Simple Loging factory for java(slf4g)
日志实现框架:log4j、logback

Logback

Logback是基于slf4j规范的实现框架

Logback主要分为三大模块
Logback-core:该模块提供Logback的最核心功能为其他的两大模块奠定基础
Logback-classsic:是logf4j的一个改良版本,完整的实现了slf4j api
Logback-access:该模块与tomcat和jetty等Service容器的继承,提供了Http的访问日志功能
Logback使用
  1. 项目中新建一个目录lib,导入相关jar文件到项目中去
  2. 配置logback
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
CONSOLE :表示当前的日志信息是可以输出到控制台的。
-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--输出流对象 默认 System.out 改为 System.err-->
<target>System.out</target>
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽
度
%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %c [%thread] :
%msg%n</pattern>
</encoder>
</appender>
<!-- File是输出的方向通向文件的 -->
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}
- %msg%n</pattern>
<charset>utf-8</charset>
</encoder>
<!--日志输出路径-->
<file>D:/code/logback-data.log</file>
<!--指定日志文件拆分和压缩规则-->
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--通过指定压缩文件名称,来确定分割文件方式-->
<fileNamePattern>D:/code/logback-data-%d{yyyyMMdd}.log%i.gz</fileNamePattern>
<!--文件拆分大小-->
<maxFileSize>1MB</maxFileSize>
</rollingPolicy>
</appender>
<!--
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
, 默认debug
<root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
-->
<root level="ALL">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE" />
</root>
</configuration>
  1. 在代码中获取日志对象

Logger logger = LoggerFactory.getLogger(“类对象”);

public static void main(String[] args) {
//日志的级别 Trace<Debug<Info
// all 打开所有的日志信息
//off 关闭所有的日志信息
Logger logger = LoggerFactory.getLogger(LogDemo1.class);
logger.info("这是一个info级别的日志");
logger.debug("这是一个debug级别的日志");
logger.trace("这是一个trace级别的日志");
}

日志的级别的设置:

level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
, 默认debug
<root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
-->
<root level="TRACE">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE" />
</root>
</configuration>

值输出级别不低于设定级别的日志信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值