0

I have an Integer ArrayList with elements e.g. 60,45,60,15 - These are activity minutes. Each of these elements have an associated Activity Names. E.g. Activity A has time of 60, Activity B has time of 45, etc.

How to write a function in Java which given integer value, can return Activity Name? Initially I thought HashMap was correct, but since minutes can be duplicate, it overwrites the previous value if its same and I am not interested in implementing a custom Map similar to MultiValueMap of Guava collections.

Any clues to implement this helps.

EDIT 1:

I tried implementing as suggested by Wasi - however, I am getting IndexOutOfBoundsException. I am expecting both activities from mapping60, 1 activity from mapping15, and 1 activity from mapping45. What am I doing wrong?

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MultiMapTest {

public static void main(String[] args) {

    Map<Integer, List<String>> map = new HashMap<Integer, List<String>>();

    List<String> activityMappings60 = new ArrayList<String>();
    activityMappings60.add("Act 1 60min");
    activityMappings60.add("Act 2 60min");

    List<String> activityMappings15 = new ArrayList<String>();
    activityMappings15.add("Act 3 sprint");
    activityMappings15.add("Act 4 sprint");

    List<String> activityMappings45 = new ArrayList<String>();
    activityMappings45.add("Act 5 45min");
    activityMappings45.add("Act 6 45min");


    map.put(new Integer(60), activityMappings60 );
    map.put(new Integer(15), activityMappings15 );
    map.put(new Integer(45), activityMappings45 );

    List<Integer> arrayInteger = Arrays.asList(60,60,15,45);

    for(Integer i=0; i < arrayInteger.size();i++) {
        System.out.println(map.get(arrayInteger.get(i)).get(i));
        System.out.println(map.get(arrayInteger.get(i)).remove(i));
    }

}
6
  • 2
    If there two activity with same integer value then which one's name you want? You can use HashMap<Integer, ArrayList<String>> and it should work for you. Commented Dec 11, 2016 at 7:15
  • you can create an object with 2 members activity and duration and fill them in an ArrayLsit, BUT, you need to solve the duplicate issue, even if you can have 2 records with same duration (say 60) and different activity names, then when giving duration 60 to the function which activity should be returned?? Commented Dec 11, 2016 at 7:20
  • any one of the activity should be returned - but once its returned, I want to remove it from the source list, so next call with 60 should return the other one. Commented Dec 11, 2016 at 7:26
  • since you maybe often make remove operation then you can use HashMap<Integer,LinkedList<Srting>> for it's more simple about remove operation. Commented Dec 11, 2016 at 7:29
  • 1
    i can see Wasi Ahmad sol is good, you can take that concept and wrap it in a class with basic operation [add(), remove(), find()]. Commented Dec 11, 2016 at 7:36

3 Answers 3

1

The only problem in your code is when get and remove from the activities list you should not use i. Use 0 instead to get and remove the first element always. This should work in your loop:

List<String> list = map.get(arrayInteger.get(i));
    if (list != null && !list.isEmpty()) {
        System.out.println(list.remove(0));
}

The output I got:

Act 1 60min
Act 2 60min
Act 3 sprint
Act 5 45min

The whole thing I use:

public static void main(String[] args) {
    Map<Integer, List<String>> map = new HashMap<Integer, List<String>>();

    List<String> activityMappings60 = new ArrayList<String>();
    activityMappings60.add("Act 1 60min");
    activityMappings60.add("Act 2 60min");

    List<String> activityMappings15 = new ArrayList<String>();
    activityMappings15.add("Act 3 sprint");
    activityMappings15.add("Act 4 sprint");

    List<String> activityMappings45 = new ArrayList<String>();
    activityMappings45.add("Act 5 45min");
    activityMappings45.add("Act 6 45min");

    map.put(new Integer(60), activityMappings60);
    map.put(new Integer(15), activityMappings15);
    map.put(new Integer(45), activityMappings45);

    List<Integer> arrayInteger = Arrays.asList(60, 60, 15, 45);

    for (Integer i = 0; i < arrayInteger.size(); i++) { // inside loop I use my code as above
        List<String> list = map.get(arrayInteger.get(i));
        if (list != null && !list.isEmpty()) {
            System.out.println(list.remove(0));
        }
    }

}
Sign up to request clarification or add additional context in comments.

2 Comments

Still getting the same IndexOutOfBoundException.
Did you try running it with the code I added? If yes, can you paste the entire example that you tested? May be I am not doing it right.
1

I guess this is what you are looking for.

public static void main(String[] args) {
    HashMap<Integer, ArrayList<String>> duration_to_activity_map = new HashMap<>();

    ArrayList<String> activityList = new ArrayList<>();
    activityList.add("A");
    activityList.add("B");
    duration_to_activity_map.put(30, activityList);

    activityList = new ArrayList<>();
    activityList.add("C");
    activityList.add("D");
    duration_to_activity_map.put(60, activityList);

    System.out.println(duration_to_activity_map.toString());
}

It prints:

{60=[C, D], 30=[A, B]}

So, if you want the activities with duration 60, it will give you [C, D].

System.out.println(duration_to_activity_map.get(60)); // prints - [C, D]

Remove elements from ArrayList: See this tutorial. But as @cainiaofei said, LinkedList is better option as implementation of List interface since you need to remove elements.

4 Comments

Kind of, but the minutes can be duplicate i.e. there could be multiple activities with value 60. So I want to return the first value and use it for printing and then remove this selected element from the list. Next time when other activity with 60 min comes, I want to retrieve the next value from the list.
@YogendraJ you can do that. just remove the element from ArrayList using index and return the first element from ArrayList every time when you need to print it.
I tried implementing the example as you suggested, but getting indexOutOfBoundsException. I have updated the question with my example. Can you point it where I am going wrong?
This is also correct answer and I was able to achieve what I needed. Thanks again, Wasi.
0

just as Wasi Ahmad advice you can use Map<Integer,List> and since you maybe often make delete operation, i think use LinkedList is better.

here is a demo:

public void demo(){
    Map<Integer,List<String>> map = new HashMap<Integer,List<String>>();
    List<String> innerList = new LinkedList<String>();
    innerList.add("d1");
    innerList.add("d2");
    map.put(60, innerList);
    System.out.println(map.get(60).remove(0));
    System.out.println(map.get(60).remove(0));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.