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

Best approachTime O(n)Space O(n)

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.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * 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)
  1. Why is a static counter risky with threads?