Java pass class variable inside Diamond operator

Viewed 836

I have a doubt in a Java project:

public class example {

   public Data getData() {
        List<Users> users = usersService.findByClinicId(id);
        Type targetListType = new TypeToken<List<UserDTO>>() {}.getType();
        List<UserDTO> usersDTO = modelMapper.map(users, targetListType);

        List<Personas> profesionales = personasService.findProfesionalsByClinicId(id);
        targetListType = new TypeToken<List<PersonaDTO>>() {}.getType();
        List<PersonaDTO> profesionalesDTO = modelMapper.map(profesionales, targetListType);

        List<Personas> auxiliares = personasService.findAuxiliarsByClinicId(id);
        targetListType = new TypeToken<List<PersonaDTO>>() {}.getType();
        List<PersonaDTO> auxiliaresDTO = modelMapper.map(auxiliares, targetListType);

        List<Prescripciones> prescripciones = prescripcionesService.findProfesionalsByClinicId(id);
        targetListType = new TypeToken<List<PrescriptionNameDTO>>() {}.getType();
        List<PrescriptionNameDTO> prescripcionesDTO = modelMapper.map(prescripciones, targetListType);

       profesionales = entityToDTO(PersonaDTO.class, profesionales);

    ...
   }

    private <T> List<T> entityToDTO(Class<T> clazz, List<T> list) {
        Type targetListType = new TypeToken<List<clazz>>() {}.getType();
        List<PersonaDTO> auxiliaresDTO = modelMapper.map(list, targetListType);

    }
}

The idea is to reduce the code of the getData function using the entityToDTO function.

The problem I have is:

  • In the method entityToDTO, I want to pass in TypeToken first parameter the type of List that I want, but it doesn't accept List, where clazz is the variable that has the Class name.

Is there a way to pass inside the List diamond operator a variable with the type of class I want to use?

UPDATE: The idea is to reduce the number of lines of getData function.

3 Answers

Why not pass the Type instead?

private <T> List<T> entityToDTO(Type type, List<T> list) {
     return modelMapper.map(list, type);
}

And on the caller side, for example:

Type typeToUse = TypeToken.getParameterized(List.class, UserDTO.class).getType();

you can update your entityToDTO method as follow :

public static <D, T> List<D> entityToDTO(final Collection<T> sourceList, Class<D> destinationCLass) {
        if (Objects.isNull(sourceList)) {
            return null;
        }
        return sourceList.stream().map(entity -> modelMapper.map(entity, destinationCLass))
            .collect(Collectors.toList());

   }

I think, to reduce getData() you should add filtering.

  1. Create search request object with set of variable for filtering
  2. Put it to the database
  3. Build SQL: SearchRequest -> SQL
  4. Retrieve only that data from DB, that you want.

This is general approach:

class SearchDataRequest {
   private String id;
   private Type type;
   //... other parameters 
}

public Data getData(SearchDataRequest request) {
    return reposiotry.getDataByFilter(request);
}

DAO Layer:

public Data getDataByFilter(SearchDataRequest request) {
    String sql = buildSqlForRequest(request);
    return executeSql(sql);
}
Related