I use following complex data structure.
departures = new TreeMap<String, Map<String, Set<MyObject>>>();
arrivals=new HashMap<String, Set<MyObject>>();
flights=new HashSet<MyObject>();
Then I use loops (I also tried other loops).
for(String dep: nizDep){
for(String arr: nizArr){
for(MyObject flight: _flights){
if(flight.getFrom().equalsIgnoreCase(dep)&&flight.getTo().equalsIgnoreCase(arr)){
flights.add(flight);
}
}
if(!flights.isEmpty()){
arrivals.put(arr, flights);
flights.clear();
}
}
if(!arrivals.isEmpty()){
departures.put(dep, arrivals);
arrivals.clear();
}
}
System.out.println(departures.size()); //result 14
System.out.println(departures.containsKey("Madrid")); //result true
arrivals=departures.get("Madrid");
System.out.println(arrivals.size()); //result 0, arrivals is empty. WHY?
My question is how to use this complex data structure and how to retrieve arrivals from departures?
System.out.println(arrivals.size()); //result 0, arrivals is empty. WHY?
BECAUSE When you call flights.clear(); after arrivals.put(arr, flights); or arrivals.clear(); after departures.put(dep, arrivals);, this clears your original objects(flights and arrivals). Please bring your initialization statements i.e.
Map<String, Set<MyObject>> arrivals=new HashMap<String, Set<MyObject>>();
Set<MyObject>(); flights=new HashSet<MyObject>();
within the for loops or replace that statement as below:
if(!flights.isEmpty()){
Set<MyObject> newflights=new HashSet<MyObject>();
newflights.addAll(flights); //copy elements to new set
arrivals.put(arr, newflights);
flights.clear();
}
Same you may do with departures.
Now for retrievals:
Set<String> arrivalKeys = departures.keySet();
Interator<String> arrIter = arrivalKeys.iterator();
while(arrIter.hasNext()){
String arrKey = arrIter.next();
Map<String, Set<MyObject>> arrivals = departures.get(arrKey );
//use your arrivals map object
}
Same you can do to retrieve flights from arrivals e.g.
for each arrivals retrieved as above:
Set<String> flightKeys = arrivals.keySet();
Interator<String> flIter = flightKeys.iterator();
while(flIter.hasNext()){
String flKey = flIter.next();
Set<MyObject> flights = arrivals.get(flKey );
//use your flights set object
}
arrivals=new HashMap<String, Set<MyObject>>();
departures = new TreeMap<String, Map<String, Set<MyObject>>>();
for(String dep: nizDep){
for(String arr: nizArr){
for(MyObject flight: _flights){
if(flight.getFrom().equalsIgnoreCase(dep)&&flight.getTo().equalsIgnoreCase(arr)){
flights=new HashSet<MyObject>();
flights.add(flight);
arrivals.put(arr, flights);
departures.put(dep, arrivals);
}
}
}
}
System.out.println(departures.size()); //result 14
if(departures.containsKey("Madrid")) {
arrivals=departures.get("Madrid");
System.out.println(arrivals.size());
}
In case you want to keep a one-to-one mapping between arrivals and flights, then this code works. In case you want to keep a global structure of maintaining the set of flights then you'll have to create another global gflights object and put every flights object into it.
Related
Am getting response from Elasticsearch with duplicates, to avoid that i used Hashmap implementation and i put all the values into the HashMap object.
After that am iterating over the HashMap object to convert into JSONArray.
Am geting one unique record from distinctObjects (HashMap Object). But after if convert into JSONArray., the length of JSONArray shows 2 it suppose to be 1 and am printing the JSONArray, it shows like below.
JSONArray --->[{"code":"VA1125-GGA-1","id":"code"},{"code":"12816","id":"id"}]
Expected Result should be :
JSONArray --->[{"code":"VA1125-GGA-1","id":"12816"}]
Please find my code below.
JSONObject responseObj;
JSONArray responseArray = new JSONArray();
Map<String, Object> distinctObjects = null;
SearchHit[] searchHits2 = searchResponse2.getHits().getHits();
for (SearchHit hit2 : searchHits2) {
Map<String, Object> sourceAsMap2 = hit2.getSourceAsMap();
distinctObjects = new HashMap<String, Object>();
distinctObjects.put("id", sourceAsMap2.get("id").toString());
distinctObjects.put("code", sourceAsMap2.get("code").toString());
}
Iterator it = distinctObjects.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
System.out.println(pair.getKey() + " = " + pair.getValue());
responseObj = new JSONObject();
responseObj.put("id", pair.getKey());
responseObj.put("code", pair.getValue());
responseArray.put(responseObj);
it.remove(); // avoids a ConcurrentModificationException
}
System.out.println("Link ID List Size --->"+responseArray.length());
System.out.println("JSONArray --->"+responseArray.toString());
It looks like you're adding both code and id as top level entries to your distinctObjects map which is why you're getting two objects back. Assuming you want to de-dup based on ID your first loop should look something like:
for (SearchHit hit2 : searchHits2) {
Map<String, Object> sourceAsMap2 = hit2.getSourceAsMap();
distinctObjects = new HashMap<String, Object>();
distinctObjects.put(sourceAsMap2.get("id"), sourceAsMap2.get("code").toString());
}
That will give you one entry in distinctObjects for every unique id with a value of the code.
If you wanted you could also add sourceAsMap2 as the value in distinctObjects to maintain the full response if you need more than just the code in downstream processing.
I'm using Java and Infusionsofts API to get a list of contacts based on the customer id. I can't figure out a way to do this. I'm using Googles Guava to use multimap but it's producing an error:
org.apache.xmlrpc.common.XmlRpcExtensionException: Serializable objects aren't supported, if isEnabledForExtensions() == false
So now i'm trying hashmap and i'm inserting "Id" as the key and the customer id as the value but there's always one entry in the hashmap.
How can I add to the parameters variable a map that contains:
["Id",11111]
["Id",22322]
["Id",44444]
List parameters = new ArrayList();
parameters.add(APP_ID);
parameters.add(TABLE_NAME);
parameters.add(LIMIT);
parameters.add(pageNumber);
HashMap<String, Integer> map = new HashMap<String, Integer>();
for(int customerId : customerIds){
map.put("Id", customerId);
}
//PROBLEM IS HERE
parameters.add(map);
//THIS IS THE PROBLEM, I NEED TO ADD ["Id", customerId] multiple
//times with the customerId being different but since there's a hashmap
//There's always 1 entry in the map
String[] fields = {"Email","FirstName"};
parameters.add(fields);
Object[] contacts = null;
try{
contacts = ( Object [] ) client.execute("DataService.query",parameters);
}catch(XmlRpcException e){
e.printStackTrace();
}
for (int i = 0; i < contacts.length; i++) {
Map contact = (Map) contacts[i];
System.out.println(contact+"\n\n");
}
I have a scenario to count number of names which is stored in the LinkedHashMap , and names can be duplicated but i should not count the duplicate name.
Below is Sample code:
LinkedHashMap<Long,MyApplicationDTO> myApps = (LinkedHashMap<Long,MyApplicationDTO>) request.getAttribute("data");
for (Map.Entry app : myApps.entrySet()) {
Long ID = (Long)app.getKey() ;
MyApplicationDTO singleMyApp = (MyApplicationDTO) app.getValue();
LinkedHashMap<Long, MyDTO> myList = singleMyApp.getMyList();
String name = "";
for (Map.Entry details : myList.entrySet()) {
Long id1 = (Long)details.getKey() ;
MyDTO myDetails = (MyDTO) details.getValue();
name = myDetails.getName(); // For first time it stores A
//how to loop so that i can only get the count of names as 3 by avoiding duplicate names from the below shown list.
//A B A B A B C
}
}
On the Screen i have something as below:
Name :
A
B
A
B
A
B
C
I have to print the count of the name as 3(non repeating names)
As you iterate over the entrySet, add all names to a Set<String>. Then output set.size().
The Set will not add duplicates when you add names by set.add(name), so the size of the set will be the count of uniqe names.
LinkedHashMap<Long,MyApplicationDTO> myApps = (LinkedHashMap<Long,MyApplicationDTO>) request.getAttribute("data");
for (Map.Entry app : myApps.entrySet()) {
Long ID = (Long)app.getKey() ;
MyApplicationDTO singleMyApp = (MyApplicationDTO) app.getValue();
LinkedHashMap<Long, MyDTO> myList = singleMyApp.getMyList();
String name = "";
Set<String> uniqueNames = new HashSet<String>();
for (Map.Entry details : myList.entrySet()) {
Long id1 = (Long)details.getKey() ;
MyDTO myDetails = (MyDTO) details.getValue();
name = myDetails.getName(); // For first time it stores A
//how to loop so that i can only get the count of names as 3 by avoiding duplicate names from the below shown list.
//A B A B A B C
uniqueNames.add(name);
}
}
To get size do =
uniqueNames.size();
I'm not sure I'm understanding your question entirely, but if you're just looking to count the occurrences of unique values in the LinkedHashmap you can do something like this `
public static void main(String[] args) {
LinkedHashMap<Long, String> myApps = new LinkedHashMap<Long, String>();
myApps.put(4L, "A");
myApps.put(14L, "B");
myApps.put(44L, "A");
myApps.put(54L, "B");
myApps.put(46L, "A");
myApps.put(543L, "B");
myApps.put(144L, "C");
ArrayList<String> names = new ArrayList<String>();
for (Map.Entry app : myApps.entrySet()) {
if (!(names.contains(app.getValue()))) {
names.add(app.getValue().toString());
}
}
System.out.println(names.size());
for (String s : names ) {
System.out.print(s + " ");
}
}
One liner with JAVA 8 Stream API
LinkedHashMap<Long, MyDTO> myList = singleMyApp.getMyList();
long disctinctNamesCount = myList.values().stream().map(MyDTO::getNAme).distinct().count();
i want to retrieve all data that are present in my data structure, which is of type Map of Maps.The data structure is mentioned below.
public static Map<String, Map<String, String>> hourlyMap = new HashMap<String, Map<String, String>>();
i need all the data that are stored in the map irrespective of key.
This may help you
Map<String,Map<String,String>> hourlyMap = new HashMap<String,Map<String,String>>();
for(Map<String,String> i:hourlyMap.values()){
// now i is a Map<String,String>
for(String str:i.values()){
// now str is a value of map i
System.out.println(str);
}
}
Try:
Set<String> allData = new HashSet<>(); // will contain all the values
for(Map<String, String> map : hourlyMap.values()) {
allData.addAll(map.values());
}
for (String outerKey: hourlyMap.keySet()) {
// outerKey holds the Key of the outer map
// the value will be the inner map - hourlyMap.get(outerKey)
System.out.println("Outer key: " + outerKey);
for (String innerKey: hourlyMap.get(outerKey).keySet()) {
// innerKey holds the Key of the inner map
System.out.println("Inner key: " + innerKey);
System.out.println("Inner value:" + hourlyMap.get(outerKey).get(innerKey));
}
}
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.