I have a List of ServerPricing Object, which i want to group by offeringClass and payment option.
Tried below code , but failing. Advice please
Map<String, List<ServerPricing>> groupByOfferingClassPaymentOption =
serverPricingList.stream().collect(
p.getOfferingClass().getOfferingClassMapped()+ p.getPaymentOption().getPaymentOptionMapped(),
Collectors.groupingBy(
p -> Arrays.asList(p.getOfferingClass().getOfferingClassMapped(), p.getPaymentOption().getPaymentOptionMapped())));
and below is the server pricing class
public class ServerPricing implements Serializable {
#JsonIgnore
private Date createdDate;
private LeaseTerm leaseTerm;
private OfferingClass offeringClass;
private PaymentOption paymentOption;
private int serverAttributesId;
#Transient
private float price;
}
given
import org.apache.commons.lang3.tuple.Pair;
you could have the following
public static Map<Pair<OfferingClass, PaymentOption>, List<ServerPricing>> getServerPricingMap(
List<ServerPricing> serverPricingList) {
return serverPricingList.stream()
.collect(Collectors.groupingBy(serverPricing
-> Pair.of(serverPricing.getOfferingClass(), serverPricing.getPaymentOption())));
}
Related
Let's say that I have a list of dtos like:
#Builder(setterPrefix = "with")
#Data
public class ListWithDetailsRow {
String name;
LocalDateTime updatedAt;
LocalDateTime createdAt;
String customerId;
String listId;
String productName;
String productId;
Integer quantity;
LocalDateTime addedAt;
}
I would like to map the above one to the:
#Builder
#Getter
#Setter
#RequiredArgsConstructor
public class ListDetails {
private final String name;
private final String listId;
private final String customerId;
private final LocalDateTime createdAt;
private final LocalDateTime updatedAt;
private final List<ListProductDetails> products;
}
where ListProductDetails looks like:
#RequiredArgsConstructor
#Builder
#Getter
#Setter
public class ListProductDetails {
private final String productId;
private final Integer quantity;
private final LocalDateTime addedAt;
}
So far I have:
public List<ListDetails> groupListWithProductsById1(List<ListWithDetailsRow> listWithDetailsRows) {
return listWithDetailsRows.stream()
.collect(Collectors.groupingBy(ListWithDetailsRow::getListId))
.values()
.stream()
.flatMap(Collection::stream)
.map(sl -> new ListDetails(
sl.getName(),
sl.getListId(),
sl.getCustomerId(),
sl.getCreatedAt(),
sl.getUpdatedAt(),
newArrayList(
new ListProductDetails(
sl.getProductId(),
sl.getQuantity(),
sl.getAddedAt()))))
.collect(Collectors.toList());
but with this implementation, I am receiving List of ListDetails class
but the goal is to receive List with a flattened structure of products because they have the same id group.
I know that I can flat this product structure by using:
listDetails.stream().flatMap(sl -> sl.getProducts().stream()).collect(Collectors.toList())
but I don't know how to use it properly after the groupingBy() operation. Will be grateful for suggestions. Cheers!
If I understand correctly, you want to do:
public List<ListDetails> groupListWithProductsById1(List<ListWithDetailsRow> listWithDetailsRows) {
return listWithDetailsRows.stream()
.collect(Collectors.groupingBy(ListWithDetailsRow::getListId)).values().stream()
.map(rows ->
new ListDetails(
rows.get(0).getName(),
rows.get(0).getListId(),
rows.get(0).getCustomerId(),
rows.get(0).getCreatedAt(),
rows.get(0).getUpdatedAt(),
rows.stream().map(row -> new ListProductDetails(
row.getProductId(), row.getQuantity(), row.getAddedAt()
)).collect(Collectors.toList())
)
).collect(Collectors.toList());
}
After grouping by the list ID, you have a Collection<List<ListWithDetailsRow>> as the values() of the returned map. Each of the lists in the collection represents a group.
You can then map each group to a ListDetails. The name, listId, customerId, createdAt and updatedAt fields of the ListDetails can be taken from an arbitrary element in the group (I've chosen the first one), since every element should have the same values for those fields.
For the products field, just map the ListWithDetailsRows to ListProductDetails and collect to a list.
I have a structure that looks like this for RechargeResponse Model:
public class RechargeResponse {
private String code;
private String status;
private Set<OperatorWiseCircles> payload;
// setter and getters
}
here is the OperatorWiseCircles Model
public class OperatorWiseCircles {
private String operatorName;
private String operatorId;
private List<CircleWisePlan> circleWisePlanLists;
//setter and getters
}
CircleWisePlan Model class
public class CircleWisePlan {
private String circleName;
private String circleId;
}
Below is the sample json which we need to flattern.
{
"code": 200,
"status": "SUCCESS",
"payload": [
{
"operatorName": "VODAFONE",
"operatorId": "VF",
"circleWisePlanLists": [
{
"circleName": "C1",
"circleId": "1"
},
{
"circleName": "C2",
"circleId": "2"
}
]
}
]
}
I am expecting this to be flattern and map it to Entity object, so that I can add all these iteration to Hashset and save them all to DB, I want to do it using java8 stream. I how can I do it efficiently. I didnt get the right example, to parse nested json values and create entities for it using map/ flatmap.
Result should be like
Eg: ["VODAFONE","VF","C1", "1"]--->
ENTRY1
["VODAFONE","VF","C2", "2"] ---> ENTRY2
#Entity
public class RechargePlanEntity extends Audit<String>{
#Id
#Column(name="id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name="operator_name")
private String operatorName;
#Column(name="operator_id")
private String operatorId;
#Column(name="circle_name")
private String circleName;
#Column(name="circle_id")
private String circleId;
}
Truth is I'm sure is there any easy way to do this, Yet you can follow something like this,
Here in this example I have created utility class to map OperatorWiseCircles class to List<RechargePlanEntity>.
public class Main {
public static void main(String[] args) throws IOException {
String s = "{\"code\":200,\"status\":\"SUCCESS\",\"payload\":[{\"operatorName\":\"VODAFONE\",\"operatorId\":\"VF\",\"circleWisePlanLists\":[{\"circleName\":\"C1\",\"circleId\":\"1\"},{\"circleName\":\"C2\",\"circleId\":\"2\"}]}]}";
ObjectMapper om = new ObjectMapper();
RechargeResponse response = om.readValue(s, RechargeResponse.class);
List<RechargePlanEntity> collection = response.getPayload()
.stream()
.map(MapUtil::toEntity)
.flatMap(Collection::stream)
.collect(Collectors.toList());
System.out.println(collection);
}
}
#Getter
#Setter
#ToString
class RechargePlanEntity {
private Long id;
private String operatorName;
private String operatorId;
private String circleName;
private String circleId;
}
#Getter
#Setter
class RechargeResponse {
private String code;
private String status;
private Set<OperatorWiseCircles> payload;
}
#Getter
#Setter
class OperatorWiseCircles {
private String operatorName;
private String operatorId;
private List<CircleWisePlan> circleWisePlanLists;
}
#Getter
#Setter
class CircleWisePlan {
private String circleName;
private String circleId;
}
final class MapUtil {
public static List<RechargePlanEntity> toEntity(OperatorWiseCircles in) {
return in.getCircleWisePlanLists()
.stream()
.map(MapUtil::map)
.peek(out -> map(in, out))
.collect(Collectors.toList());
}
private static RechargePlanEntity map(CircleWisePlan in) {
RechargePlanEntity out = new RechargePlanEntity();
out.setCircleId(in.getCircleId());
out.setCircleName(in.getCircleName());
return out;
}
private static void map(OperatorWiseCircles in, RechargePlanEntity out) {
out.setOperatorId(in.getOperatorId());
out.setOperatorName(in.getOperatorName());
}
}
The entities without ids may be created from RechargeResponse model providing that the entity has all-args constructor:
RechargeResponse modelFromJson = ... //
List<RechargePlanEntity> entities = modelFromJson.getPayload()
.stream() // Stream<OperatorWiseCircles>
.flatMap(ows -> ows.getCircleWisePlanLists()
.stream() // Stream<CircleWisePlan>
.map(cwp -> new RechargePlanEntity(
null, // instead of id
ows.getOperatorName(),
ows.getOperatorId(),
cwp.getCircleName(),
cwp.getCircleId()
)) // Stream<RechargePlanEntity>
) // Stream<RechargePlanEntity>
.collect(Collectors.toList());
or, if a builder is implemented in the entity class (e.g. using Lombok's #Builder annotation), this conversion may look as follows:
List<RechargePlanEntity> entities = modelFromJson.getPayload()
.stream() // Stream<OperatorWiseCircles>
.flatMap(ows -> ows.getCircleWisePlanLists()
.stream() // Stream<CircleWisePlan>
.map(cwp -> RechargePlanEntity.builder()
.operatorName(ows.getOperatorName())
.operatorId(ows.getOperatorId())
.circleName(cwp.getCircleName())
.circleId(cwp.getCircleId())
.build()
) // Stream<RechargePlanEntity>
) // Stream<RechargePlanEntity>
.collect(Collectors.toList());
I'm trying to return the record that I got from my database. But I'm having a problem on how I can do that because the data than I retrieved from the database is in a different class from the return parameter.
public List<Record> getRecord(List<Request> requests) {
List<Record> records = new ArrayList<>();
for (Request request : requests) {
Billing billing = billingRepository
.findByBillingCycleAndStartDateAndEndDate(
request.getBillingCycle()
, request.getStartDate()
, request.getEndDate());
if (billing != null) {
// Need to add "billing" to "records" list here
}
}
return records;
}
Record.class
public class Record {
private int billingCycle;
private LocalDate startDate;
private LocalDate endDate;
private String accountName;
private String firstName;
private String lastname;
private double amount;
public Record() {
}
//Getters and setters
Billing.class
public class Billing {
private int billingId;
private int billingCycle;
private String billingMonth;
private Double amount;
private LocalDate startDate;
private LocalDate endDate;
private String lastEdited;
private Account accountId;
public Billing() {
}
//Getters and setters
What can I do? and please explain the answer so I can understand it. I really want to learn
You can use DozerMapper. It will map the object to another object having same name properties or you have to write the mapping in the dozer-mapping xml.
Lets come to your question. Here you are trying to convert your entity to another object.
For that you have to write mapping code. It will be something like this and it is very common practice to convert entity objects to another object before using them.
Record toRecord(Billing billing) {
if(billing == null) {
return null;
}
Record record = new Record();
record.setBillingCycle = billing.getBillingCycle();
...
...
// other properties
...
return record;
}
I have two classes that I mapped as RealmObject and I would like to do a query that will filter both the parent and the child.
The query will filter all the products that are greater than the passed date and inside it filter all the compras that have date greater than the passed date.
Is it possible with a query or I really need to execute the query for products and after take this List and remove the compras that I don't want ?
public class Produto extends RealmObject implements Id{
#PrimaryKey
private Long id;
#Index
#Required
private String codigoBarras;
private String nome;
private String marca;
private String categoria;
private String subCategoria;
private Double quantidade;
private String unidade;
private byte[] imagemData;
private Date dataAlteracao;
private RealmList<Compra> compras;
...
public class Compra extends RealmObject implements Id{
#PrimaryKey
private Long id;
//#LinkingObjects("compras")
private Produto produto = null;
private Double preco;
private String local;
private String mercado;
private Date data;
private Boolean liquidacao = false;
private String observacao;
private Date dataAlteracao;
...
public List<Produto> buscarProdutoEComprasPorDataAlteracao(Long dataAlteracao) {
RealmResults<Produto> results = realm.where(Produto.class)
.greaterThan("dataAlteracao", new Date(dataAlteracao))
.greaterThan("compras.dataAlteracao", new Date(dataAlteracao))
.sort("codigoBarras")
.findAll();
return realm.copyFromRealm(results);
}
//#LinkingObjects("compras")
private Produto produto = null;
You can replace this with
#LinkingObjects("compras")
private final RealmResults<Produto> isComprasOfProdutos = null;
Although if your current query doesn't work, unfortunately Realm-Java does not support SUBQUERY nor the ALL predicate, and https://github.com/realm/realm-java/issues/5730 was never added nor do I think they will ever add it, so you'll have to do this manually. :(
I'm trying to achive a findAllByUUID using mongo-spring-boot, but with no luck.
What I have:
public interface CarMatchRepository extends MongoRepository<CarMatchEntity, String> {
List<CarMatchEntity> findAllByCarID(Iterable<UUID> ids);
CarMatchEntity findByCarID(UUID carID);
}
Function call:
public void addCarsToCollection(String id, List<UUID> carId) {
List<CarMatchEntity> entities = carMatchRepository.findAllByCarID(carId); <--- empty
}
If I call findByCarID() it retrieves correctly a single object (if exists) but using Iterable the query does not fail, but it never returns any object. Am I doing something wrong here or am I taking the wrong road for this problem?
Thanks!
Edit:
#Document(collection = "car_index")
public class CarMatchEntity implements Serializable {
#Id
private String id;
private UUID carID;
//partner data
private UUID partnerID;
private String partnerThumbURL;
private String partnerName;
private Date partnerMembershipSince;
// car location
private List<Double> location;
private String district;
private String city;
// car data
private CarType carType;
private String carBrand;
private String carModel;
private String carPlate;
private List<CarFeature> carFeatures;
private String carAddress;
private String description;
private BigDecimal hourFare;
private BigDecimal dayFare;
private BigDecimal weekFare;
private BigDecimal dailyPrice;
private BigDecimal suggestedHourlyPrice;
private BigDecimal suggestedDailyPrice;
private BigDecimal suggestedWeeklyPrice;
private String carThumbURL;
private Map<String, CarPhotos> carPhotosURL;
private CarAvailability availability;
private CarStatus carStatus;
private String carYear;
private FuelType fuelType;
#Transient
private DayOfWeek prohibitedDay;
private String carYearModel;
#Transient
private double partnerRating = 5.0;
private CarTransmission carTransmission;
private CarColor carColor;
private String odometer;
private Integer manufactureYear;
private String fipeCode;
private String renavam;
private String chassi;
private InsuranceCompany insuranceCompany;
private List<CarSpecialFeature> carSpecialFeatures;
private BigDecimal deductible;
private Boolean superCar;
public CarMatchEntity() {
}
Try using JSON based queries with SpEL expressions
#Query("{carID: { $in: ?0 } })")
List<CarMatchEntity> findAllByCarIds(List<UUID> ids);
Use
List<CarMatchEntity> findAllByCarIDIn(Iterable<UUID> ids);
instead of
List<CarMatchEntity> findAllByCarID(Iterable<UUID> ids);
UPDATE:
Did you try to explicitly declare JPQL query instead of relying on Spring Data query generation mechanism?
#Query("select e from CarMatchEntity e where e.carID in (:ids)")
List<CarMatchEntity> findAllByCarID(#Param("ids") Iterable<UUID> ids);
UPDATE 2:
Another solution I would try is to declare argument ids in findAllByCarIDIn method as Collection<UUID> instead of Iterable<UUID>.