I am using quite a similar method for 4, 5 screens basically to do same thing on List of different objects. Now I extracted that method to reuse it and make it generic. Now while making a list generic I face the issue with attributes. It’s attributes are no longer accessible when made generic. How to overcome this issue. Please note that for all the List
of T
objects I will have those attributes i.e "GoodsIssueToPerson", "getProductId()"
My attempt:
@NonNull private <T> List<T> getSelectedGoodsList(List<T> objectList) { List<T> modifiedGoodsToSellerList = objectList; for (int i = 0; i < productSections.size(); i++) { ProductRowItem rowItem = productSections.get(i); T goodsEntity = getGoodsIssuePersonsEntity(rowItem.getProductId(), modifiedGoodsToSellerList); Double quantity = parseGermanToDecimal(rowItem.getQuantity()); if (goodsEntity != null && quantity > 0) { setUpdatedQuantity(goodsEntity, quantity); } } // remove items if quantity is 0 modifiedGoodsToSellerList.removeIf(x -> x.GoodsIssueToPerson < 1); return modifiedGoodsToSellerList; } @Nullable private <T> T getGoodsIssuePersonsEntity(int productId, List<T> objectList) { Optional<T> matchingObject = objectList.stream(). filter(p -> p.getProductId() == productId). findFirst(); return matchingObject.orElse(null); } private <T> void setUpdatedQuantity(T goodsEntity, List<T> objectList, Double quantity) { int indexExistingData = objectList.indexOf(goodsEntity); goodsEntity.GoodsIssueToPerson = quantity; if (indexExistingData != -1) { objectList.set(indexExistingData, goodsEntity); } }
Snapshot of issues: As seen in screenshot x.GoodsIssueToPerson
is not accessible, same as p.getProductId
and etc. For the objects which i will use this method all will have those attributes.
Any suggestion, any help will be appreciated.
Advertisement
Answer
I wanted to expand on my comment which suggested
Add a typebound to T, e.g. T extends YourClass that has the GoodsIssueToPerson field and/or the getProductId method.
While this may hold true to your current use case, what if T
has no common base class ? One should not create an inheritance hierarchy just because of a chosen abstraction – it should be the other way round.
There are multiple solutions to this problem:
- use an
interface
on all classes and thus create a common type bound - pass a
Function<T, WantedData>
to your generic functions which extract the required data
The second variant is useful when you cannot modify the classes of the passed types (e.g. they are framework objects).
There is nothing wrong with a common base class
though.