0

we are facing a challenge in implementing one of our client requirement, using java as code technology. we need to format the input given by the system, to display the data in a userfriendly format.

below is the data as input to our program. its a java map with key as string and value as a list of strings

OP1004=[],
OP1006=[OP1004]
OP1005=[OP1003]
OP1009=[OP1006, OP1044, OP1046, OP1004], 
OP1016=[OP1008, OP1009, OP1044, OP1005, OP1004], 

output we are expecting as below.

OP1004=[],
OP1006=[OP1004]
OP1005=[OP1003]
OP1009=[OP1006, OP1044, OP1046], //here 1004 is deleted
OP1016=[OP1008, OP1009, OP1005, OP1004], //here 1044 is deleted

here, if we observe closely, we want to delete the repeated values from the list, that is

if we go thru the bottom, that is OP1016 contains the list as OP1008, OP1009 etc.. where OP1009 also has the list as OP1006, OP1044 etc.. where OP1006 again has the list as OP1004 so here we want to delete OP1004 from OP1009 because its already mapped to other(OP1006) OPID which is part of OP1009.

actually we are displaying this in a hierachy/flowchart diagram, so we want to delete duplicate navigation to the items.

Please help us in providing solution. appreciate your help in advance.

Thanks

  • Please post some code of what you've tried so far. – Reinard Oct 19 '16 at 13:23
  • 3
    have you considered using a set instead of a list? – Ash Oct 19 '16 at 13:24
  • Possible duplicate of [Removing an object from the duplicate ArrayList only](http://stackoverflow.com/questions/7543131/removing-an-object-from-the-duplicate-arraylist-only) – akshay Oct 19 '16 at 13:26
  • loop through each key of Map. inside value of key - loop through your arraylist if duplicates are found, remove them. alternatively, do as @AshFrench said :). – Abbas Kararawala Oct 19 '16 at 13:26
  • Possible duplicate of [How do I remove repeated elements from ArrayList?](http://stackoverflow.com/questions/203984/how-do-i-remove-repeated-elements-from-arraylist) – Abbas Kararawala Oct 19 '16 at 13:29
  • So you want to check whether elements in a value list exists in other values list. Is that what you want? – Ravikumar Oct 19 '16 at 14:42
  • We have more lists like this, we need to compare among those all, simple set may not work for us. as we need to remove only if that is already pointing to particular item. – Shivaji Dole Oct 20 '16 at 05:46
  • Tried below snippet, but not worked `private boolean isOperationPresent(String operId, String b4opr, Map> oprB4OprMap) { boolean flag = false; if (isEmptyString(b4opr)) return flag; List opList = oprB4OprMap.get(operId); List b4List = oprB4OprMap.get(b4opr); for (String s : opList) { List sList = oprB4OprMap.get(s); if(!b4List.contains(s)){ flag = true; break; } } return flag; }` – Shivaji Dole Oct 20 '16 at 06:13
  • @Ravikumar Yes Ravikumar, we ant to know if that item is already present in any of the other associated item. – Shivaji Dole Oct 20 '16 at 06:22
  • @Ravikumar Yes Ravikumar, we want to know if that item is already present in any of other key/value here if we take 1016 it has 1009 in its list. 1009 has 1006 in its list, and then 1006 has 1004 in its, here we want to delete 1004 from 1016 as its already mapped to other key. association like, 1016->1009->1006->1004 1016->1008 1016-> but we dont want associations like 1016->1004 x 1009->1004 x etc Actually we are using this map to make associations directly, whatever present, which is not a requirement, so we want to remove them in map itself. – Shivaji Dole Oct 20 '16 at 06:32
  • @ShivajiDole I have added an answer, check it once. – Ravikumar Oct 20 '16 at 08:29

4 Answers4

0

A simple solution would be to change the

Map<String, List<String>> to Map <String<Set<String>>

Let me explain it in a better way:

List list = map.get(str);
Set<String> set = new HashSet<>();
set.addAll(list);
list.clear();
list.addAll(set);

now you can use it in the way you want..

Let me know if you didnt understand any part of it

0

Pseudo-code: if key exists then remove it from any values (of other keys)

for (String key : map.keySet()){ // iterate through all keys
 for (Map.Entry<String, List> mapEntry : map.entrySet()){ // again iterate but this time get Map.Entry
  if (!mapEntry.getKey().equals(key)){ // if entry is for other key
   ((List)mapEntry.getValue()).remove(key); // then remove key from list
    // if this map cannot be modified you can keep key, mapEntry in another map here...
  }
 }
}
donlys
  • 440
  • 6
  • 13
0

Create a set to hold all the values previously displayed. If an item can not be added to this set, then do not add it at all.

Map<String, String[]> original = ...
Set<String> used = new HashSet<>();
Map<String, String[]> reduced = original
        .entrySet().stream()
        .collect(Collectors.toMap(Map.Entry::getKey,
                entry -> Arrays.stream(entry.getValue())
                        .filter(used::add)
                        .toArray(String[]::new)));
flakes
  • 21,558
  • 8
  • 41
  • 88
0

Your problem boils down to checking whether elements of a list are present in other lists but these list are present in a map so you need to maintain the key-value pair.

This is how you can achieve that.

  1. Loop over map and get the key and list of values, add a condition to check whether list is empty and contains more than 1 values.
  2. Loop over same map again, get the key and add a condition to check whether the first loop key is equal to second loop key this is to avoid checking for same list. Add one more condition to check whether list is empty and contains more than 1 values.
  3. Now you can remove elements from a list if those elements are present in another list by using List.removeAll() method.

Sample code

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

public class Example {

public static void main(String[] args) {

    List<String> firstList = new ArrayList<String>();
    firstList.add("");

    List<String> secondList = new ArrayList<String>();
    secondList.add("OP1004");

    List<String> thirdList = new ArrayList<String>();
    thirdList.add("OP1003");

    List<String> fourthList = new ArrayList<String>();
    fourthList.add("OP1006");
    fourthList.add("OP1044");
    fourthList.add("OP1046");

    List<String> fifthList = new ArrayList<String>();
    fifthList.add("OP1008");
    fifthList.add("OP1009");
    fifthList.add("OP1044");
    fifthList.add("OP1005");
    fifthList.add("OP1004");

    Map<String, List<String>> map = new HashMap<String, List<String>>();
    map.put("OP1004", firstList);
    map.put("OP1006", secondList);
    map.put("OP1005", thirdList);
    map.put("OP1009", fourthList);
    map.put("OP1016", fifthList);

    for (Map.Entry<String, List<String>> keyAndValue: map.entrySet()) {
        String key = keyAndValue.getKey();
        List<String> values = keyAndValue.getValue();

        if (values.isEmpty() || (values.size() < 2)){
            continue;
        }
        for (Map.Entry<String, List<String>> mapKeyAndValue: map.entrySet()) {

            String key1 = mapKeyAndValue.getKey();
            if (key.equals(key1)){
                continue;
            }
            List<String> values2 = mapKeyAndValue.getValue();

            if (values2.isEmpty() || (values2.size() < 2)){
                continue;
            }
            values2.removeAll(values);
        }
    }

    for (Map.Entry<String, List<String>> keyAndValue: map.entrySet()) {
        System.out.println("Key is " + keyAndValue.getKey() + " Values are " + keyAndValue.getValue());
    }
}
}

Check Output Here

 Key is OP1004 Values are []
 Key is OP1006 Values are [OP1004]
 Key is OP1005 Values are [OP1003]
 Key is OP1009 Values are [OP1006, OP1044, OP1046]
 Key is OP1016 Values are [OP1008, OP1009, OP1005, OP1004]

Note - I assumed that you are using HashMap as you didn't specify what kind of map you are using and if you want the map to be ordered then use LinkedHashMap as HashMap does not store elements in order.

Ravikumar
  • 891
  • 12
  • 22