I have a list of values which concatenates the method name with the class name.
Ex: method1#class1
Now, I want to create a map where the key is the class name and values is a list of method names. The sample code is as follows.
Map<String, List<String>> map = new HashMap<>();
List<String> name = new ArrayList<>();
name.add("method1#class1");
name.add("method2#class1");
name.add("method3#class2");
name.add("method4#class2");
So, based on the above example, I need to create a map that should contain
{class1 : [method1,method2]}
{class2 : [method3,method4]}
Can someone help to iterate the above list and add to the map?
You can use streams in combination with the groupingBy collector:
Map<String, List<String>> result = name.stream()
.map(s -> s.split("#")) // split string by '#'
.collect(
Collectors.groupingBy(arr -> arr[1], // second element is the key
Collectors.mapping(arr -> arr[0], // first element is the value
Collectors.toList()))); // collect values with the same key into a list
System.out.println(result); // {class2=[method3, method4], class1=[method1, method2]}
You could do something like this:
Map<String, List<String>> map = new HashMap<String, List<String>>();
List<String> name = new ArrayList<String>();
name.add("method1#class1");
name.add("method2#class1");
name.add("method3#class2");
name.add("method4#class2");
for (String item : name) {
String[] split = item.split("#");
String className = split[1];
if(!map.containsKey(className))
map.put(className, new ArrayList<String>());
map.get(className).add(split[0]);
}
Good luck!
Clue about extracting method names from a class:
Class c = Example.class;
Method[] m = c.getDeclaredMethods();
for (Method method: m) {
System.out.println(method.getName());
}
I made all explanations in comments to the code:
Map<String, List<String>> map = new HashMap<>();
List<String> name = new ArrayList<>();
name.add("method1#class1");
name.add("method2#class1");
name.add("method3#class2");
name.add("method4#class2");
for(String nm : name) { // for each String from name list...
String[] splitted = nm.split("#"); // split this string on the '#' character
if(map.containsKey(splitted[1])) { // if result map contains class name as the key...
map.get(splitted[1]).add(splitted[0]); // get this key, and add this String to list of values associated with this key
} else { // if result map doesn't contain that class name as key...
map.put(splitted[1], new ArrayList<String>()); // put to map class name as key, initialize associated ArrayList...
map.get(splitted[1]).add(splitted[0]); // and add method name to ArrayList of values
}
}
Related
It consists of a map in the list object. I try to match lists with the same id by comparing them through loop statements. How can I convert to lambda?
List<Map<String, String>> combineList = new ArrayList<>(); // Temp List
for(Map titleMap : titleList) { // Name List
for(Map codeMap : codeList) { // Age List
if(titleMap.get("ID").equals(codeMap.get("ID"))) { // compare Id
Map<String,String> tempMap = new HashMap<>();
tempMap.put("ID", titleMap.get("ID"));
tempMap.put("NAME", titleMap.get("NAME"));
tempMap.put("AGE", codeMap.get("AGE"));
combineList.add(tempMap);
}
}
}
You are already doing it in efficient manner. So if you want you could change same code to just use stream().forEach or if want to use streams more do it as below:
titleList.stream()
.forEach(titleMap ->
combineList.addAll(
codeList.stream()
.filter(codeMap -> titleMap.get("ID").equals(codeMap.get("ID")))
.map(codeMap -> {
Map<String, Object> tempMap = new HashMap<>();
tempMap.put("ID", titleMap.get("ID"));
tempMap.put("NAME", titleMap.get("NAME"));
tempMap.put("ID", codeMap.get("ID"));
tempMap.put("AGE", codeMap.get("AGE"));
return tempMap;
})
.collect(Collectors.toList())
)
);
Notice that you have to filter from the codeList each time because your condition is that way. Try using a class in place of Map to be more efficient, cleaner and effective.
I have a HashSet of (a hashmap of (string and list of (hashmap of (two strings))))
HashSet<HashMap<String1,List<HashMap<String2,HashMap<String3,String4>>>>>
Now, I need to search with String inputs (StrA and StrB) and this should search the HashSet on
StrA-->String1
StrB-->String2
and it should return the hashMap of String 3 and String 4.
This is what I tried.
HashSet<HashMap<String,List<HashMap<String,HashMap<String,String>>>>> ObjList;
public void getElement(String strA, String strB) {
if(ObjList.contains(strA) && ObjList.contains(strB))
System.out.println("Yes");
}
A solution using Streams would be :
HashSet<HashMap<String, List<HashMap<String, HashMap<String, String>>>>> fooSet = //;
String string1 = "string1";
String string2 = "string2";
HashMap<String, String> mapFound;
mapFound = fooSet.stream() // iterate over HashSet
.filter(map -> map.containsKey(string1)) // keep maps that contains string1
.findFirst() // take first map that match
.orElseGet(HashMap::new) // take it really (or create new Map)
.getOrDefault(string1, new ArrayList<>()) // take the List associated as value,or new List if not exists
.stream() // iterate over the list
.filter(map -> map.containsKey(string2)) // keep maps that contains string2
.findFirst() // take first map that match
.orElseGet(HashMap::new) // take it really (or create new Map)
.getOrDefault(string2, new HashMap<>()); // take HashMap associated as value, or new Map if not found
Solution with classic for each loop would be :
HashMap<String, String> mapFound;
for (HashMap<String, List<HashMap<String, HashMap<String, String>>>> map : fooSet) {
if (map.containsKey(string1)) {
List<HashMap<String, HashMap<String, String>>> list = map.get(string1);
for(HashMap<String, HashMap<String, String>> map2 : list){
if(map2.containsKey(string2)){
mapFound = map2.get(string2);
}
}
}
}
There is no other choice than iterating both, the outer Set and the inner List (untested):
HashSet<HashMap<String1,List<HashMap<String2,HashMap<String3,String4>>>>> outer = //...
HashMap<String3,String4> result =
outer.stream()
.findFirst(map1-> map1.containsKey(string1))
.get()
.stream()
.findFirst(map2-> map2.containsKey(string2))
.get();
i'm pretty new when it comes to Java but i'll hopefully clear this up.
I currently have one class and within that class i have a TreeMap called "departments" which takes an argument of >:
TreeMap <String, List<String>> department;
Within each department such as HR, Builders etc there are a list of names of people who work there. Such as:
HR: Janet, Jones, Bob
What i'd like to do is search through department to find all departments (keys) that contain someone who's called "bob" for instance and add them to a collection to make a return.
Can anyone help with this, i've been pulling my hair out for a few days! So far i'm this far with the method although clearly nowhere near complete!
public List<String> selectValues( String... aValue)
{
for(String eachDept : department.keySet()){
Collection<String> peopleInTheDept = department.get(eachDept);
for(String person : aValue){
if(peopleInTheDept.contains(person)){
result.add(person);
}
}
}
System.out.println(result);
}
Just like OH GOD SPIDERS predicted, there is a Java 8 stream solution:
TreeMap <String, List<String>> department = new TreeMap<>();
department.put("AB", Arrays.asList("Bob", "Truus", "Miep"));
department.put("CD", Arrays.asList("Jan", "Kees", "Huub"));
department.put("EF", Arrays.asList("Jan", "Piet", "Bert"));
String aValue = "Jan";
Map<String,List<String>> result = department.entrySet().stream()
// filter out those departments that don't contain aValue
.filter(entry -> entry.getValue().contains(aValue))
// collect the matching departments back into a map
.collect(Collectors.toMap(k -> k.getKey(), k -> k.getValue()));
// print the result
result.forEach((k,v)-> System.out.println(k + " " + v.toString()));
Which prints:
EF [Jan, Piet, Bert]
CD [Jan, Kees, Huub]
Pre Java 8 solution:
Map<String, List<String>> result2 = new TreeMap<>();
for(String eachDept : department.keySet()){
List<String> peopleInTheDept = department.get(eachDept);
if(peopleInTheDept.contains(aValue)){
result2.put(eachDept, department.get(eachDept));
}
}
for (String s : result2.keySet()){
System.out.println(s + " " + result2.get(s));
}
This prints exactly the same as my Java 8 code.
Here is some java 8 Streams fancy solution to get the information and fill your list.
public void selectValues(String... values)
{
for(String value : values) {
results.addAll(department.entrySet()
.stream()
.filter(entry -> entry.getValue().contains(value))
.map(entry -> entry.getKey())
.collect(Collectors.toList()));
}
}
What I understand that you need a list of department who's Value contain certain name. Here is the solution of Java 8 version.
public static void main(String[] args) {
// Initialization of map
Map<String, List<String>> department = new TreeMap<>();
department.put("HR", new ArrayList<>());
department.put("ACC", new ArrayList<>());
department.put("MK", new ArrayList<>());
department.get("HR").add("bob");
department.get("HR").add("John");
department.get("ACC").add("Kim");
department.get("ACC").add("bob");
department.get("MK").add("XXX");
// Here is the solution
// depts is a list of string which contains the name of
// department who's value contains 'bob'
List<String > depts = department.entrySet()
.stream()
.filter(i -> i.getValue().contains("bob"))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
// Printing out the result
depts.stream().forEach(System.out::println);
}
In traditional way
List<String> depts = new ArrayList<>();
for (Map.Entry<String , List<String >> it :
department.entrySet()) {
if (it.getValue().contains("bob"))
depts.add(it.getKey());
}
Java8's streams is certainly an elegant solution...but if you are restricted with the use of java 8 then how about your departments be of type TreeMap<String, Set<String>>. If you insist in using a list its very similiar. Just change the Set to List. There is a contains method in List interface too.
TreeMap<String, List<String>> departments = new TreeMap<String, List<String>>();
ArrayList<String> myList = new ArrayList<String>();
myList.add("person1");
departments.put("dep1", myList);
String[] aValue = {"person1","person2"};
public void selectValues( String... aValue)
{
for(String eachDept : departments.keySet()){
List<String> peopleInTheDept = departments.get(eachDept);
for(String person : aValue){
if(peopleInTheDept.contains(person)){
result.add(person)
}
}
}
System.out.println(result);
}
Something similar to this maybe?
I am making something like tags using Java collections. I made a map using list as a value.
Can I get a key searching by words from list? How I can do that?
Map<String, List<String>> map = new HashMap<String, List<String>>();
List<String> list1 = new ArrayList<String>();
List<String> list2 = new ArrayList<String>();
list1.add("mammal");
list1.add("cute");
list2.add("mammal");
list2.add("big");
map.put("cat", list1);
map.put("dog", list2);
If I understand you correctly, you want to obtain the key given one of the value in the list stored as the corresponding value? Of course, you can always get all these lists using the values() method of the Map interface and then iterate over those. However, how about having a second map where you use your tags as keys and store a list of all the entries carrying this tag? For large data sets, this will probably perform better.
for (Entry<String, List<String>> entry : map.entrySet()) {
if (entry.getValue().contains(animalYouSearch)) {
System.out.println(animalYouSearch + " is in " + entry.getKey());
}
}
Output if you search for "mammal":
mammal is in cat
mammal is in dog
There is no 'magic' way for it, you need to search inside the values and then report the correct key.
For example:
String str = "cute";
List<String> matchingKeys = map.entrySet().stream().filter( e -> e.getValue().contains(str))
.map(e -> e.getKey()).collect(Collectors.toList());
But you probably want to store your data other way arround, the list of "features" being the key, and the value the animal name.
If you want to retrieve set of tags, use this method:
public Set<String> findMatchingKeys(Map<String, List<String>> map, String word){
Set<String> tags = new HashSet<String>();
for(Map.Entry<String,List<String> > mapEntry : map.entrySet()){
if(mapEntry.getValue().contains(word))
tags.add(mapEntry.getKey());
}
return tags;
}
I've got an ArrayList that looks like this:
ArrayList<String> item;
item [0] --> boom
item [1] --> pow
item [2] --> bang
item [3] --> zing
Now what I'm trying to do is take each item and create an empty ArrayList of strings with that item's name. For instance, the result would be
ArrayList<String> boom;
ArrayList<String> pow;
ArrayList<String> bang;
ArrayList<String> zing;
Sorry if this is a simple answer, but I'm still learning.
If I understand your question, then you might use a Map<String, ArrayList<String>> map, check if the heading is already present (and if it isn't create a new ArrayList<>). Something like,
Map<String, List<String>> headings = new HashMap<>();
// perform processing in a loop, for each heading...
String heading = "Example";
String content = "Body";
// ...
if (!headings.containsKey(heading)) {
headings.put(heading, new ArrayList<>());
}
List<String> bodies = headings.get(heading);
bodies.add(content);
// .. iterate heading
or you might prepopulate the headings map like
List<String> nameList = Arrays.asList("boom", "pow", "bang");
Map<String, List<String>> headings = new HashMap<>();
for (String name : nameList) {
headings.put(name, new ArrayList<>());
}
// ...
In programming language variable names is used to refers a stored value in computer memory. So a variable name can be considered as a key to access the value stored in computer memory. The standard data structure Map have the similar key value structure. So we can user Map here - "boom" as a key and new ArrayList<String>() as an value.
Suppose you have all the names (that is boom, pow, bang) in the nameList -
ArrayList nameList = new ArrayList(){{
add("boom");
add("pow");
add("bang");
}};
Now you want to create 3 ArrayList of Stirng by the name given in nameList. So you put them in a Map<String, List<String> like this -
Map<String, List<String> > vars = new HashMap<String, List<String>>();
for(int i=0; i<nameList.size(); i++){
String key = nameList.get(i);
List<String> value = new ArrayList<String>();
vars.put(key, value);
}
The complete cod can be -
import java.util.*;
public class ArrayListFromNameList {
public static void main(String[] args){
List<String> nameList = new ArrayList<String>(){{
add("boom");
add("pow");
add("bang");
}};
Map<String, List<String> > vars = new HashMap<String, List<String>>();
for(int i=0; i<nameList.size(); i++){
String key = nameList.get(i);
List<String> value = new ArrayList<String>();
vars.put(key, value);
}
}
/* Use the Map vars like this -
* vars.get("boom") --> will reuturns you an ArrayList<String>();
* similarly vars.get("pow") --> will returns you an ArrayList<String>();
*/
}