2017-07-11 7 views
1

Ich habe viele bean igenerische Methode, generischer Typ unknow

In jeder Klasse Dto umwandeln möchte, ich tue so etwas wie

private List<AddressDto> convertsToDto(List<Address> addresses) { 

    List<AddressDto> addressesDto = new ArrayList<>(); 
    addresses.stream().map((address) -> convertToDto(address)).forEachOrdered((addressDto) -> { 
     addressesDto.add(addressDto); 
    }); 
    return addressesDto; 

} 

convertToDto in jeder Klasse sein würde .... aber für convertsToDto werde ich in ta abstrakter Klasse setzen, wo es jede Klasse wird erweitert und ein generisches convertsToDto Verfahren mit generischem Typ setzt

public abstract class BaseService { 
    public List<T> convertsToDto(List<R> beans) { 

     List<T> listDto = new ArrayList<>(); 
     beans.stream().map((bean) -> convertToDto(bean)).forEachOrdered((dto) -> { 
      listDto.add(dto); 
     }); 
     return listDto; 
    } 
} 

ich immer bekommen T und 0.123.ist unbekannt ... scheinen etwas zu verpassen.

+0

Vielleicht fügen T und R als Typ Parameter an die Funktion? aka "public Liste conversToDto (Liste Bohnen)" – Wietlol

+0

Generika werden zur Kompilierzeit gelöscht. Zur Laufzeit ist es immer eine Objektliste. Sie sollten den Typ als Parameter übergeben. – PeterMmm

+0

Warum müssen Generika verwendet werden? Warum verwenden Sie nicht einfach Ihre abstrakten Basisklassen? – fujy

Antwort

3

Beginnen Sie mit dem Hinzufügen von T und R Typ-Parameter zu Ihrer generischen Methode. Dies wird jedoch nicht funktionieren, weil convertToDto(bean) undefined bleiben würde.

Sie haben mehrere Möglichkeiten:

  • Sie könnten Bean-Schnittstelle definieren ihre DTO zu produzieren, oder
  • Sie könnten eine Bean-to-DTO Funktion Objekt übergeben. Hier

ist der erste Ansatz:

interface Bean<T> { 
    T convertToDto(); 
} 
public abstract class BaseService { 
    public <T,R extends Bean<T>> List<T> convertsToDto(List<R> beans) { 
     return beans.stream().map((b) -> b.convertToDto()).collect(Collectors.toList()); 
    } 
    ... // Additional methods 
} 

Hier ist der zweite Ansatz:

public abstract class BaseService { 
    public <T,R> List<R> convertsToDto(List<T> beans, Function<T,R> convert) { 
     return beans.stream().map((b) -> convert.apply(b)).collect(Collectors.toList()); 
    } 
} 
+0

von der ersten Option, in meiner Klasse, wenn ich versuche, Methode convertsToDto aufzurufen, bekomme ich: Methode ConvertsToDto in der Klasse BaseService kann nicht auf bestimmte Typen angewendet werden; erforderlich: Liste gefunden: Liste

Grund: Inferenz Variable R inkompatibel Grenzen Gleichheitsbedingungen: Adresse oberen Grenzen: Bean wobei R, T sind Typ-Variablen: R erweitert Bean in Methode deklariert convertsToDto (Liste ) T extends Objekt deklariert in Methode convertsToDto (Liste ) –

+0

@roberttrudel Es sieht aus wie Ihre 'Bean'-Schnittstelle ist anders - es braucht zwei Parameter, nicht einen. Die erste Lösung verwendet einen Parameter "T", der dem Ziel-DTO-Typ entspricht. Mit anderen Worten, wenn Ihr Ziel-DTO für "Address" "AddressDto" ist, dann muss "Address" "Bean " implementieren. – dasblinkenlight

+0

Ich denke, sollte etwas wie öffentliche T convertToDto (R r) haben; da der Eingabeparameter sollte anders sein als die Ausgabe –

1

Ihre BaseService-Klasse definiert diese generischen Typen nicht.

Try 
public abstract class BaseService<T, R> { 
... 
} 

public class AddressService extends BaseService<AddressDto, Address> { 
... 
} 
1

Sie können eine generische Schnittstelle wie Dto<T> verwenden, damit dies funktioniert.

Und können Sie Ihre allgemeine convertion Methode haben, wie folgt aussehen:

public <T extends Dto<R>> List<T> convertsToDto(List<R> beans) { 
} 

Ihre Dto Objekte wird die Schnittstelle implementieren sie auf das Objekt Basis abbildet.

Verwandte Themen