Lombok :
介绍:
Lombok 是一个在 Java 开发中广泛使用的开源库,它的主要作用是通过注解的方式,减少 Java 代码中大量的样板代码(如 getter、setter、构造函数等),从而让代码更加简洁、易读和易于维护。
1.Getter 和 Setter 方法
在 Java 类中,为了访问和修改类的私有属性,通常需要编写大量的 getter 和 setter 方法。使用 Lombok 的@Getter和@Setter注解,可以自动生成这些方法。
import lombok.Getter;
import lombok.Setter;
public class Person {
@Getter @Setter
private String name;
@Getter @Setter
private int age;
}
上述代码中,@Getter和@Setter注解会在编译时自动为name和age属性生成对应的 getter 和 setter 方法。
2.构造函数
Lombok 提供了@NoArgsConstructor、@RequiredArgsConstructor和@AllArgsConstructor注解来自动生成构造函数。
@NoArgsConstructor:生成一个无参构造函数。
@RequiredArgsConstructor:为类中所有被final修饰的字段和被@NonNull注解的字段生成一个带参构造函数。
@AllArgsConstructor:生成一个包含所有字段的构造函数。
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
public class Student {
private String id;
private final String name;
}
3.@EqualsAndHashCode注解
@EqualsAndHashCode注解用于自动生成equals()和hashCode()方法,简化对象比较和哈希操作的代码编写。
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class Product {
private String productId;
private String name;
}
4.@Data注解
@Data是一个综合性的注解,它包含了@Getter、@Setter、@ToString、@EqualsAndHashCode和@RequiredArgsConstructor的功能。使用@Data注解可以极大地简化类的定义。
import lombok.Data;
@Data
public class Employee {
private String employeeId;
private String name;
private int age;
}
5. @Builder注解
@Builder注解可以为类生成一个构建器模式的代码,使得对象的创建更加灵活和易读。
import lombok.Builder;
@Builder
public class Order {
private String orderId;
private String customerName;
}
// 使用构建器创建对象Order order = Order.builder()
.orderId("123")
.customerName("John Doe")
.build();
这里的builder方法有
builder情况下给点字段默认值:
@builder.Default在我们的目标字段头上
工作原理
Lombok 的工作原理基于 Java 的注解处理器(Annotation Processor)。在 Java 编译过程中,注解处理器会在编译期扫描代码中的注解,并根据注解的定义生成相应的 Java 代码。例如,当编译器遇到@Getter注解时,会自动在编译后的字节码中添加对应的 getter 方法。
优点
提高开发效率:减少了大量样板代码的编写,开发人员可以将更多的精力放在业务逻辑上。
代码简洁易读:去除了冗长的 getter、setter 等方法,使代码更加简洁,提高了代码的可读性和可维护性。
减少人为错误:自动生成的代码遵循统一的规范,减少了因手动编写代码而可能引入的错误。
缺点
学习成本:团队成员需要学习 Lombok 的注解和使用方法,对于不熟悉 Lombok 的开发者来说,可能会增加一定的学习成本。
调试难度:由于部分代码是在编译期自动生成的,在调试时可能会增加一定的难度。
兼容性问题:某些 IDE 或工具可能对 Lombok 的支持不够完善,可能会导致代码提示或编译错误等问题。
集成与使用
要在项目中使用 Lombok,需要在项目的依赖管理文件中添加 Lombok 的依赖。以 Maven 为例,在pom.xml文件中添加以下依赖:
xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
<scope>provided</scope></dependency>
同时,为了让 IDE 能够正确识别和处理 Lombok 注解,还需要安装 Lombok 的 IDE 插件。
关键字:var,不写明,根据后面的内容判断类型
val,是final var
资源释放和异常处理:
try with resource
也可以使用@cleanup的注解
如果需要抛出异常,可以使用@sneakyThrows(静默抛出)
非空判断:
@NonNull
@sneakyThrows
可以做到
锁处理:
这里的a不会在100000退出,会在更多的时候退出,这是因为++不是原子性的操作
使用synchronized可以实现互斥访问
这里的synchronized的锁:成员方法:对象作为锁,
静态方法:class类作为锁
会出现同一个类中的多个成员方法出现互斥访问
使用功能@synchronized/@locked可以实现代码块的互斥访问()内可以自定义锁的名字
日志:
@Log、@Log4、@SLF4j等等都有
算法:
树形dp:
Ural 大学有 NN 名职员,编号为 1∼N1∼N。
他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。
每个职员有一个快乐指数,用整数 HiHi 给出,其中 1≤i≤N1≤i≤N。
现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。
在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。
输入格式
第一行一个整数 NN。
接下来 NN 行,第 ii 行表示 ii 号职员的快乐指数 HiHi。
接下来 N−1N−1 行,每行输入一对整数 L,KL,K,表示 KK 是 LL 的直接上司。(注意一下,后一个数是前一个数的父节点,不要搞反)。
输出格式
输出最大的快乐指数。
#include<bits/stdc++.h>
using namespace std;
const int N=10010;
int f[N][2];
int a[N];
bool is[N];
unordered_map<int,vector<int>> e;
int dp(int u,int fa){
f[u][1]=a[u];
for(int v:e[u]){
if(v==fa)continue;
dp(v,u);
f[u][1]+=f[v][0];
f[u][0]+=max(f[v][0],f[v][1]);
}
return max(f[u][1],f[u][0]);
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=0;i<n-1;i++){
int u,v;
cin>>u>>v;
is[u]=1;
e[u].push_back(v);
e[v].push_back(u);
}
int root=0;
for(int i=1;i<=n;i++){
if(is[i]==0){
root=i;
break;
}
}
dp(root,-1);
cout<<max(f[root][0],f[root][1]);
}
完全背包:
#include <bits/stdc++.h>
using namespace std;
const long long N=100010;
long long w[N];
long long f[N];
long long n,m;
signed main(){
cin>>n>>m;
f[0]=1;
for(long long i=0;i<n;i++){
cin>>w[i];
}
for(long long i=0;i<n;i++){
for(long long j=w[i];j<=m;j++){
f[j]+=f[j-w[i]];
}
}
cout<<f[m];
}
货币系统
完全背包问题可以表示出1-m中所以可以表示出来的数
#include <bits/stdc++.h>
using namespace std;
const long long N=100010;
long long w[N];
long long f[N];
long long n,m;
signed main(){
cin>>n>>m;
f[0]=1;
int res=0;
for(long long i=0;i<n;i++){
cin>>w[i];
}
for(long long i=0;i<n;i++){
if(!f[a[i]])res++;
for(long long j=w[i];j<=m;j++){
f[j]+=f[j-w[i]];
}
}
cout<<res;
}
混合背包问题:
二进制处理+特殊处理完全背包over
能量石:
#include<bits/stdc++.h>
using namespace std;
const int N=11000;
typedef struct node{
int s,e,l;
bool operator<(const node& a){
return s*a.l<l*a.s;
}
}node;
node num[N];
int f[N];
int main(){
int t;
cin>>t;
int ww=0;
while(ww<t){
ww++;
int n;
cin>>n;
int m=0;
for(int i=0;i<n;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
num[i]={a,b,c};
m+=a;
}
memset(f,-0x3f,sizeof f);
f[0]=0;
sort(num,num+n);
for(int i=0;i<n;i++){
int s=num[i].s,l=num[i].l,e=num[i].e;
for(int j=m;j>=s;j--){
f[j]=max(f[j],f[j-s]+e-l*(j-s));
}
}
int res=0;
for(int i=0;i<=m;i++)res=max(res,f[i]);
printf("Case #%d: %d\n",ww,res);
}
}
状态机模型,密码设计问题