I have a for each loop running as:
for (System system : val.keySet())
{
do something
}
Is there an alternate method to write this?
Here are some ways how you can loop through a map:
1- Using for-Each loop:
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
2- Iterating over keys or values
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
//iterating over keys only
for (Integer key : map.keySet()) {
System.out.println("Key = " + key);
}
//iterating over values only
for (Integer value : map.values()) {
System.out.println("Value = " + value);
}
3- Using iterator:
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<Integer, Integer> entry = entries.next();
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
Related
The for loop in the code is need to be replaced by java8 streams. How can I resolve this?
public class Conversion {
public static void main(String[] args) {
// TODO Auto-generated method stub
//Person class (name, age , gender)
//Employee class (name, gender)
Map<String, List<Person>> mapPerson = new HashMap<String, List<Person>>();
Map<String, List<Employee>> employeeMap = new HashMap<>();
List<Person> personList1 = new ArrayList<Person>();
personList1.add(new Person("Adam", 22, "Male"));
personList1.add(new Person("Alon", 21, "Female"));
List<Person> personList2 = new ArrayList<Person>();
personList2.add(new Person("Chad", 23, "Male"));
personList2.add(new Person("Daina", 21, "Female"));
List<Person> personList3 = new ArrayList<Person>();
personList3.add(new Person("Mark", 22, "Female"));
personList3.add(new Person("Helen", 25, "Male"));
mapPerson.put("A", personList1);
mapPerson.put("B", personList2);
mapPerson.put("C", personList3);
for (Map.Entry<String, List<Person>> entry : mapPerson.entrySet()) {
String key = entry.getKey();
List<Person> values = entry.getValue();
System.out.println("Key = " + key);
System.out.println("Values = " + values + "n");
}
System.out.println("******************************************");
employeeMap = getEmployeeMap(mapPerson);
for(Map.Entry<String, List<Employee>> listMap : employeeMap.entrySet())
{
System.out.println("Key : " + listMap.getKey());
System.out.println("Values : " + listMap.getValue());
System.out.println("===============");
}
}
This is the for loop in the function for iteration of MAP. Instead of this I have to use streams.
public static Map<String, List<Employee>> getEmployeeMap(Map<String, List<Person>> personMap) {
Map<String, List<Employee>> employeeMap = new HashMap<>();
for(Map.Entry<String, List<Person>> listMap : personMap.entrySet()) {
String key = listMap.getKey();
List<Person> personList = listMap.getValue();
List<Employee> employeeList = personList.stream().map(p-> new Employee(p.getName(), p.getGender())).collect(Collectors.toList());
employeeMap.put(key, employeeList);
}
return employeeMap;
}
}
You can use Collectors.toMap and modify the value inside it.
Map<String, List<Employee>> employeeMap =
mapPerson.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().stream().map(p-> new Employee(p.getName(), p.getGender())).collect(Collectors.toList()));
I need to write to csv all the keys from one map in one column, and all the values from a different map in the next column.
I can do either column individually with this code but when I combine, how do I explain this(?), if I have 10 keys and 10 values the keys will repeat 10 of each key.
What do I need to do to my loops?
private static void generateCourseCounts() throws IOException {
ArrayList<StudentCourse> lsc = loadStudentCourses();
Map<Integer, Integer> countStudents = new TreeMap<Integer, Integer>();
for (StudentCourse sc : lsc) {
Integer freq = countStudents.get(sc.getCourseId());
countStudents.put(sc.getCourseId(), (freq == null) ? 1 : freq + 1);
}
ArrayList<Course> lc = loadCourses();
Map<String, String> courses = new LinkedHashMap<String, String>();
for (Course c : lc) {
String freq = courses.get(c.getCourseName());
courses.put(c.getCourseName(), freq);
}
FileWriter writer = new FileWriter("CourseCounts.csv");
PrintWriter printWriter = new PrintWriter(writer);
printWriter.println("Course Name\t# Students");
for (Entry<String, String> courseKey : courses.entrySet())
for (Entry<Integer, Integer> numberKey : countStudents.entrySet()) {
printWriter.println(courseKey.getKey() + "\t" + numberKey.getValue());
}
printWriter.close();
writer.close();
}
So, as per comments below, I edited to this:
for (String courseKey : courses.keySet()) {
Integer count = countStudents.get(courseKey) ;
printWriter.println(courseKey + "\t" + count);
}
However, this writes an empty file.
Try this. It does presume that the number of map entries in each map is the same.
Otherwise, you will either get an index out of bounds exception or you won't print all the values.
int i = 0;
Integer[] counts = countStudents.values().stream().toArray(Integer[]::new);
for (String courseKey : courses.keySet()) {
printWriter.println(courseKey + "\t" + counts[i++]);
}
printWriter.close();
writer.close();
You don't need embedded cycles. You can just iterate by keys from 1st map and get values from 2nd:
for (String courseKey: courses.keySet())
String count = countStudents.get(courseKey);
// ... output courseKey and count to file
}
This question already has answers here:
Why does my ArrayList contain N copies of the last item added to the list?
(5 answers)
Closed 5 years ago.
I am trying to create a HashMap in a HashMap so it will be easier for me to access elements of it in the future as shown below.
The problem is it only repeating the last elements of the while loop and not the rest of it.
HashMap<String,String> result = new HashMap<>();
HashMap<Integer, HashMap<String,String>> fr = new HashMap<>();
int i = 0;
try {
ResultSet rq = qexec.execSelect();
// ResultSetFormatter.out(System.out, rq, query);
// get result from SPARQL query
while (rq.hasNext()) {
QuerySolution soln = rq.next();
id = soln.getLiteral("?id").getLexicalForm();
//...
result.put("id",id);
//...
if (soln.getLiteral("?wateruse") != null) {
wateruse = soln.getLiteral("?wateruse").getLexicalForm();
//...
result.put("wateruse",wateruse);
} else {
System.out.println("NO");
}
fr.put(i, result);
i++;
}
} finally {
qexec.close();
}
This is how the result should be:
John001
High usage
John002
John003
Smith001
Moderate
Smith002
Smith003
...
Kevin001
Low usage
But fr only repeats Kevin001 and Low usage without the rest.
I've tried to put fr.put(i,result) outside the loop but that still does not give the correct result.
EDIT
I tried to print all elements from fr that shows the repeating elements.
finally {
qexec.close();
}
for (int index : fr.keySet()) {
for(Map.Entry<String, String> entry :result.entrySet()) {
System.out.println(index + " = " + entry.getKey() + " : " + entry.getValue());
}
}
UPDATE - SOLUTION
Declare HashMap inside the loop as mentioned in comments below.
To print nested HashMap, no need to use result.
I did as shown below and it prints both outermap and innermap as well.
for (int k=0; k < fr.size(); k++) {
HashMap<String,String> innermap = fr.get(k);
for(Map.Entry<String, String> e : innermap.entrySet()) {
System.out.println(k + " = " + e.getKey() + " : " + e.getValue());
}
}
You're adding the same result map to your parent map each time through the loop. Create a new instance of result each time through the loop:
Map<String, String> result = new HashMap<>();
Map<Integer, Map<String, String>> fr = new HashMap<>();
int i = 0;
try {
ResultSet rq = qexec.execSelect();
while (rq.hasNext()) {
// Create your new HashMap inside the loop:
result = new HashMap<>();
QuerySolution soln = rq.next();
id = soln.getLiteral("?id").getLexicalForm();
//...
result.put("id",id);
//...
if (soln.getLiteral("?wateruse") != null) {
wateruse = soln.getLiteral("?wateruse").getLexicalForm();
//...
result.put("wateruse",wateruse);
}
else {
System.out.println("NO");
}
fr.put(i,result);
i++;
}
}
To print the results from fr an its nested map, you can do something like this:
for (Map<String, String> map : fr.values()) {
for(Map.Entry<String, String> e : map.entrySet()) {
System.out.println(index + " = " + e.getKey()
+ " : " + e.getValue());
}
}
Try this a small change here, place the "result" map creation in while loop
Map<Integer, Map<String, String>> fr = new HashMap<>();
int i = 0;
try {
ResultSet rq = qexec.execSelect();
while (rq.hasNext()) {
Map<String, String> result = new HashMap<>();
QuerySolution soln = rq.next();
id = soln.getLiteral("?id").getLexicalForm();
//...
result.put("id",id);
//...
if (soln.getLiteral("?wateruse") != null) {
wateruse = soln.getLiteral("?wateruse").getLexicalForm();
//...
result.put("wateruse",wateruse);
}
else {
System.out.println("NO");
}
fr.put(i,result);
i++;
}
}
This for loop to print elemenets:
for (int i=0;i< fr.size();i++){
Map<String,String> element= fr.get(i);
// use the element here.
}
Nested HashMap:
HashMap<String,HashMap<String,String>> outerMap=new HashMap<String, HashMap<String, String>>();
HashMap<String,String> innerhashMap=new HashMap<String, String>();
innerhashMap.put("aaa","AAA");
outerMap.put("111",innerhashMap);
innerhashMap.put("aaa","AAA");
outerMap.put("222",innerhashMap);
I want outer map keys list,inner map keys list and innermap values list
for ( String outerkey : outerMap.keySet() ) {
HashMap<String,String> innerHashMap = (HashMap<String,String>) outerMap.get(outerKey)
for ( String innerKey : innerHashMap.keySet() ) {
String innerValue = (String) innerHashMap.get(innerKey);
//... Process them
}
}
HashMap<String,HashMap<String,String>> outerMap = new HashMap<>();
HashMap<String,String> innerhashMap = new HashMap<>();
innerhashMap.put("aaa","AAA");
outerMap.put("111",innerhashMap);
innerhashMap.put("aaa","AAA");
outerMap.put("222",innerhashMap);
outerMap.forEach((k, v) -> {
System.out.println("OUTER KEY: " +k);
v.forEach((kk, vv) -> {
System.out.println("INNER KEY: " +kk+ " INNER VALUE: " +vv);
});
});
I am iterating 500,000 items using for loop , after 300, 000 item i am getting Out of memory , I have also tried to split loop in 100,000 still, but that also didn't work. When I increased memory in runConfig-xms10g, its working fine. Can anyone tell me how to split and free memory or any other way to iterate large number of recods.
protected Map<Long, Map<String, String>> getExistingItems()
{
Map<Long, Map<String, String>> items = new HashMap<Long, Map<String, String>>();
for (Item item : itemMaster.getItems()) {
if (item.getExpirationDate() == null && !items.containsValue(item.getItemId())) {
Map<String, String> item_hash = new HashMap<String, String>();
if (item.getEffectiveDate() != null)
item_hash.put("effectiveDate", sdf.format(item.getEffectiveDate().getTime()));
for (ItemMasterAttributeValue attrVal : item.getItemMasterAttributeValues()) {
item_hash.put(attrVal.getId().getItemMasterAttribute().getCode(), attrVal.getValue());
}
items.put(item.getItemId(), item_hash);
}
}
after splitting below is code:
protected Map<Long, Map<String, String>> getExistingItems()
{
Map<Long, Map<String, String>> items = new HashMap<Long, Map<String, String>>();
java.util.Date date = new java.util.Date();
System.out.println("before getItems : " + new Timestamp(date.getTime()));
Collection<Item> allItems = itemMaster.getItems();
System.out.println("after getItems : " + new Timestamp(date.getTime()));
int split = (allItems.size() / 100000);
Map<Integer, Collection<Item>> splitMap = new HashMap<Integer, Collection<Item>>();
Collection<Item> tempCollection = new ArrayList<Item>();
int splitKey = 1;
int key = 1;
for(Item item : allItems)
{
tempCollection.add(item);
if(splitKey / 100000 >= key && splitKey % 100000 == 0)
{
splitMap.put(key, tempCollection);
tempCollection = new ArrayList<Item>();
key++;
}
splitKey++;
}
splitMap.put(key, tempCollection);
System.out.println("map size " + splitMap.size());
for(int i = 1; i <= split + 1; i++)
{
System.out.println("i is :" + i + " " + Calendar.getInstance().getTime());
for(Item item : splitMap.get(i))
{
if(!items.containsKey(item.getItemId()))
{
Map<String, String> item_hash = new HashMap<String, String>();
if (item.getEffectiveDate() != null)
item_hash.put("effectiveDate", sdf.format(item.getEffectiveDate().getTime()));
for (ItemMasterAttributeValue attrVal : item.getItemMasterAttributeValues()) {
item_hash.put(attrVal.getId().getItemMasterAttribute().getCode(), attrVal.getValue());
}
items.put(item.getItemId(), item_hash);
}
}
System.gc();
}