0

Assume I have two classes:

class 1:

class Person{
    String name;
    int age;
    public Person(){}
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Override
    String toString(){
        return "Name: "+name + "\tAge: "+age;
    }
}

class 2

class Animal{
    String name;
    int age;
    public Animal(){}
    public Animal(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Override
    String toString(){
        return "Name: "+name + "\tAge: "+age;
    }
}

And I create a List Object to stored 2 classes Person and Animal

List newList = new ArrayList<>();
newList.add( new Person("person", 20);
newList.add( new Person("aPerson",20);
newList.add( new Animal("animal",20);
newList.add( new Animal("aAnimal",20);

Now i want sort newList by name but i don't know how to do it. With one Class I can Create Class SortByName and compare name between two Object, But with two Class i can not

Stack
  • 111
  • 6
  • 1
    You would need to create an abstraction. Example: `Entity` interface which contains a` getName () ` method that gets implemented by both entities. So you can use that type in the `compare` method. – CodeMatrix Apr 24 '20 at 08:01
  • Base class say NamedObject they both depend on would be one way. – Tony Hopkinson Apr 24 '20 at 08:01

3 Answers3

2

What you need is an Interface. Both your Animal and Person class offer name as one of their properties, so you can have an Interface say Nameable in this regard to essentially specify that your class definitely has name property.

You'll code to the Nameable interface so as to create a list of Nameable's and you can create a sorter on that list.

List<Nameable> list = new ArrayList<>();
newList.add( new Person("person", 20);
newList.add( new Person("aPerson",20);
newList.add( new Animal("animal",20);
newList.add( new Animal("aAnimal",20);

list.sort(new Comparator<Nameable>() {
    public int compare(Nameable o1, Nameable o2) {
        return o1.getName().compareTo(o2.getName());
    }
});

The interface ans its usage:

Nameable.java

public interface Nameable {
    String getName();
}

public class Person implements Nameable {
   ...

   String getName() {
      return name;
   }

   ...
}

public class Animal implements Nameable {
   ...

   String getName() {
      return name;
   }

   ...
}
Pbd
  • 1,219
  • 1
  • 15
  • 32
1

An abstraction for that specific case is needed that holds all the information which both entities need. E. g. an interface called Entity which has the method getName().

Example:

public interface Entity {
    String getName();
}
public class Person implements Entity {

...
    @Override
    public String getName() {
        return name;
    }
}
public class Animal implements Entity {

...
    @Override
    public String getName() {
        return name;
    }
}

After you got this you can use it by type:

List<Entity> entities = new ArrayList<>();
entities.add(new Person("person", 20);
entities.add(new Person("aPerson", 20);
entities.add(new Animal("animal", 20);
entities.add(new Animal("aAnimal", 20);
entities.sort((o1, o2) -> o1.getName().compareTo(o2.getName());

It would also be possible to use an abstract class.

CodeMatrix
  • 2,124
  • 1
  • 18
  • 30
  • entities.sort((o1, o2) -> o1.getName().compareTo(o2.getName()); – Stack Apr 24 '20 at 08:21
  • It is a lambda expression that does the same as the example from @Pdb. In this case, it overwrites the `compare` method of the `Comparator`. Check [this](https://stackoverflow.com/a/53633161/8052043) or [this](https://stackoverflow.com/a/56183593/8052043). – CodeMatrix Apr 24 '20 at 08:25
  • yep, I did try it, and I know it is short ways to Overwrites compare, but the first time I see it, Thank you so much – Stack Apr 24 '20 at 08:29
1

After creating a Base class/interface as suggested in other answers, you can sort as with Comparator.comparing,

newList.sort(Comparator.comparing(Entity::getName));
Vikas
  • 6,868
  • 4
  • 27
  • 41