Badałem transformację obiektu z jednego rodzaju klasy na inny przy użyciu języka Java 8. Mam pakiet klas XxX generowanych przez jaxb. Klasy nie mają wystarczająco przyjaznej struktury, ponieważ mapują strukturę XML bardziej niż strukturę obiektu biznesowego. Nie chcę edytować wygenerowanych klas, ponieważ lubię je regenerować za każdym razem, gdy zmienia się schemat bez martwienia się o zachowywanie dostosowań.Przekształcanie klas za pomocą Javy 8
Mam coś podobnego schematu:
<xs:element name="farm">
<xs:sequence>
<xs:element ref="animal" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:element>
<xs:element name="animal">
<xs:complexType>
<xs:sequence>
<xs:element ref="goat"/>
<xs:element ref="sheep"/>
</xs:sequence>
<xs:complexType>
</xs:element>
<xs:element name="goat">
<xs:complexType>
<xs:sequence>
goat fields
</xs:sequence>
<xs:complexType>
</xs:element>
<xs:element name="sheep">
<xs:complexType>
<xs:sequence>
sheep fields
</xs:sequence>
<xs:complexType>
</xs:element>
Generuje to coś jak Java:
class Farm
public List<Animal> getAnimals()
class Animal
public Goat getGoat()
public String getGoatField()
public Sheep getSheep()
public String getSheepField()
getGoat
i getSheep
może zwrócić null, ale nie mogą one być zarówno wartość null. Podobnie przynajmniej jeden z nich musi mieć wartość zerową. Jest to wymuszane przez reguły biznesowe i ograniczenia bazy danych, ale nie w xml (chociaż jeśli ktoś ma sugestię strukturyzowania xml bardziej jak pożądane VO, ja jestem tylko uszami)
Chciałbym przekształcić tę klasę w
class FarmWrapper
public ArrayList<AnimalVO> getAnimals()
//optional features tbd
//possibly public ArrayList<GoatVO> getGoats()
//possibly public ArrayList<SheepVO> getSheep()
class GoatVO extends AnimalVO
class SheepVO extends AnimalVO
Mój pomysł był aby zrobić coś takiego:
herd.stream()
.filter(Objects::nonNull)
.map(a -> {
Optional<AnimalVO> goatVO = Optional.ofNullable(a.getGoat())
.map(g -> new GoatVO(g.getGoatField()));
Optional<AnimalVO> sheepVO = Optional.ofNullable(a.getSheep())
.map(s -> new SheepVO(s.getSheepField()));
return goatVO.orElse(sheepVO.get());
})
.collect(Collectors.toList());
teraz byłem karmienie go z listy, a gdy tylko napotka null owce, to rzuca NoSuchElementException
.
Chyba kilka pytań:
- Czy to podejście warto podzielić moją listę do klas, które używają dziedziczenia?
- Jaki jest najlepszy sposób na wykorzystanie Opcjonalnie w celu ochrony przed przychodzących wartości potencjalnie NULL, gdy nie można zmienić klas przekazując Ci null
- Co mi brakuje z
goatVO.orElse(sheepVO.get())
pracuje tak długo, jak goatVO zawiera wartość null, a następnie rzucaNoSuchElementException
gdy jest sheepVO zawiera wartość null
Co naprawdę robię, to pracuję z wygenerowanym kodem jaxb i próbuję wziąć wygenerowane klasy i sprawić, że będzie on bardziej przyjazny. Tradycyjnie projekt wykorzystywał klasę wrapper, która przekształca wygenerowane klasy w VO poprzez znaczną ilość kontroli zerowych i int do manipulacji typu BigInteger.
Edycja wygenerowanych klas (kozie, owcze, zwierząt) to nie rozrusznik, ponieważ chciałbym, aby zachować zdolność do regeneracji bez martwienia
Dlaczego potrzebujesz 'GoatVO' lub' SheepVO' zamiast tylko 'Kóz' i' Owca'? –
Twoje ostatnie pytanie jest podobne do tego: http: // stackoverflow.com/questions/31657306/java-8s-orelse-not-working-as-expected/31657522 # 31657522 – Alex
Edytowałem pytanie, aby dodać więcej informacji o tym, co próbuję wykonać i jakie są moje ograniczenia: – monknomo