0

I have a string sequence and a HashMap.I need to sort my hashmap according to the sequence.If the hashmap contains strings which is present in the sequence,those strings should sort according to the sequence and print.

String sequence="People,Object,Environment,Message,Service";
HashMap<String, String> lhm = new HashMap<String, String>();
List<String> list=new ArrayList<String>();
lhm.put("Objectabc", "biu");
lhm.put("Message someText", "nuios");
lhm.put("Servicexyxyx", "sdfe");
lhm.put("People bcda", "dfdfh");
lhm.put("Environment qwer", "qwe");
lhm.put("Other", "names");
lhm.put("Elements", "ioup");            
lhm.put("Rand", "uiy");

// Get a set of the entries
Set<Entry<String, String>> set = lhm.entrySet();
String[] resultSequence=sequence.split(",");

for(int j=0;j<resultSequence.length;j++)
{
    Iterator<Entry<String, String>> iter = set.iterator();
    while(iter.hasNext()) {

       Map.Entry me = (Map.Entry)iter.next();
       String res=(String) me.getKey();

       if(res.contains(resultSequence[j]))
       {
           System.out.println("values according with the sequence is "+res);
       }
       if(!res.contains(resultSequence[j]))
       {
           list.add(res);
           // System.out.println("values not according with the sequence is "+res);
       }

    }  

 }

 List<String> list2=new ArrayList<String>(new LinkedHashSet<String>(list));

 Iterator<String> iterlist2=list2.iterator();
 while(iterlist2.hasNext())
 {
     System.out.println("non equal elements are "+iterlist2.next());
 }

The output I'm getting here is

values according with the sequence is People bcda
values according with the sequence is Objectabc
values according with the sequence is Environment qwer
values according with the sequence is Message someText
values according with the sequence is Servicexyxyx
non equal elements are Elements
non equal elements are Other
non equal elements are Servicexyxyx
non equal elements are Objectabc
non equal elements are Message someText
non equal elements are Rand
non equal elements are Environment qwer
non equal elements are People bcda

My Expected output:

values according with the sequence is People bcda
values according with the sequence is Objectabc
values according with the sequence is Environment qwer
values according with the sequence is Message someText
values according with the sequence is Servicexyxyx
non equal elements are Elements
non equal elements are Other
non equal elements are Rand

In my code I'm storing the elements which are not equal to sequence into an arraylist and printing that.But I can't design the loop properly which will add only the remaining elements which does not contains strings in sequence.Somebody help me on this.Thanks

EDIT:For this same problem I tried to write a comparator. But it not works

Comparator<String> comparator = new Comparator<String>() {
             @Override
             public int compare(String key1, String key2) {
                 int returned = sequence.indexOf(key1) - sequence.indexOf(key2);

                 if (returned == 0 && !key1.contains(key2))
                     returned = -1;

                 return returned;

             }
         }; 
Vignesh Vino
  • 1,242
  • 4
  • 25
  • 50

4 Answers4

3

Your problem seems to be, that you're iterating over the sequence and for every element in that sequence you're iterating over the map and add each non-matching element.

