Looping iterator until it's empty - java

I want to get all the objects from the list and put them into a Map grouped by creation date, which means the map is like this: Map<String, List<MyObject>>. The MyObject object has a field that stores its creation date.
I've thought of doing a nested while loop that looks like this:
public Map<String, List<Expense>> getExpensesSorted(SortType type){
Map<String, List<Expense>> map = new HashMap<String, List<Expense>>();
List<Expense> expenses = getAllExpenses(budgetId).getExpenses()
.getList();
if (type.equals(SortType.DAY)) {
Iterator<Expense> expIter = expenses.iterator();
while (expIter.hasNext()) {
List<Expense> list = new ArrayList<Expense>();
Expense exp = (Expense) expIter.next();
list.add(exp);
String day = exp.getDate().format("YYYY-MM-DD");
expIter.remove();
while (expIter.hasNext()) {
Expense exp2 = (Expense) expIter.next();
if (exp2.getDate().format("YYYY-MM-DD").equals(day)) {
list.add(exp2);
expIter.remove();
}
}
map.put(day, expenses);
}
} else if (type.equals(SortType.WEEK)) {
...
} else if (type.equals(SortType.TYPE)) {
...
} else if (type.equals(SortType.CATEGORY)) {
...
}
return map;
}
But this is wrong, it only gets all the ones that have the same day as the first element, so my map ends up having only one element.
I seriously don't know how to solve this...
Thanks in advance for any help.

Map<Data, List<MyObject>> result = new HashMap<Data, List<MyObject>>;
for (List<MyObject> list : myMap.values()) {
for (MyObject myObject : list) {
Date date = myObject.getDate();
List<MyObject> newList = result.get(date);
if (newList == null) {
newList = new Arraylist<MyObject>;
result.put(date. newList);
}
newList.add(myObject);
}
}

Something like this should do the job. I didn't compile it though.
while (iter.hasNext()) {
MyObject obj = (MyObject) iter.next();
String day = obj.getDate().format("YYYY-MM-DD");
if(!map.containsKey(day)) {
map.put(day, new ArrayList<MyObject>());
}
List<MyObject> list = map.get(day);
list.add(obj);
map.put(day, list);
}

Related

Java lambda to return a list with duplicated code issue

I have a question when I tried to get a list by lambda expression. The code looks like
Collection<Order> updateOrders = orderCodes.stream().filter(orderCode -> {
List<String> iccids = new ArrayList<>();
ShippedOrder shippedOrder = orderMap.get(orderCode);
iccids.addAll(getSimEsnByShippedOrder(shippedOrder));
Optional<Order> maybeOrder = orderRepository.findByCode(orderCode);
return maybeOrder.isPresent() && !iccids.isEmpty();
}).map(orderCode -> {
List<String> iccids = new ArrayList<>();
ShippedOrder shippedOrder = orderMap.get(orderCode);
iccids.addAll(getSimEsnByShippedOrder(shippedOrder));
Optional<Order> maybeOrder = orderRepository.findByCode(orderCode);
Order order = maybeOrder.get();
List<String> existedEsnList = order.getEsnList();
if(!existedEsnList.isEmpty())
iccids.addAll(existedEsnList);
order.setEsnList(iccids);
return order;
}).collect(Collectors.toList());
Obviously, a piece of duplicated code is appeared in filter() and map(), and database is accessed 2 times for the same reason. How can I reduce the code? Thanks
First solution could be:
List<String> l = List.of("a", "b", "c");
l.stream().map((String orderCode)->{
boolean isOrderPresent = true;
if(isOrderPresent)
return orderCode + " order"; //return Order object
else
return null;
})
.filter(ss-> ss!= null)
.map((String order) -> {
System.out.println(order); // else use order.orderCode
return order;
}).collect(Collectors.toList());
Or you can maintain a map of <OrderCode, Order> like this:
List<String> l = List.of("a", "b", "c");
Map<String, String> map = new HashMap<>();
l.stream().filter((String s)->{
map.put(s, s+" order");
return !s.isEmpty();
})
.forEach((String s) -> {
System.out.println(map.get(s)); //<== retrieve Orders from local map
});
What about mapping to null and filtering nulls? It would be something like this:
Collection<Order> updateOrders = orderCodes.stream().map(orderCode -> {
List<String> iccids = new ArrayList<>();
ShippedOrder shippedOrder = orderMap.get(orderCode);
iccids.addAll(getSimEsnByShippedOrder(shippedOrder));
Optional<Order> maybeOrder = orderRepository.findByCode(orderCode);
if (maybeOrder.isPresent && !iccids.isEmpty) {
return getObject(iccids, maybeOrder);
} else {
return null;
}
}).filter(Objects::nonNull).collect(Collectors.toList());
where getObject
private Object getObject(List<String> iccids, Optional<Order> maybeOrder) {
Order order = maybeOrder.get();
List<String> existedEsnList = order.getEsnList();
if(!existedEsnList.isEmpty())
iccids.addAll(existedEsnList);
order.setEsnList(iccids);
return order;
}

Java Print Value Object on Map<String, Object>

