Как реализовать класс enum с несколькими строковыми атрибутами, которые могут повторяться? - PullRequest
0 голосов
/ 23 февраля 2019

В качестве переподготовки фона в ООП с Java я пытался решить проблему с дизайном:

У меня есть несколько имен людей, а также атрибуты name, age и профессия.Я хочу реализовать класс перечисления ListOfPersons, который действует как база данных со всей этой информацией.Единственная проблема состоит в том, что большая часть данных в этом списке является дубликатами, поэтому, например, может быть две или три записи для атрибутов возраста и рода занятий.

Example:
Enum object one- 
Name: Joe
Age: 40
Age: 41
Occupation: Engineer
Occupation: Software Engineer

Для Джо видно, что есть две записи о возрасте и две записи о профессии.

Example 2:
Enum object two- 
Name: Judy
Age: 55
Age: 65
Occupation: Judge

В примере 2 это возраст, который отображается дважды.

Дело в том, что есть несколько таких записей, которые должны быть реализованы в классе enum. Каков оптимальный способ его настройки (мой список лиц) с намерением перейти на TreeMap или HashMap (или есть лучшая структура данных, которая может служить в качестве базы данных для поиска пользователей?люди)?

Проблема в том, что я не уверен, как учесть эти случайные повторяющиеся записи, которые затрудняют последующее включение в структуру данных.

public enum ListOfPersons{
Joe("Joe", 40, 41, "Engineer", "Software Engineer"), Judy("Judy", 55, 65, 
"Judge")...etc.
//methods 
}

Ответы [ 4 ]

0 голосов
/ 23 февраля 2019

Не уверен, если это то, что нужно, но, возможно, есть некоторые полезные советы в коде ниже

import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.Map;
import java.util.TreeMap;

public class Test {
    public static void main(String[] args) {
        // load some test data
        Set<Integer> joesAges = Person.JOE.getAges();
        joesAges.add(21);
        joesAges.add(34);
        joesAges.add(43);

        Set<String> joesOccupations = Person.JOE.getOccupations();
        joesOccupations.add("Engineer");
        joesOccupations.add("Software Engineer");
        joesOccupations.add("Mechanical Engineer");

        // .... and so on for all the names in Person enum

        String searchTerm = "joe occupation"; // hardcoded search terms, it should be replaced with user's input
        String searchTermSeparator = " ";
        int indexOfSearchTermsSeparator = searchTerm.indexOf(searchTermSeparator);
        String searchName = searchTerm;
        String searchDetails = "age"; // initialze with age as default option for search, if user only types a name
        if (indexOfSearchTermsSeparator > -1) {
            searchName = searchTerm.substring(0, indexOfSearchTermsSeparator);
            searchDetails = searchTerm.substring(indexOfSearchTermsSeparator + 1);
        }
        try {
            Person person = Person.valueOf(searchName.toUpperCase());
            if ("age".equals(searchDetails)) {
                // list all ages for searched name
                String agesString = person.getAges()
                                          .stream()
                                          .map(age -> {return "" + age;})
                                          .collect(Collectors.joining( ", age: " ));

                System.out.println(searchName + " age: " + agesString);
            } else {
                // list all occupations of searched name
                String occupationsString = person.getOccupations()
                      .stream()
                      .collect(Collectors.joining(", occupation: " ));

                System.out.println(searchName + " occupation: " + occupationsString);
            }
        } catch(Exception e) {
            System.out.println("Unknown name");
        }
    }
}
enum Person {
    JOE(new TreeSet<Integer>(), new TreeSet<String>()),
    JANE(new TreeSet<Integer>(), new TreeSet<String>()),
    JUDY(new TreeSet<Integer>(), new TreeSet<String>())
    //.... and so on for all the names
    ;

    private Set<Integer> ages;
    private Set<String> occupations;

    Person(Set<Integer> ages, Set<String> occupations) {
        this.ages = ages;
        this.occupations = occupations;
    }

    public Set<Integer> getAges() {
        return this.ages;
    }

    public Set<String> getOccupations() {
        return this.occupations;
    }

    public void reset() {
        this.ages = new TreeSet<>();
        this.occupations = new TreeSet<>();
    }
}
0 голосов
/ 23 февраля 2019

enum не подходит для вашего случая.Более простой подход состоит в том, чтобы иметь класс Person (с необходимыми полями), а затем переопределить методы equals() и hashCode() для включения имени в качестве уникального идентификатора (я предполагаю, что имя уникально, потому что вы пытались поместить его в качестве именив вашем перечислении пример).Затем вы создаете список экземпляров Person, используя ArrayList.

Чтобы позже обработать его в структуре данных, такой как Map (имя персонажа в качестве ключа, объект персоны в качестве значения), вы можете сделать:

Map<String, Person> personsMap = persons.stream()
  .collect(Collectors.toMap(Person::getName, Function.identity());

Затем получить: personsMap.get("Joe"), чтобы дать вам экземпляр Person

0 голосов
/ 23 февраля 2019

Я бы также порекомендовал Hashmap, но если вы застряли с Enum, вы можете сохранить их таким образом, как

public enum ListOfPersons{
Joe("Joe", "40,41","Engineer,Software Engineer"), Judy("Judy", "55,65","Judge")...etc.
//methods 
}

Таким образом, вы всегда получите 3 строки в качестве значения, а затем вы можете применитьпростая обработка строк для преобразования их в структуру данных

0 голосов
/ 23 февраля 2019

Извините за мой английский.

Как насчет использования пользовательского класса с HashMap?

вот так.

class Person {
    private List<Integer> ages;
    private String name;
    ...
    // getter setter..
    // equals hashcode..
}

Map<String, Person> maps = new HashMap<>();
maps.add("Joe", new Person(...));
map.get("Joe");
...

Почему вы должны реализовать его как перечисление?

...