I'm using a Multimap that has two values per key. Below is the code I'm using to get each value separately:
The first bit of code gets the first object value:
for(Object object : map.get(object))
{
return object
}
Then, I'm using another method to retrieve the other value. This method takes the first object as an argument:
for(Object object : team.get(object))
{
if(object != initialObject)
{
return object;
}
}
This seems like a 'hackish' way of doing things, so is there any way for me to get the values more easily?
If you're using Guava, Iterables#get is probably what you want - it returns the Nth item from any iterable, example:
Multimap<String, String> myMultimap = ArrayListMultimap.create();
// and to return value from position:
return Iterables.get(myMultimap.get(key), position);
If you're using a ListMultimap then it behaves very much like a map to a List so you can directly call get(n).
Collection<Object> values = map.get(key);
checkState(values.size() == 2, String.format("Found %d values for key %s", values.size(), key));
return values.iterator().next(); // to get the first
Iterator<Object> it = values.iterator();
it.next(); // move the pointer to the second object
return it.next(); // get the second object
for getting all the values for the same key the most easiest way to do it will be :
Iterator iterator = multimap.get(key).iterator();
System.out.println("first element: " + iterator.next());
System.out.println("second element: " + iterator.next());
System.out.println("third element: " + iterator.next());
And so on
another option if you want to get all the elements without know how much elements there
Iterator iterator = multimap.get(key).iterator();
int index=1;
while (iterator.hasNext()) {
System.out.println(index +" element: " + iterator.next());
index++;
}
Related
The issue is that I must add a for-loop as my tree grows. So, the basic idea is that I have a tree which has branches, and those branches could have more branches as it grows in the application. The issue is that as the branch grows, I have to add more for loop.
Tree Strut
So, if you see Gen1 have three branches GenTest1, GenTest2, GenTest3. Later GenTest1 have two more branches 321 and MAT00000000000630, further GenTest2 have branch 123 and 123 also have 21 as a branch.
So, this grows more the branches more the for loop.
Implementation
The idea of how I am implementing
parent = new Map<String,List<String>>;
for (Map.Entry i : parent.entrySet()) {
key = i.getKey();
valueList = (List<String>) i.getValue();
S.O.P("Key: "+
key +
" & Value: " +
valueList);
for (String child: valueList)
{
parent = Map(child.get(0)) //Please don't worry about how the string value is converted into Map I did with my helper classes.
for(Map.Entry j : parent.entrySet())
{
key = j.getKey();
valueList = (List<String>) j.getValue();
S.O.P("2ndKey: "+
key +
" & 2ndValue: " +
valueList);
}
}
}
You see I can retrieve the branch of GenTest1 and GenTest2.
But in GenTest2 there is 123 and for 123 I must use for loop again.
I know recursion is the best option but, I am having a problem achieving it.
Ok the output should be like this
Gen1
GenTest1
321
MAT000000000628
GenTest2
123
21
GenTest3
maybe you need some like this...
private void print(Map<String, List<String>> parent) {
for (Map.Entry<String, List<String>> i : parent.entrySet()) {
String key = i.getKey();
List<String> valueList = i.getValue();
System.out.println("Key: " +
key +
" & Value: " +
valueList);
for (String child : valueList) {
print(Map(child.get(0))); // you helped method
}
}
}
In the Java, there is a standard TreeNode interface that you should consider implementing within WTPart. Its main methods are
n.children() // equivalent to your MBOMH.getPCP(MBOMH.getPP(n).get(0))
n.isLeaf() // MISSING in your code, to know when to stop digging
n.getParent() // this you do not need for your specific case
For a tree of MyNode extends TreeNode are used, you can print contents recursively by implementing a print function in MyNode, as follows:
public void print() {
System.out.println(this); // calls toString() to print self
if (isLeaf()) {
return; // avoids trying to print children if none there
}
// TreeNode's children() returns an enumeration; returning a List
// would make it easier to iterate with for (MyNode n : children())
for (Enumeration<MyNode> e=children(); e.hasNextElement(); /**/) {
e.next().print();
}
}
So my suggestion is to implement an isLeaf(), and while you are at it, implement a children() method that is less ugly than MechatronicBOMHelper.getPartentChildPart(MechatronicBOMHelper.getPartProp(child).get(0)). Since you have a helper class, you can consider having a MechatronicBOMHelper.childrenOf(child) instead of having a child.getChildren(), but the second is more OO-like.
It was simple recursion which I made complex through iteration.
Map<String, List<String>> parent;
for (Map.Entry<String, List<String>> i : root.entrySet()) {
logger.debug("Root"+" "+i.getKey());
for (String j : i.getValue()) {
parent = Map(j.get(0)); // using my helper class
build(parent);
I am attempting to iterate through a HashMap that contains the following type of data types:
HashMap<city, neighbors>
A city is an object that contains a String value and returns the string upon being called upon. Here is the code that makes up my city class:
import java.util.*;
public class city{
String city;
public city(String s){
this.city = s;
}
public String toString() {
return this.city;
}
}
A neighbors is an object that contains an ArrayList of cities. Here is the code that makes up my neighbors class:
import java.util.*;
public class neighbors extends ArrayList<city> {
public neighbors (city[] n) {
for (city v : n)
this.add(v);
}
}
I am attempting to iterate through this hash map using the normal convention of using an iterator like so:
Iterator it = graph.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
System.out.println("Key :" + pair.getKey()); //prints the city System.out.println("Value :" + pair.getValue()); //prints the neighbors
//for (city c: pair.getValue()){
// System.out.println("Test... " + c);
//}
}
The iterator above works well and prints the getKey and getValue statements well. The problem I am having is that I am having difficulty iterating THROUGH the VALUE of the Map.Entry (which is an ArrayList). The for loop that I have commented out is an attempt to accomplish this task. I am realizing that the getValue() method returns back an Object, but how can I retain the data type of the Value, which is an ArrayList? Should I include another method in my neighbors class that follows the toString() strategy from the city class? How can I iterate through the neighbors of the HashMap so I can compare them to other values? Please let me know if my question is unclear, and any tips, modifications, or advise will be helpful.
Use parameterized types instead of raw types for the Iterator and the Map.Entry variables:
Iterator<Map.Entry<city, neighbors>> it = graph.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<city, neighbors> pair = it.next();
System.out.println("Key :" + pair.getKey()); //prints the city
System.out.println("Value :" + pair.getValue()); //prints the neighbors
for (city c: pair.getValue()){
System.out.println("Test... " + c);
}
}
You can cast the Object you're iterating through to neighbors class. Of course that should be preceeded by a type check.
neighbors values = (neighbors) pair.getValue();
for (city c: values){
System.out.println("Test... " + c);
}
I've noticed some weird things:
You should not have classes starting with lowercase letters (city, neighbors)
If the city has just one field called "city" (which is a String), you can just have a String to represent a city.
If your neighbors class contains a list of cities which represent just Strings you can simply have a List<String> to represent a list of cities.
Your map becomes Map<String, List<String>> which is much easier to read and you don't need extra classes.
You can iterate like this after having made these changes without a need of a cast.
for(String city : graph.keySet()){
for(String neighbor : graph.get(city)){
}
}
I am looking at a possibility of unrolling the loop which is written to iterate the elements in a hash map.Below posted is the code.
for (final Object key : map.keySet())
{
if (input_map.containsKey(key))
{
System.out.println("Matching key: " + key);
if (map.get(key).equals(input_map.get(key)))
{
System.out.println("hii!done");
}
else
{
System.out.println(key);
final String values =
key.
toString().
substring(key.toString().lastIndexOf("\\") + 1);
System.out.println("input_map" +
input_map.get(key));
System.out.println("map" + map.get(key));
}
}
}
Explanation:
Currently, comparison in the loop is being done based on one element at a time i.e "key".I am looking at a possibility where i can retrieve the next successive keys in one single iteration i.e(key,key+1,key+2).
Any Suggestions would be highly helpful.
Use the KeySet or EntrySet iterator() method and while loop through with hasNext() and next(). You need to handle cases where it has not 3 repeating elements. Then you have the 3 keys and should be able to easily access the values in the Map.
Iterator<Integer> it = myMap.keySet().iterator();
while(it.hasNext())
{
int first = it.next();
int second = it.next();
int third = it.next();
}
Very rudimentary question but I have a loop e.g.
List<ObjectList> = //set of values inside.
for(Object data : ObjectList){
// how to access next element?
// current element is accesed by 'data'. I could get the index position and then increment but is there a easier way?
}
How would you get the next element/previous? I know there are iterators i can use and so on but i want to know a neat way to do it in a for loop.
You can but don't do it as the time complexity of the loop will
increase. Just use a normal loop with an int i looping variable.
If you still want to do it you can find the index this way:
int index = lst.indexOf(data);
Then index+1 is the index of the next element.
And index-1 is the index of the previous element.
Make two methods for next and pervious and pass list and element.
public static <T> T nextElement(List<T> list,T element){
int nextIndex=list.indexOf(element)+1;
return list.size()<nextIndexlist?null:list.get(nextIndex);
}
public static <T> T previousElement(List<T> list,T element){
int previousIndex=list.indexOf(element)-1;
return list.size()>previousIndexlist?null:list.get(previousIndex);
}
1)First way
for(ObjectList data : objectList){
ObjectList previousElement=previousElement(objectList,data);
ObjectList nextElement=nextElement(objectList,data);
}
2) Second way
for(int i=0;i<=objectList.size();i++){
ObjectList previousElement=objectList.size>i-1?null:objectList.get(i-1);
ObjectList nextElement=objectList.size<i+1?null:objectList.get(i+1);
}
3) Third way using iterator
Actually, your for-each isn't iterating a List. This,
List<ObjectList> = //set of values inside.
for(Object data : ObjectList){
}
Should look something like,
List<ObjectList> al = new ArrayList<>();
for(ObjectList data : al){ // <-- like so.
}
But that won't find any data until you populate the List.
Using a "normal" for-loop, this might be, what you are looking for:
List<Object> objectList = new ArrayList<>();
// add some data
for (int i = 0; i < objectList.size(); i++) {
System.out.println((i > 0) ? "previous Object: " + objectList.get(i - 1) : "No previous object, current is the first one.");
System.out.println("Current Object: " + objectList.get(i));
System.out.println((i < objectList.size()) ? "Next Object: " + objectList.get(i + 1) : "No next object, current is the last one.");
}
Key aspect is, that you have to use your loop variable (i in this case) to access your actual elements. i + 1 gives you the next element and i - 1 the previous.
I think what you is an iterator, its used like this:
List<ObjectList> list= //set of values inside.
Iterator<ObjectList> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
System.out.println(iterator.previous());
iterator.next()
}
It allows you to access the next and previous objects.
ListIterator:
There is the ListIterator which can a bit of stepping back and forth.
Mind in the code below previousIndex() yields -1 at the start.
for (ListIterator<Object> iter = objectList.listIterator(); iter.hasNext(); ) {
Object object = iter.next();
Object previous = objectList.get(iter.previousIndex()); // Might fail
Object next = objectList.get(iter.nextIndex()); // Might fail
if (iter.hasPrevious()) ... iter.previous();
}
My program is a very simple one. All I need to do is track the duplicates and print the unique and the duplicate elements separately. I am using a hashmap for this. (dup is an arraylist containing all the elements)
Map<Employee, Integer> newMap = new HashMap();
int count = 0;
for (Employee element : dup) {
System.out.println("oooo" + element);
if (newMap.put((Employee) element, count) != null) {
newMap.put((Employee) element, newMap.get(element) + 1);
}
}
System.out.println("oooo" + newMap);
The o/p generated is:
Employee No :9 Employee Name :Swasti Employee MailId :swasti#gmail.com=0, Employee No :2 Employee Name :Shanthi Employee MailId :shanthi#gmail.com=0
The records with duplicates are incremented and the o/p is :
Employee Name :Shreya Employee MailId :shreya#gmail.com=1, Employee Name :Sujatha Employee MailId :suravich#gmail.com=1
The problem here is that the count is not incrementing more than one for records with more number of duplicates. I don't understand why. Any sort of help on this would be appreciated.
P.S: I tried doing this with an arraylist and a hashset and did get an output but using a map seemed like a better way.
This is because with this line:
if (newMap.put((Employee) element, count) != null) {
you put 0 again each time (since count is always 0 in your code). And on the next line, your newMap.get(element) will therefore be 0...
You need to grab the old value and check that it is not null:
Integer oldValue = newMap.put((Employee) element, 0);
if (oldValue != null)
newMap.put((Employee) element, oldValue + 1);
Note that your dup should be a List<Employee>, not a raw List. This would avoid all the casts you have to make currently.
if (newMap.containsKey(element)) {
newMap.put(element, newMap.get(element) + 1);
}
Also since you using generics you need to typecast.
if (newMap.get(element) != null) {
newMap.put(element, newMap.get(element) + 1);
} else {
newMap.put(element, 1);
}