实体类对象赋值的四种方式

本文介绍了四种为对象字段赋值的方法,包括传统的set方法、构造器赋值、通用Builder模式以及链式编程。每种方式都有其优缺点,如set方法在字段多时易读性下降,构造器要求顺序且可能导致冗余,Builder模式简洁但不适用于多次赋值,链式编程方便但需额外注解。选择合适的方式取决于个人喜好和具体场景需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

假设我们现在有一个Student对象,对象中有两个属性age和score,如下方代码块所示

private int age;
private int score;

思考:如果我们要对对象中的字段进行赋值可以选的方式有哪几种?

1.采用 new 对象并进行set赋值

public static void main(String[] args) {
        Student student = new Student();
        student.setAge(10);
        student.setScore(15);
    }

这种赋值方式可以说是最老牌也用的人最多的赋值方式了,不过这种赋值方式有种弊端,就是当实体类字段过多的时候,需要写很多set,代码易读性大大降低

//例
 Student student = new Student();
        student.setAge(10);
        student.setScore(15);
        student.setAge(10);
        student.setScore(15);
        student.setAge(10);
        student.setScore(15);
        student.setAge(10);
        student.setScore(15);
        student.setAge(10);
        student.setScore(15);
        student.setAge(10);
        student.setScore(15);
        student.setAge(10);
        student.setScore(15);

2.采用对象类中设置赋值方法,并通过new Student(x,x)的方式进行赋值

//在Student类中添加如下方法
Student(int age, int score){
        super();
        this.age = age;
        this.score = score;
    }
//赋值
Student student = new Student(10,20);

使用这种方法,字段顺序必须保证正确,并且无用的值也需要进行设置,容易产生冗余工作。对于代码的读者来说,也很难去对应各个属性值代表的意思

//例:当我们只想给age字段赋值,score字段不用赋值时
Student student = new Student(10,null);

3.通用Builder构造器赋值

//例
Student student = Builder.of(Student::new)
                .with(Student::setAge, 10)
                .with(Student::setScore, 15)
                .build();

可以看到,构造器使用的是流式编程,整个赋值过程简洁易懂。但是这种赋值方式在同一个对象需要在不同的位置针对不同的字段进行赋值时,使用体验几乎为零

3.1使用通用Builder构造器进行赋值的话,需要在项目种添加Builder类(如下),添加之后即可像上面的例子一样进行使用

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * @program: practice
 * @description: 通用Build构造器
 * @author: ID-Tang
 * @create: 2021-03-31 09:31
 **/
public class Builder<T> {
    private final Supplier<T> instantiator;
    private List<Consumer<T>> modifiers = new ArrayList<>();
    
    private Builder(Supplier<T> instantiator) {

        this.instantiator = instantiator;
    }

    public static <T> Builder<T> of(Supplier<T> instantiator) {

        return new Builder<>(instantiator);
    }

    public <P1> Builder<T> with(Consumer1<T, P1> consumer, P1 p1) {

        Consumer<T> c = instance -> consumer.accept(instance, p1);
        modifiers.add(c);

        return this;
    }

    public <P1, P2> Builder<T> with(Consumer2<T, P1, P2> consumer, P1 p1, P2 p2) {

        Consumer<T> c = instance -> consumer.accept(instance, p1, p2);
        modifiers.add(c);

        return this;
    }

    public <P1, P2, P3> Builder<T> with(Consumer3<T, P1, P2, P3> consumer, P1 p1, P2 p2, P3 p3) {

        Consumer<T> c = instance -> consumer.accept(instance, p1, p2, p3);
        modifiers.add(c);

        return this;
    }

    public T build() {
        T value = instantiator.get();
        modifiers.forEach(modifier -> modifier.accept(value));
        modifiers.clear();

        return value;
    }

    /**
     * 1 参数 Consumer
     */
    @FunctionalInterface
    public interface Consumer1<T, P1> {
        void accept(T t, P1 p1);
    }

    /**
     * 2 参数 Consumer
     */
    @FunctionalInterface
    public interface Consumer2<T, P1, P2> {
        void accept(T t, P1 p1, P2 p2);
    }

    /**
     * 3 参数 Consumer
     */
    @FunctionalInterface
    public interface Consumer3<T, P1, P2, P3> {
        void accept(T t, P1 p1, P2 p2, P3 p3);
    }
}

4.采用链式编程方式进行赋值

链式编程需要在实体类上添加@Accessors(chain = true)注解,该注解的意思是开启链式编程

//示例
@Data
@Accessors(chain = true)
public class Student {
    private int age;
    private int score;
}

上面的示例即已开启链式编程,在对实体类进行赋值时,可以使用.set的方式进行追加赋值

	//示例
    public static void main(String[] args) {
        Student student = new Student()
                .setAge(10)
                .setScore(10);
    }

采用该赋值方式,需要在每个新建的实体类上都加入@Accessors(chain = true)注解,而使用Builder构造器进行赋值,只用引入一次Builder类即可实现任何地方无差别使用

链式编程和通用Builder构造器赋值对比

		//链式编程
 		Student student = new Student()
                .setAge(10)
                .setScore(10);
		//通用Builder构造器
        Student build = Builder.of(Student::new)
                .with(Student::setAge, 10)
                .with(Student::setScore, 15)
                .build();

萝卜青菜各有所爱,没有什么方式是最优解,跟随自己的心,用自己最喜欢的方式就好~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ID-Tang

梦想支持度+1

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值