系统在开发阶段或者上线后,一旦业务出现问题,需要有信息定位,记录程序的运行信息就需要使用日志框架。
生活中的日志就好比日记,可以记录你生活中的点点滴滴。
程序中的日志可以用来记录程序运行过程中的信息,并可以永杰存储。
1.可以将系统执行的信息选择性的记录到指定的位置(控制台、文件中、数据库中)。
2.可以随时以开关的形式控制是否记录日志,无需修改源代码。
1.日志规范大多是一些接口,提供给实现框架去设计。
2.常见的规范是:
Commons Logging
Simple Logging Facade for Java
1.Log4J
2.Logback
1.在项目下新建文件夹lib,导入Logback的相关jar包到该文件下,并添加到项目依赖库中去,
2.将Logback的核心配置文件logback.xml直接拷贝到src目录下(必须是src下)。
3.在代码中获取日志的对象。
4.使用日志对象LOGGER调用其方法输出不能的日志对象。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoggerDemo {
//获取日志对象
public static final Logger LOGGER = LoggerFactory.getLogger("LoggerDemo类");
public static void main(String[] args) {
LOGGER.trace("trace级别的日志");
//打印结果 2023-09-10 22:10:30.992 [TRACE] LoggerDemo类 [main] : trace级别的日志
}
}
public class LambdaDemo {
public static void main(String[] args) {
useSwimming(new Swimming() {
@Override
public void swim() {
System.out.println("匿名内部类");
}
});
System.out.println("====================");
//lambda表达式
useSwimming(()->{
System.out.println("lambda");
});
}
//方法的参数为接口,调用此方法要传入实现类对象
public static void useSwimming(Swimming swimming){
swimming.swim();
}
}
interface Swimming{
//抽象方法
public abstract void swim();
}
1.只有一个抽象方法需要重写的接口,函数式接口。函数式接口是允许其他的非抽象方法的存在例如静态方法,默认方法,私有方法。
2.为了标识接口是一个函数式接口,可以在接口之上加上一个注解:@FunctionalInterface以示区别。
public class FunctionDemo {
public static void main(String[] args) {
}
}
//函数式接口里面要包含一个抽象方法
@FunctionalInterface
interface Swim{
public abstract void show();
//注意 Object类中的方法如果作为抽线方法,那么子类可以不重写
public abstract String toString();
}
(形式参数) -> {代码块}
1.():括号里面没有内容,可以看成方法形式参数为空。
2.->:用箭头指向后面要做的事情。
3.{}:包含一段代码,我们称之为代码块,可以看成是方法中的内容。
4.如果有多个参数。参数之间用逗号隔开;如果没有参数,留空即可。
//省略规则:
/*
参数类型可以省略,但是有多个参数的情况下,不能只省略一个
如果参数有且仅有一个,那么小括号可以省略
如果代码块的语句只有一个,可以省略大括号和分号,甚至是return
*/
public class Test {
public static void main(String[] args) {
//无参所以小括号里面不需要写什么东西
useShowHandler(()-> System.out.println("lambda"));
}
public static void useShowHandler(ShowHandler showHandler){
showHandler.show();
}
}
@FunctionalInterface
interface ShowHandler{
public abstract void show();
}
public class Test2 {
public static void main(String[] args) {
useStringHandler(a-> System.out.println(a));
//lambda表达式最简式
useStringHandler(System.out::println);
}
public static void useStringHandler(StringHandler stringHandler){
stringHandler.printMessage(5);
}
}
@FunctionalInterface
interface StringHandler{
public abstract void printMessage(int a);
}
public class Test4 {
public static void main(String[] args) {
useCalculator(new Calculator() {
@Override
public double calc(double a, double b) {
//想要精确运算要加字符串
BigDecimal bigDecimal1 = new BigDecimal(a+"");
BigDecimal bigDecimal2 = new BigDecimal(b+"");
BigDecimal sum = bigDecimal1.add(bigDecimal2);
//将BigDecimal进行转换为double类型
return sum.doubleValue();
}
});
useCalculator((a, b)->{
BigDecimal bigDecimal1 = new BigDecimal(a+"");
BigDecimal bigDecimal2 = new BigDecimal(b+"");
BigDecimal sum = bigDecimal1.add(bigDecimal2);
return sum.doubleValue();
});
}
public static void useCalculator(Calculator calculator){
double result = calculator.calc(0.1,0.2);
System.out.println(result);
}
}
@FunctionalInterface
interface Calculator{
public abstract double calc(double a,double b);
}
1.参数类型可以省略,但是有多个参数的情况下,不能只省略一个。
2.如果有参数有且仅有一个,那么小括号可以省略。
3.如果代码块的语句只有一条,可以省略大括号和分号,甚至是return。
1.匿名内部类:可以是接口,也可以是抽象类,还可以是具体类。
2.Lambda表达式:只能是函数式接口。
1.如果接口中仅有一个抽象方法需要重写,可以使用Lambda表达式,也可以使用匿名内部类。
2.如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式。
1.匿名内部类:编译之后,产生一个单独的class字节码文件。
2.Lambda表达式:编译之后,没有一个单独的class字节码文件,对应的字节码会在运行的时候动态生成。
1.获取Stream流。
创建一条流水线,并把数据放到流水线准备进行操作。
2.中间方法
流水线上的操作。
一次操作完毕之后,还可以继续进行其他操作。
3.终结方法
一个Stream流只能有一个终结方法。
是流水线上的左后一个操作。
public class StreamDemo {
public static void main(String[] args) {
/*
单列集合
*/
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张三丰","张飞","曹操","孙尚香");
list.stream().forEach(s -> System.out.println(s));
/*
双列集合
*/
HashMap<Integer,String> hm = new HashMap<>();
hm.put(1,"张三丰");
hm.put(2,"张飞");
hm.put(3,"曹操");
hm.put(4,"孙尚香");
Set<Integer> set = hm.keySet();
set.stream().forEach(s-> System.out.println(hm.get(s)));
/*
数组
*/
Integer[] arr = {1,2,3};
Arrays.stream(arr).forEach(s-> System.out.println(s));
//可变参数
Stream.of(1,2,3,4,5,6,7).forEach(s-> System.out.println(s));
}
}
用于对流中的数据进行过滤。
//1.Stream filter(Predicate predicate) 用于对流中的数据进行过滤
//Predicate接口中的方法:boolean test(T t):对指定的参数进行判断,返回一个布尔值
public class test {
public static void main(String[] args) {
//新建集合
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白起","鲁班","貂蝉","吕布");
/*
filter方法会拿到流中的每一个数据
把每一个数据传递给Lambda表达式的形参s
如果返回false就丢弃,如果返回true就保留。
*/
list.stream().filter(s -> {return true;}).forEach(s-> System.out.println(s));
//return true;
//打印结果全部打印
//return false;
//打印结果全部不打印
}
}
limit拿到前面多少位元素。
public class test {
public static void main(String[] args) {
//新建集合
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白起","鲁班","貂蝉","吕布");
//limit拿到前面多少位元素,这里拿到前面3个元素
list.stream().limit(3).forEach(s -> System.out.println(s));
}
}
skip跳过指定参数个数的元素。
public class test {
public static void main(String[] args) {
//新建集合
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白起","鲁班","貂蝉","吕布");
//skip跳过指定参数个数的元素,这里跳过前三个元素
list.stream().skip(3).forEach(s -> System.out.println(s));
}
}
concat合并a和b两个流成为一个流。
public class test {
public static void main(String[] args) {
//新建集合
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白起","鲁班","貂蝉","吕布");
//concat合并a和b两个流成为一个流
//只有前三个元素
Stream a = list.stream().limit(3); //"白起","鲁班","貂蝉"
//跳过前三个元素
Stream b = list.stream().skip(3); //"吕布"
Stream.concat(a,b).forEach(s-> System.out.println(s));
}
}
去重,保证唯一性
public class test {
public static void main(String[] args) {
//新建集合
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白起","鲁班","貂蝉","吕布");
//去重,保证唯一型
list.stream().distinct().forEach(s -> System.out.println());
}
}
默认升序排序。
public class test {
public static void main(String[] args) {
//新建集合
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"白起","鲁班","貂蝉","吕布");
Stream.of(1,2,3,7,64,3,5).sorted().forEach(s-> System.out.println(s));
//打印结果 1 2 3 3 5 7 64
Stream.of(1,2,3,7,64,3,5).sorted(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
}).forEach(s-> System.out.println(s));
//打印结果 降序排序
}
}
返回流中的元素个数。
public class test {
public static void main(String[] args) {
//新建集合
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "白起", "鲁班", "貂蝉", "吕布");
//返回流中的元素个数
long result = list.stream().count();
System.out.println(result);
}
}
/*
过滤元素并遍历集合
定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
将集合中的奇数删除,只保留偶数
*/
public class test {
public static void main(String[] args) {
//新建集合
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "白起", "鲁班", "貂蝉", "吕布");
Stream.of(1,2,3,4,5,6,7,8,9,10).filter(s->{return s%2==0;}).forEach(s-> System.out.println(s));
}
}
public class test {
public static void main(String[] args) {
//新建集合
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "白起", "鲁班", "貂蝉", "吕布","吕布","吕布","孙尚香","马儿扎哈");
List<String> newList = list.stream().filter(s -> {
return s.length() >= 3;
}).collect(Collectors.toList());
System.out.println(newList);
//打印结果 [孙尚香, 马儿扎哈]
Set<String> set = list.stream().filter(s -> {
return s.length() >= 2;
}).collect(Collectors.toSet());
System.out.println(set);
//打印结果 [马儿扎哈, 白起, 吕布, 貂蝉, 孙尚香, 鲁班]
}
}
public class StreamDemo7 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"zhangsan,23","lisi,24","wangwu,25");
Map<String, Integer> map = list.stream().filter(s -> {
String[] strings = s.split(",");
int age = Integer.parseInt(strings[1]);
return age >= 24;
// }).collect(Collectors.toMap(Function类型的数据,Function类型的数据));
}).collect(Collectors.toMap(
(String s) -> {
return s.split(",")[0];
},
(String s) -> {
return Integer.parseInt(s.split(",")[1]);
})
);
System.out.println(map) ;
//打印结果 {lisi=24, wangwu=25}
}
}