newbie
newbie

Reputation: 107

Proper use of generics in list

I have the following problem and I hope someone can tackle this. The setting is me having Lists of different entity classes from a psql call. I have the following method that I want to apply to them. I want to extract the names of the object and save them in an array for further use. Note: Every class I want to use has a getName() method.

private String[] getNamesOfList(List<EntityClassA> list) {
      namesArray = new String[list.size()];
      for (int j = 0; j < list.size(); j++) {
          namesArray[j] = list.get(j).getName();
      }
      return Array;
}

Since I don't want to rewrite this method for every single class, I would like to use generics to generalize this. But I don't know how exactly. I have not worked with generics before and all the examples I have seen could not apply to this.

Upvotes: 4

Views: 117

Answers (3)

Puce
Puce

Reputation: 38132

With Java SE 8 (recommended if you use Oracle JRE unless you have support contracts with Oracle to get security updates for older Java versions) you can use:

private <T, R> List<R> map(List<T> list, Function<? super T, ? extends R> mapper) {
    return list.stream().map(mapper).collect(Collectors.toList());
}

And then:

List<EntityClassA> list = ...;
List<String> names = map(list, EntityClassA::getName);

With this code you can extract a list of any property from any list type.

As other mentioned, if you have a common interface such as

interface SuperInterface {
    String getName();
}

and only want to get names (no other properties) then you can use:

private List<String> getNames(List<? extends SuperInterface> list) {
    return list.stream().map(SuperInterface::getName).collect(Collectors.toList());
}

And then:

List<EntityClassA> list = ...;
List<String> names = getNames(list);

Upvotes: 1

Konstantin Yovkov
Konstantin Yovkov

Reputation: 62864

If the classes have a common super-class or interface, you can do:

private String[] getNamesOfList(List<? extends SuperInterface> list) {
      namesArray = new String[list.size()];
      for (int j = 0; j < list.size(); j++) {
          namesArray[j] = list.get(j).getName();
      }
      return namesArray;
}

If they don't, you can introduce one and make all the classes which expose a getName() method implement this interface:

interface SuperInterface {
    String getName();
}

Upvotes: 4

almeynman
almeynman

Reputation: 7408

Actually if all your entities have the same field, it is better to refactor it out

You can have a super class that all other entity classes extend:

public abstract class BaseEntity {
    private int id;
    private int name; 

    // creation date, modification date, if you need them

    //getters, setters
}

Then your entities would extend it. And then you can replace

private String[] getNamesOfList(List<EntityClassA> list) {

with

private String[] getNamesOfList(List<? extends BaseEntity> list) {

Upvotes: 0

Related Questions