I guess you want something like this instead:

  • create a copy of the map
  • for each element in the sequence
    • for each entry in the map copy (use an iterator here, since you'll have to call remove()on it)
      • if the entry matches the sequenc element
        • add to the list
        • remove the current entry from the map copy (that's why you need the copy)
  • after doing this, the list contains all matching elements in order and the map copy contains all non-matching elements

The problem in your case is that map keys and sequence elements don't match entirely, otherwise you could optimize that for better lookups.

EDIT:

Another option might be to use a TreeMap and a lookup wrapper, like this:

String sequence = "People,Object,Environment,Message,Service";

Map<String, String> lhm = new TreeMap<String, String>();
lhm.put( "Objectabc", "biu" );
lhm.put( "Message someText", "nuios" );
lhm.put( "Servicexyxyx", "sdfe" );
lhm.put( "People bcda", "dfdfh" );
lhm.put( "Environment qwer", "qwe" );
lhm.put( "Other", "names" );
lhm.put( "Elements", "ioup" );
lhm.put( "Rand", "uiy" );

for( String element : sequence.split( "," ) )
{
  final String elem = element;

  //try to get the value and remove it in one step
  String value = lhm.remove( new Comparable<String>()
  {
    public int compareTo( String other )
    {
      if( other.contains( elem ) )
      {
        return 0;
      }

      return elem.compareTo( other );
    }
  } );

  if( value != null )
  {
    System.out.println("values according with the sequence (key:" + element + ") is " + value); 
  }
}

for( Map.Entry<String, String> e : lhm.entrySet())
{
  System.out.println("non equal elements are " + e.getKey() + " (value: " + e.getValue() + ")");
}

Output would be:

values according with the sequence (key:People) is dfdfh
values according with the sequence (key:Object) is biu
values according with the sequence (key:Environment) is qwe
values according with the sequence (key:Message) is nuios
values according with the sequence (key:Service) is sdfe
non equal elements are Elements (value: ioup)
non equal elements are Other (value: names)
non equal elements are Rand (value: uiy)

Note that the contains(...) call is embedded in the anonymous comparator. That way you'd have to only iterate once and within each iteration you'd do a binary search instead of looping over all remaining map entries.

Thomas
  • 87,414
  • 12
  • 119
  • 157
1
  1. Why use Iterator when Java has a nicer foreach?
  2. Turn your two if's to if-else, there is no reason to write the opposite condition in the second if
  3. Put that Strings in some ArrayList and remove from it those, that are found. Then, at the end, just list the remaining.
Eel Lee
  • 3,513
  • 2
  • 31
  • 49
1

It's much easier to do it in two loops like so:

final String sequence = "People,Object,Environment,Message,Service";
final HashMap<String, String> lhm = new HashMap<String, String>();
final List<String> list = new ArrayList<String>();
lhm.put("Objectabc", "biu");
lhm.put("Message someText", "nuios");
lhm.put("Servicexyxyx", "sdfe");
lhm.put("People bcda", "dfdfh");
lhm.put("Environment qwer", "qwe");
lhm.put("Other", "names");
lhm.put("Elements", "ioup");
lhm.put("Rand", "uiy");

// Get a set of the entries
final Set<Entry<String, String>> set = lhm.entrySet();
final String[] resultSequence = sequence.split(",");

for (int j = 0; j < resultSequence.length; j++)
{
    final Iterator<Entry<String, String>> iter = set.iterator();
    while (iter.hasNext())
    {
        final Map.Entry me = iter.next();
        final String res = (String) me.getKey();

        if (res.contains(resultSequence[j]))
        {
            System.out.println("values according with the sequence is " + res);
        }
    }
}

final Iterator<Entry<String, String>> iter = set.iterator();
while (iter.hasNext())
{
    final Map.Entry me = iter.next();
    final String res = (String) me.getKey();
    boolean found = false;
    for (int j = 0; j < resultSequence.length; j++)
    {
        if (res.contains(resultSequence[j]))
        {
            found = true;
            break;
        }
    }
    if (!found)
    {
        list.add(res);
    }
}

//final List<String> list2 = new ArrayList<String>(new LinkedHashSet<String>(list));

final Iterator<String> iterlist2 = list.iterator();
while (iterlist2.hasNext())
{
    System.out.println("non equal elements are " + iterlist2.next());
}

This generates the output

values according with the sequence is People bcda
values according with the sequence is Objectabc
values according with the sequence is Environment qwer
values according with the sequence is Message someText
values according with the sequence is Servicexyxyx
non equal elements are Elements
non equal elements are Other
non equal elements are Rand
jimjim
  • 420
  • 3
  • 10
0

java.util.HashMap is unordered. This class makes no guarantees as to the order of the map. In particular, it does not guarantee that the order will remain constant over time.

In your case java.util.LinkedHashMap will be a best option. Once sorted it will keep the ordering and return all the elements in the sorted way.

Macrosoft-Dev
  • 2,195
  • 1
  • 12
  • 15