创建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
相关产品推荐
相关产品推荐

