Singleton: One Shared Counter

Problem

Several clients ask for the next number from one shared counter. Each input line is CLIENT next. Print CLIENT and the new counter value. All clients must use the same single counter object (the Singleton pattern), so the numbers are 1, 2, 3, ... in the order of the lines.

Constraints

  • 1 <= lines <= 10^4

Examples

Input

A next
B next
A next

Output

A 1
B 2
A 3

Solutions

Best approachTime O(n)Space O(n)

The private constructor stops other code from creating a second counter. This simple version is not thread-safe; for threads use an enum singleton or a holder class in Java.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Process lines.
 * Input   : Several lines.
 * Output  : One line per request.
 * Approach: One shared object.
 * Time    : O(n)
 * Space   : O(n)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
        // Step 1: A singleton has one instance for the whole program. The constructor is private, so nobody else can create one.
        static final class Counter {
            private static Counter instance;
            private long value = 0;

            private Counter() {
            }

            // Step 2: getInstance creates the object the first time and gives the same object every next time.
            static Counter getInstance() {
                if (instance == null) {
                    instance = new Counter();
                }
                return instance;
            }

            long next() {
                value++;
                return value;
            }
        }

    // This method solves the task. It receives the input and returns the answer.
    static String[] solve(String[] lines) {
        String[] output = new String[lines.length];
        for (int i = 0; i < lines.length; i++) {
            String client = lines[i].split(" ")[0];

            // Step 3: Every client asks getInstance(). All of them get the same object, so the counter is shared.
            output[i] = client + " " + Counter.getInstance().next();
        }
        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 the constructor private?