Static Counter: ID Generator
Problem
Every new person gets the next id: 1, 2, 3, ... The counter belongs to the class (static), not to one object. Commands: create <name> prints id=<id> name=<name>, count prints how many persons were created, lookup <id> prints the name of that person or none if there is no such id.
Constraints
- 1 <= commands <= 10^4
Examples
Input
create amit create ravi count lookup 2
Output
id=1 name=amit id=2 name=ravi 2 ravi
Solutions
A static (class-level) field is shared by all objects, so it is the natural place for a counter. The downside is hidden global state: in tests it must be reset, and in threaded programs it needs an AtomicInteger or a lock.
/*
* Problem : Process lines.
* Input : Several lines.
* Output : One result per command.
* Approach: Class-level counter.
* Time : O(n)
* Space : O(n)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// Step 1: "static" means one copy for the whole class. All objects share the same nextId.
static class Person {
private static int nextId = 1;
private static final java.util.List<Person> ALL = new java.util.ArrayList<>();
private final int id;
private final String name;
Person(String name) {
// Step 2: Take the current number as id, then move the counter forward.
this.id = nextId++;
this.name = name;
ALL.add(this);
}
static int count() {
return ALL.size();
}
static String lookup(int id) {
return id >= 1 && id <= ALL.size() ? ALL.get(id - 1).name : "none";
}
}
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
// Step 3: The static state lives as long as the program, so we reset it for a fresh run.
Person.nextId = 1;
Person.ALL.clear();
String[] output = new String[lines.length];
for (int i = 0; i < lines.length; i++) {
String[] part = lines[i].split(" ");
if (part[0].equals("create")) {
Person person = new Person(part[1]);
output[i] = "id=" + person.id + " name=" + person.name;
} else if (part[0].equals("count")) {
output[i] = String.valueOf(Person.count());
} else {
output[i] = Person.lookup(Integer.parseInt(part[1]));
}
}
return output;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(String.join("\n", solve(lines)));
}
}
Hints (1)
- Why is a static counter risky with threads?