You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建Job类实例时如何避免Job Number属性重复?

解决Job实例job number重复的问题

嘿,我完全懂你现在的困扰——想确保每个Job实例的job number都是唯一的,但之前用数组循环比对的思路确实行不通:一是数组初始化后里面全是null,根本没实例可比对;二是就算之后创建了实例,每次都遍历数组检查效率低还容易出错。

给你几个实用的解决方案,都是从提前校验编号是否被使用的角度出发的:

方法一:在Job类中用静态集合跟踪已用编号

我们可以给Job类加一个静态的HashSet(属于类本身,所有实例共享),用来存储已经被使用的job number。然后在构造方法里做校验:

import java.util.HashSet;
import java.util.Set;

public class Job {
    // 静态集合,所有Job实例共享,存储已用的编号
    private static final Set<String> USED_JOB_NUMBERS = new HashSet<>();
    private String jobNumber;

    public Job(String jobNumber) {
        // 先检查编号是否已存在
        if (USED_JOB_NUMBERS.contains(jobNumber)) {
            throw new IllegalArgumentException("Job number " + jobNumber + " 已经被使用了!");
        }
        this.jobNumber = jobNumber;
        // 把新编号加入集合
        USED_JOB_NUMBERS.add(jobNumber);
    }

    // 如果有删除Job实例的需求,记得在销毁时把编号从集合移除
    @Override
    protected void finalize() throws Throwable {
        USED_JOB_NUMBERS.remove(jobNumber);
        super.finalize();
    }

    // Getter方法
    public String getJobNumber() {
        return jobNumber;
    }
}

怎么用这个类?

你原来的数组初始化逻辑可以保留,只需要在创建实例时捕获异常,让用户重新输入重复的编号:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Job[] jobs = new Job[3];

        for (int i = 0; i < jobs.length; i++) {
            System.out.print("请输入第" + (i+1) + "个Job的编号:");
            String inputNum = scanner.nextLine();
            try {
                jobs[i] = new Job(inputNum);
                System.out.println("Job创建成功!");
            } catch (IllegalArgumentException e) {
                System.out.println(e.getMessage());
                i--; // 回退索引,让用户重新输入当前位置的编号
            }
        }

        scanner.close();
    }
}

这样每次创建Job实例前,都会先检查静态集合里有没有这个编号,从根源上避免了重复。

方法二:用工厂类封装实例创建逻辑

如果不想让Job类本身承担编号校验的职责(更符合单一职责原则),可以把校验和创建实例的逻辑放到一个工厂类里:

import java.util.HashSet;
import java.util.Set;

// Job工厂类,负责管理编号和创建实例
public class JobFactory {
    private static final Set<String> USED_JOB_NUMBERS = new HashSet<>();

    public static Job createJob(String jobNumber) {
        if (USED_JOB_NUMBERS.contains(jobNumber)) {
            throw new IllegalArgumentException("Job number " + jobNumber + " 已被占用!");
        }
        Job newJob = new Job(jobNumber);
        USED_JOB_NUMBERS.add(jobNumber);
        return newJob;
    }

    // 提供释放编号的方法,当Job实例被删除时调用
    public static void releaseJobNumber(String jobNumber) {
        USED_JOB_NUMBERS.remove(jobNumber);
    }
}

// Job类只负责自身的属性和业务逻辑
public class Job {
    private String jobNumber;

    // 构造方法可以设为私有,强制通过工厂创建实例
    private Job(String jobNumber) {
        this.jobNumber = jobNumber;
    }

    public String getJobNumber() {
        return jobNumber;
    }
}

使用工厂类的示例

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Job[] jobs = new Job[3];

        for (int i = 0; i < jobs.length; i++) {
            System.out.print("请输入第" + (i+1) + "个Job的编号:");
            String inputNum = scanner.nextLine();
            try {
                jobs[i] = JobFactory.createJob(inputNum);
                System.out.println("Job创建成功!");
            } catch (IllegalArgumentException e) {
                System.out.println(e.getMessage());
                i--;
            }
        }

        scanner.close();
    }
}

这种方式把“编号管理”和“Job实例”分离开,代码结构更清晰,后期维护也更方便。

额外提示

如果是在多线程环境下创建Job实例,记得把静态集合换成线程安全的实现,比如:

// 用ConcurrentHashMap的keySet来实现线程安全的集合
private static final Set<String> USED_JOB_NUMBERS = ConcurrentHashMap.newKeySet();

或者用Collections.synchronizedSet(new HashSet<>()),避免多线程同时操作集合导致的并发问题。

内容的提问来源于stack exchange,提问作者Stay Low

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:03:29