Как добавить объект в другой набор объектов

У меня два класса. Один (человек) для геттеров и сеттеров, а другой (люди) для вычисления данных. Какова моя ситуация: я получаю данные из БД, используя ResultSet, а затем создал объект человека для хранения данных строки. Затем я создал объект people для хранения всех людей.

Каждый объект, созданный как SET.

while(rs.next())
{
    Set<People> people = new HashSet<people>();
    Person person = new Person();
    String name = rs.getString(2);
    person.setName(name);
    int id = rs.getInt(1);
    person.setId(id);
    String dept = rs.getString(4);
    person.setDept(dept);
    int age = rs.getInt(3);
    person.setAge(age);
    people.add(person);
}
return people;

Теперь проблема в последней строке цикла While people.add(person);.

Это говорит

Метод add(People) в типе Set неприменим для аргументов (Person)

Как я могу преодолеть эту проблему?

Спасибо.


person Community    schedule 23.08.2010    source источник


Ответы (6)


Насколько я понимаю из вашего дизайна, у вас есть отношение People has-many Person, поэтому класс People содержит набор объектов Person. Тогда я ожидал бы что-то вроде этого:

public class Person {
  private String name;
  private Date dateOfBirth;
  // .. more attributes

  // getters and setters

  // overrides of equals, hashcode and toString
}

public class People implements Set<Person> {
  private Set<Person> persons = new HashSet<Person>();

  public boolean add(Person person) {
    return persons.add(person);
  }

  // more methods for remove, contains, ...
}

Таким образом, в вашем коде, связанном с базой данных, вам не нужно создавать еще один набор, потому что People уже имеет тот, который вам нужен:

People people = new People();  // or get it, if it's already created
while(rs.next())
{
    Person person = new Person();
    String name = rs.getString(2);
    person.setName(name);
    int id = rs.getInt(1);
    person.setId(id);
    String dept = rs.getString(4);
    person.setDept(dept);
    int age = rs.getInt(3);
    person.setAge(age);
    people.add(person);
}
return people;
person Andreas Dolk    schedule 23.08.2010

Я не понимаю, почему вы хотите 2 класса в первую очередь. Вы также можете заставить Person реализовать вычислительную часть. Но, тем не менее, что можно было сделать:

class People implements Set<Person> {

private HashSet<Person> hashset = new HashSet<Person>();

// ... your computational code goes here
// delegate all Set methods to hashset
}

а потом:

People people = new People();
while(rs.next())
{
    Person person = new Person();
    String name = rs.getString(2);
    person.setName(name);
    int id = rs.getInt(1);
    person.setId(id);
    String dept = rs.getString(4);
    person.setDept(dept);
    int age = rs.getInt(3);
    person.setAge(age);
    people.add(person);
}
return people;
person drstupid    schedule 23.08.2010
comment
Согласен. Если бы люди делегировали HashMap вместо наследования, было бы лучше :) - person 卢声远 Shengyuan Lu; 23.08.2010
comment
Правильный. Хотя можно было и порассуждать :) - person drstupid; 23.08.2010

Я понимаю, что Person — это структура данных (bean-подобная, с геттерами и сеттерами), а People должна содержать все Person объекты из базы данных и выполнять над ними вычисления.

Если это так, то, во-первых, вы не можете объявлять людей внутри цикла (поскольку для каждого Person будет создаваться новый объект People, а вы этого не хотите, насколько я понимаю).

Во-вторых, People должен содержать объекты Person. Так что он должен состоять как минимум из Set из Person объектов. Вы можете добавить дополнительные функции по своему усмотрению. Итак, попробуйте что-то вроде этого:

public class People {

    Set<Person> persons = new HashSet<Person>();

    Set<Person> getPersons() {
        return persons;
    }

    int computeSomethingAboutPeople() { 
        // return as you please
    }

}

И используйте это так, как предложил предыдущий постер:

People people = new People();
while(rs.next())
{
    Person person = new Person();
    String name = rs.getString(2);
    person.setName(name);
    int id = rs.getInt(1);
    person.setId(id);
    String dept = rs.getString(4);
    person.setDept(dept);
    int age = rs.getInt(3);
    person.setAge(age);
    people.getPersons().add(person);
}
int answer = people.computeSomethingAboutPeople();
person double-m    schedule 23.08.2010
comment
Пусть People реализует интерфейс Set. Затем вы можете использовать его как набор и не заставлять пользователя делать что-то вроде people.getPersons().add(person);. И если предоставить геттер для набора, не возвращайте внутренний набор, возвращайте Collections.unmodifiableSet(persons), чтобы никто не мог изменить внутренности. - person Andreas Dolk; 23.08.2010
comment
Спасибо за Ваш ответ. Мне это помогло. Но у меня другой вопрос. Должен ли я объявлять набор для класса Person. Например, Set‹Person› person = new HashSet‹Person›(); . - person ; 23.08.2010

Основываясь на том, что вы пытаетесь сделать, я чувствую, вы должны преобразовать свой класс Person в People перед добавлением в набор. В вашем классе People может быть конструктор, который принимает Person в качестве аргумента и копирует необходимые поля из Person в People. Здесь ваш код для добавления в набор будет выглядеть как people.add(new People(person));

Когда вы объявляете Set<People> people = new HashSet<People>();, это означает, что этот набор должен содержать объекты «типа» People, то есть экземпляры People или экземпляры подклассов People. Если People — это интерфейс, то набор может содержать любой объект, реализующий интерфейс.

person Gopi    schedule 23.08.2010

Я не думаю, что Set<People> people = new HashSet<people>(); нужно писать в цикле.

person 卢声远 Shengyuan Lu    schedule 23.08.2010
comment
Большая проблема связана со строкой people.add(person);. В объявлении просто опечатка - person drstupid; 23.08.2010
comment
Да, я только что упомянул об этом там... На самом деле это не объявлено там. - person ; 23.08.2010

person    schedule
comment
Пожалуйста, рассмотрите возможность добавления некоторых объяснений. - person Sunil; 18.02.2018