I set list on another class
List<DataModel> dataList = new ArrayList<DataModel>();
parsed on class
for(DataModel list : dataList) {
final String[] data = {list.getVar_a(), list.getVar_b()};
System.out.println("out data");
System.out.println(list.getVar_a());
System.out.println(list.getVar_b());
}
this prints data
out data
val_a
val_b
Model Class
class DataModel {
private String var_a, var_b;
//Getter & Setter
}
But now, I use and set map on another class and I'm not implementing a model class because in real case it has too many variables.
Map<String, Object> mapData = new LinkedHashMap<String, Object>();
when I set data on map, its result from database
Map<String, Object> map = new LinkedHashMap<String, Object>();
msg = (String) cs.getObject(5);
rs = (ResultSet) cs.getObject(4);
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();
if(rs.next()){
int jml = 0;
do {
Map<String, Object> data = new LinkedHashMap<>();
for (int i = 1; i <= count; i++ ) {
String name = rsmd.getColumnName(i);
data.put(name, rs.getObject(name));
}
map.put(""+jml, data);
jml++;
} while(rs.next());
setStatus(SUCCESS);
setMessage(msg);
} else {
LOG.info(NO_DATA_FOUND);
}
parsed on class
for(Map.Entry<String,Object> list : mapData.entrySet()) {
String key = list.getKey();
Object val = list.getValue();
System.out.println("out data");
System.out.println(key);
System.out.println(val);
}
this prints data
out data
0
{var_a=val_a, var_b=val_b}
I want to get value on object like this
out data
val_a
val_b
Change your Map for loop to:
for(Map.Entry<String,Object> list : mapData.entrySet()) {
DataModel value = (DataModel) list.getValue();
System.out.println("out data");
System.out.println(value.getVar_a());
System.out.println(value.getVar_b());
}
First you have a map of object, and what you really need is a Map of Map.
Here is your reading a map of object.
for(Map.Entry<String,Object> list : mapData.entrySet()) {
String key = list.getKey();
Object val = list.getValue();
System.out.println("out data");
System.out.println(key);
System.out.println(val);
}
What you really need is a map of map as I am showing below.
Map<String, Map<String, Object>> map = new LinkedHashMap<String, Map<String, Object>>()
Now if you read it as map of map, You can have the result that you need.
0 : {a1:v1, a2:v2, etc...},
1 : {a2:v2, a2:v2, etc...},
2 : {a3:v3, a3:v3, etc...}
for(Map.Entry<String,Map<String, Object> list : mapData.entrySet()) {
String key = list.getKey();
System.out.println("out data");
for(Map.Entry<String,Object> innermap : list.getValue().entrySet()) {
//System.out.println(innermap.getKey());
System.out.println(innermap.getValue());
}
}

How does generic works for nested Lists

I have a meeting centre class, each meeting centre contains 1..n meeting rooms and each room has 0..n reservations.
I want to iterate through the meeting centres, for everyone create a sublist with all its reservations and then add the sublist to the list with all reservations from all meeting centres
public List<ArrayList<Reservation>> findAllReservations() {
List<ArrayList<Reservation>> allReservations = new ArrayList<>();
for (MeetingCentre mc : this.getMeetingCentres()) {
ArrayList<Reservation> currentMCReservations = new ArrayList<>();
for (MeetingRoom mr : mc.getMeetingRooms()){
if (mr.getReservations().size() > 0){
currentMCReservations.addAll(mr.getReservations());
}
}
if (currentMCReservations.size() > 0) {
allReservations.add(currentMCReservations);
}
}
return allReservations;
}
I want to export this data into JSON, and when I try to work with the allReservations List, the generic get "lost" and I get an exception "Object cannot be converted into Reservation"
Best simple solution is to use gson.
Gson gson = new Gson();
String jsonList = gson.toJson(list_name); // converts list to json
System.out.println(jsonList);
Do you need a List of ArrayLists?
public String getAllReservationsJSON() {
List<Reservation> allReservations = new ArrayList<>();
for (MeetingCentre mc : this.getMeetingCentres()) {
ArrayList<Reservation> currentMCReservations = new ArrayList<>();
for (MeetingRoom mr : mc.getMeetingRooms()){
if (mr.getReservations().size() > 0){
currentMCReservations.addAll(mr.getReservations());
}
}
if (currentMCReservations.size() > 0) {
allReservations.addAll(currentMCReservations);
}
}
Gson gson = new Gson();
return gson.toJson(allReservations);
}

function needs to be void with if, else if, else? hash map, java

