Разделить на списки на основе объекта, без instanceof - PullRequest
0 голосов
/ 07 сентября 2018

Я собираюсь идти прямо к делу.

Я получил 3 класса. Персона, профессор и студент. (Персона, Профессор, Выпускник). И профессор, и студент простираются от человека. Но Персона также может быть реализована, потому что она не абстрактна.

У меня есть 50 человек, случайно сгенерированных в списке. Это может быть любой человек, профессор или студент. Я хочу разделить их каждый в отдельный список.

На данный момент я сделал это:

for(Persona persona : personas) {
        if(persona instanceof Profesor) {
            profesores.add((Profesor) persona);
        }
        else if(persona instanceof Alumno) {
            alumnos.add((Alumno) persona);
        }
        else {
            nuevasPersonas.add(persona);
        }
    }

profesores - список профессоров

выпускники - это список студентов

nuevasPersonas - это список людей

Который работает идеально. Но мне сказали не использовать instanceof, поэтому я к этому не привыкаю.

Есть идеи, как разделить их на списки без использования instanceof?

Спасибо.

Ответы [ 4 ]

0 голосов
/ 07 сентября 2018

Вы можете перегрузить метод «add» для каждого из типов объектов - что-то вроде следующего кода.

Основной метод просто добавляет экземпляры трех разных объектов в класс ObjectSplitter - он разделяет их на разные коллекции

public class ObjectSplitter {

public static void main(String ... args){

    ObjectSplitter d = new ObjectSplitter();
    d.addToCollection(new Object1());
    d.addToCollection(new Object1());
    d.addToCollection(new Object2());
    d.addToCollection(new Object1());
    d.addToCollection(new Object1());
    d.addToCollection(new Object1());
    d.addToCollection(new Object2());
    d.addToCollection(new Object3());
    d.addToCollection(new Object1());

    System.out.println("Num Ob1s : " + d.getOb1sSize());
    System.out.println("Num Ob2s : " + d.getOb2sSize());
    System.out.println("Num Ob3s : " + d.getOb3sSize());

}

private List<Object1> ob1s = new ArrayList<>();
private List<Object2> ob2s = new ArrayList<>();
private List<Object3> ob3s = new ArrayList<>();

void addToCollection(Object1 o){
    ob1s.add(o);
}

void addToCollection(Object2 o){
    ob2s.add(o);
}

void addToCollection(Object3 o){
    ob3s.add(o);
}

int getOb1sSize(){
    return ob1s.size();
}

int getOb2sSize(){
    return ob2s.size();
}

int getOb3sSize(){
    return ob3s.size();
}

static class Object1 {

}


static class Object2 extends Object1 {

}

static class Object3 extends Object2 {

}

}

0 голосов
/ 07 сентября 2018

также вы можете использовать getClass (). GetSimpleName () как показано ниже:

public static void main (String[] args) throws java.lang.Exception
{
    List<Test1> list = new ArrayList<>(2);
    Test1 o1 = new Test1();
    list.add(o1);
    Test2 o2 = new Test2();
    list.add(o2);
    for (Test1 test : list) {
        System.out.println(test.getClass().getSimpleName());
    }
}
static class Test1{

}
static class Test2 extends Test1{

}

в цикле for у вас может быть условие if, как показано ниже для вашей работы:

for (Test1 test : list) {
    String className = test.getClass().getSimpleName();
    if(className.equals("Test1")) {
       System.out.println("Test1");
    } else if(className.equals("Test2")) {
       System.out.println("Test2");
    }
    System.out.println();
}

другое решение в соответствии с переопределенными методами:

public static void main (String[] args) throws java.lang.Exception
{
    List<Test1> list = new ArrayList<>(2);
    Test1 o1 = new Test1();
    list.add(o1);
    Test2 o2 = new Test2();
    list.add(o2);
    for (Test1 test : list) {
        test.addToMyTypeList();
    }
    for(Test1 test : Test1.list) {
        System.out.println(test.getClass().getSimpleName());
    }
    for(Test1 test : Test1.list) {
        System.out.println(test.getClass().getSimpleName());
    }
}
static class Test1{
    public static List<Test1> list = new ArrayList<>();
    public void addToMyTypeList() {
        String className = test.getClass().getSimpleName();
        if(className.equals("Test1")) {
                    Test1.list.add(this);
        }
    }
}
static class Test2 extends Test1{
    public static List<Test1> list = new ArrayList<>();

    @Override
    public void addToMyTypeList() {
        String className = test.getClass().getSimpleName();
        if(className.equals("Test2")) {
                    Test2.list.add(this);
        }
    }
}
0 голосов
/ 07 сентября 2018

Возможно, ваш учитель хочет, чтобы вы создали переопределенный метод , который отвечает на вопрос isStudent или isProfessor?

Однако, поскольку это не дает нам никакой дополнительной информации, которая еще не доступна через оператор instanceof, это надуманный пример, когда добавление этих избыточных методов на самом деле не является хорошим дизайнерским решением. К сожалению, в начальных классах вы иногда сталкиваетесь с такими надуманными примерами, которые чрезмерно упрощены с целью обучения определенной языковой концепции.

0 голосов
/ 07 сентября 2018

Я бы использовал instanceof, почему бы вам не захотеть привыкнуть к нему?

В любом случае, альтернативой может быть переменный тип (с getter, но без setter), Person (= 0) и переопределить его на 1 и 2 в Professor и Student. Затем вы бы протестировали переменную вместо использования instanceof.

...