Java определяет членов класса с помощью конечного массива

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

final String[] names = new String[]{"familyNames", "givenNames", "middleNames", "nickNames", "additionalNames", ..., ..., ..., ...}; // Lots of definitions

И теперь мне нужно создать новый класс с этими определениями:

public class Person {
  final private String id;
  final private String familyNames;
  final private String givenNames;
  final private String middleNames;
  final private String nickNames;
  final private String additionalNames;
  ...
  ...
  ...
  ...
  ... // Very long list
}

Можно ли определить этот класс этим массивом? Что-то типа:

public class Person {
  final private String id;
  final private .... names...
  public int compareTo(...) {...}
}

Этот класс Person должен поддерживать сортировку по нескольким полям, например. сначала по имени, потом по фамилии и т.


person Deqing    schedule 20.12.2013    source источник
comment
Сохраняете ли вы только строки или будут смешаны другие типы, к которым вам нужно получить доступ как к этому типу (т. е. выполнить математические операции с целым числом/плавающим числом, получить следующий месяц из даты и т. д.). )? Для сортировки вам необходимо реализовать Comparable, используя ответ @Juned.   -  person Clockwork-Muse    schedule 20.12.2013


Ответы (2)


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

Map<String,String> attributesMap = new HashMap<String,String>();

В качестве ключей следует использовать "familyNames", "givenNames", "middleNames", "nickNames", "additionalNames" и т.д.

person Juned Ahsan    schedule 20.12.2013
comment
Вероятно, лучший вариант для тех, кто не создает компилятор для Java... :) - person cHao; 20.12.2013
comment
Только что обновил свой вопрос. Требуется отсортировать Person объектов по нескольким полям. Похоже, мне нужно добавить CompareTo() в класс, но не знаю, как это сделать на основе карты? - person Deqing; 20.12.2013

Вы можете определить его в классе Person, взяв attributeMap в статическом фабричном методе.

public class Person {
  final private String id;
  final private Name name;
  ...
  public static Person fromAttributesMap(Map<String, String> attributesMap) {
      Person person = new Person();
      person.id = attributesMap.get("id");
      ...
  }
}

Но держите связанные атрибуты вместе в своих классах. Например; вы можете объединить familyName, givenName, nickName и т. д. в класс Name:

class Name {
  final private String familyName;
  final private String givenName;
  final private String middleName;
}

Я не полностью согласен с картографическим подходом. На самом деле вокруг того же запаха кода - это называется "Примитивная одержимость"

Вы также можете отсортировать List<Person>, например, по фамилии:

public static Comparator<Person> FamilyNameComparator 
                      = new Comparator<Person>() {

    public int compare(Person person1, Person person2) {


      //ascending order
      return person1.getFamilyName().compareTo(person2.getFamilyName());
    }

};

а затем вызов:

Arrays.sort(persons, Person.FamilyNameComparator);

Вы также можете сортировать по нескольким полям. Взгляните на этот вопрос о SO.

person aquaraga    schedule 20.12.2013
comment
Как программа должна знать, что поля X, Y, Z... из массива на самом деле находятся в подобъекте? Как этот материал должен генерироваться автоматически, поскольку вопрос, кажется, задается? - person cHao; 23.12.2013
comment
Путем реализации соответствующего конструктора или фабричного метода, такого как fromAttributeMap(). Я, вероятно, обновлю свой ответ; но я по-прежнему придерживаюсь своих оговорок против прямого использования хэш-карты. - person aquaraga; 23.12.2013
comment
@cHao Я не совсем уверен, хотел ли ОП моделировать специальные / случайные строки в массиве имен. Я, вероятно, обновлю свой ответ (и расскажу об использовании фабричного метода). - person aquaraga; 23.12.2013