OK, very odd. Not come across this before from what I can remember.
OK, so the compiler is telling me that the following method should be void for some reason:
public static HashMap<String, ArrayList<FlightData>> mapper(ArrayList<String> lineBuffer) {
HashMap<String, ArrayList<FlightData>> mapdata = new HashMap<>(); //array list for Mapdata object
for (String flightData : lineBuffer) {
String[] str = flightData.split(",");
FlightData flight = new FlightData(str[0], str[1], str[2].toCharArray(), str[3].toCharArray(), new Date(Long.valueOf(str[4])), Long.valueOf(str[5]).longValue()); //creating the object
mapdata.get(flight.getFlightID()); //getting the flight data
if (mapdata.containsKey(flight.getFlightID())) { //checking if the data for the oject contains hash key Flightdata
mapdata.get(flight.getFlightID()).add(flight);
}
else if (mapdata.containsKey(flight.getFromID())) {
mapdata.get(flight.getFromID()).add(flight);
ArrayList<FlightData> noID2 = new ArrayList<>(); //creating an array for noID
noID2.add(flight);
mapdata.put(flight.getFlightID(), noID2);
}
else {
ArrayList<FlightData> noID = new ArrayList<>(); //creating an array for noID
noID.add(flight);
mapdata.put(flight.getFlightID(), noID);
// System.out.println(mapdata);
}
return mapdata;
}
Which is odd, because when I remove the additional if (if else to just else) its fine:
public static HashMap<String, ArrayList<FlightData>> mapper(ArrayList<String> lineBuffer) {
HashMap<String, ArrayList<FlightData>> mapdata = new HashMap<>(); //array list for Mapdata object
for (String flightData : lineBuffer) {
String[] str = flightData.split(",");
FlightData flight = new FlightData(str[0], str[1], str[2].toCharArray(), str[3].toCharArray(), new Date(Long.valueOf(str[4])), Long.valueOf(str[5]).longValue()); //creating the object
mapdata.get(flight.getFlightID()); //getting the flight data
if (mapdata.containsKey(flight.getFlightID())) { //checking if the data for the oject contains hash key Flightdata
mapdata.get(flight.getFlightID()).add(flight);
} else {
ArrayList<FlightData> noID = new ArrayList<>(); //creating an array for noID
noID.add(flight);
mapdata.put(flight.getFlightID(), noID);
}
// System.out.println(mapdata);
}
return mapdata;
}
I get the following:
the error is telling my missing return statement/type. Hence void suggestion. any ideas why??
Any help would be great.
Cheers,
Glenn
Yeah, so I'm an idiot and didn't spot that my return statement was inside my for loop... Just wow.
Cheers to all who commented with a response.
markspace
ayush Gupta
ifly6
apparently I'm blind.
Cheers guys.
Glenn

Problems with creating a map of <String, List>

I've a row in db returned by query below. Columns to select include rec, head, amount. I want to sort the rows by head column. I tried Map where string for head and list for other two columns.
I've hit the wall with my non-working code posted below. How would I append another list to list of repeated key. Documentation says it replaces the value for same key whereas I need it appended to the list value. I would be really greatful for any help.
Query q= session.createQuery("select tally_receipt_prefix, tally_receipt_no, tally_head, tally_amount from Tally_table where tally_system_date='"+fmtd_date+"' and tally_dbcr_indicator='DB' and tally_mode='Ca' order by tally_head,tally_receipt_prefix,tally_receipt_no"); System.out.println("query "+q);
List heads=new ArrayList();
for(Iterator it=q.iterate(); it.hasNext(); )
{
Object[] row= (Object[]) it.next();
payincash1=new LinkedHashMap<String, List>();
heads.add((String)row[2]);
List tails = null;
tails=new ArrayList();
tails.add((String)row[0]);
tails.add((String)row[1]);
tails.add((String)row[3]);
System.out.println("heads in dao from iter 1: "+heads);
System.out.println("tails in dao from iter1 on: "+tails);
if(heads.contains((String)row[2])) // for head in temp list
{
System.out.println("in first if");
if(payincash1.containsKey((String)row[2]))
{
System.out.println("map if repeat: "+payincash1);
payincash1.put((String)row[2],tails);
}
}
else
{
System.out.println("map if not repeat: "+payincash1);
payincash1.put((String)row[2], tails);
}
}
Sounds more like you want a list of lists
Something like Map<String, List<List>>
Then you'd end up with something like...
Map<String, List<List>> payincash1 = new LinkedHashMap<String, List<List>>();
heads.add((String) row[2]);
List tails = null;
tails = new ArrayList();
tails.add((String) row[0]);
tails.add((String) row[1]);
tails.add((String) row[3]);
System.out.println("heads in dao from iter 1: " + heads);
System.out.println("tails in dao from iter1 on: " + tails);
List master = payincash1.get((String)row[2]);
if (master == null) {
master = new List();
payincash1.put((String)row[2], master);
}
master.add(tails);
Now, personally, I'd be creating a "data" object that would contain all this information.
public class MyData {
private String rec, head, amount, ??; // Apparently you have another variable I don't know about
public MyData(String rec, String head, String amount, String ??) {
// Initalise...
}
// Setters and getters not inclueded
}
Then you could do something like this...
Map<String, List<MyData>> payincash1 = new LinkedHashMap<String, List<MyData>>();
MyData data = new MyData(row[0], row[1], row[2], row[3]);
List master = payincash1.get((String)row[2]);
if (master == null) {
master = new List<MyData>();
payincash1.put((String)row[2], master);
}
master.add(data);
Which is a little cleaner (IMHO)
From what I understand you need Multimap of guava library.

Categories