Авто инкремент ключей в HashMap

132
09 января 2020, 04:30

Подскажите, почему не работает код. В Map необходимо добавлять имя объекта с уникальным ключом.

class Mamam {
    static HashMap<Integer, String> names = new HashMap<>();
}
class Customer {
    Customer(String name) {
        int x = 0;
        if (Mamam.names.containsKey(x)){
            Mamam.names.put(x++,name);
        } else {
            Mamam.names.put(x,name);
        }
    }
}
public class Res {
    public static void main(String[] args) {
        Customer asd = new Customer("Ivan");
        Customer asd2 = new Customer("Petr");
        Customer asd3 = new Customer("Vasya");
        Customer asd4 = new Customer("Ilya");
        Customer asd5 = new Customer("Vasya2");
        Customer asd6 = new Customer("Oleg");
        System.out.print(Mamam.names);
        System.out.println(Mamam.names.size());
    }
}

Вывод:

{0=Oleg}

1

Answer 1

Вам уже ответили почему, прямо когда я уже подготовил свой пример кода, Вам уже показали как использовать статическую переменную, я сделал слегка иначе:

class Customer {
    Customer(String name) {
        int x = 0;
        while(Mamam.names.containsKey(x)){
            x++;
        }
        Mamam.names.put(x,name);
    }
}

Вот код целиком:

import java.util.HashMap;
class Mamam {
    static HashMap<Integer, String> names = new HashMap<Integer, String>();
}
class Customer {
    Customer(String name) {
        int x = 0;
        while(Mamam.names.containsKey(x)){
            x++;
        }
        Mamam.names.put(x,name);
    }
}
public class Res {
    public static void main(String[] args) {
        new Customer("Ivan");
        new Customer("Petr");
        new Customer("Vasya");
        new Customer("Ilya");
        new Customer("Vasya2");
        new Customer("Oleg");
        System.out.println(Mamam.names);
        System.out.println(Mamam.names.size());
    }
}

Однако помимо корректности в Вашем коде есть ряд архитектурных ошибок

  1. Выбор ключа - зона ответсвенности хранилища, иначе вы можете нарушить логику генерации ключей извне(по месту добавления данных в мапу), в моем варианте это не получится сделать, т.к. эта логика инкапсулированиа в метод Mamam.add():

  2. Вы добавляете данные в мапу из конструктора кастомера, это однако зона ответственности управляющего кода, кастомер не должен знать куда его кладут.

  3. Вы напрямую обращаетесь к статическому полю name - это тоже нарушение инкапсуляции

class Mamam {
    private static HashMap<Integer, String> names = new HashMap<Integer, String>();
    public static void add(Customer c) {
        int x = 0;
        while(names.containsKey(x)){
            x++;
        }
        Mamam.names.put(x, c.name);
    }
    public static void stats() {
        System.out.println(names);
        System.out.println(names.size());
    }
}
class Customer {
    String name;
    Customer(String name) {
        this.name = name;
    }
}
public class Res {
    public static void main(String[] args) {
        Mamam.add(new Customer("Ivan"));
        Mamam.add(new Customer("Petr"));
        Mamam.add(new Customer("Vasya"));
        Mamam.add(new Customer("Ilya"));
        Mamam.add(new Customer("Vasya2"));
        Mamam.add(new Customer("Oleg"));
        Mamam.stats();
    }
}

Вот вывод

{0=Ivan, 1=Petr, 2=Vasya, 3=Ilya, 4=Vasya2, 5=Oleg}

6

Answer 2

Проблема была в том, что при создании нового объекта класса Customer переменная x, создавалась заново, поэтому, диапазон был, либо 0 либо 1. НО, в этом вызове:

Mamam.names.put(x++,name);

x++ инкрементация проводилась после вызова метода. Поэтому в функцию посылалась просто x. В итоге все записи были на ключ 0.

При таком синтаксисе ++x происходит сначала инкрементация, а потом отправление в функцию, а при таком x++ сначала вызывается функция , а потом происходит инкрементация.

import java.util.*; 
class Mamam { 
    static HashMap<Integer, String> names = new HashMap<>(); 
   
} 
 
class Customer { 
 
public static int x = 0; 
    Customer(String name) { 
 
        if(Mamam.names.containsKey(x)){ 
         
            Mamam.names.put(++x,name); 
        }else{ 
            Mamam.names.put(x,name); 
        } 
 
    } 
 
} 
 
 
 
public class test { 
 
 
    public static void main(String[] args) { 
 
        Customer asd = new Customer("Ivan"); 
        Customer asd2 = new Customer("Petr"); 
        Customer asd3 = new Customer("Vasya"); 
        Customer asd4 = new Customer("Ilya"); 
        Customer asd5 = new Customer("Vasya2"); 
        Customer asd6 = new Customer("Oleg"); 
        System.out.print(Mamam.names); 
        System.out.println(Mamam.names.size()); 
 
 
 
 
    } 
    }

READ ALSO
Ошибка в алгоритме выявление 2ух минимальных чисел в массиве

Ошибка в алгоритме выявление 2ух минимальных чисел в массиве

Формат ввода Первая строка входного файла содержит целое число N — количество дроидов (), вторая строка — N целых чиселФормат вывода Выведите...

183
JAVA, IntelliJ IDEA и ошибка Exception in thread &ldquo;AWT-EventQueue-0&rdquo; java.lang.NullPointerException

JAVA, IntelliJ IDEA и ошибка Exception in thread “AWT-EventQueue-0” java.lang.NullPointerException

Я очень, очень глупый новечёкУ меня есть ошибка но нет решения(((( A Google отказываеться помогать(((( Пожалуйста, сделайте это за него

173
JDA Discord. Бот ожидает ответа от юзера

JDA Discord. Бот ожидает ответа от юзера

Пишу Discord бот с помощью библиотеки JDA и столкнулся с достаточно банальной проблемой

163
Как проверить существование видео youtube?

Как проверить существование видео youtube?

Например, есть поле ввода для ссылки, пользователь вводит и нажимает добавить, и если видео существует, то возврощает true

136