根据我的序列对哈希映射进行排序

时间:2013-09-10 12:57:52

标签: java sorting hashmap

我有一个字符串序列和一个HashMap。我需要根据序列对我的hashmap进行排序。如果hashmap包含序列中存在的字符串,那些字符串应该按照序列排序并打印。

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());
 }

我到这里的输出是

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

我的预期输出:

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

在我的代码中,我将不等于序列的元素存储到一个arraylist中并打印出来。但我无法正确设计循环,这将只添加不包含字符串的其余元素。帮助我。谢谢

编辑:对于同样的问题,我试着写一个比较器。但它不起作用

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;

             }
         }; 

4 个答案:

答案 0 :(得分:3)

您的问题似乎是,您正在迭代序列,并且对于该序列中的每个元素,您将迭代地图并添加每个不匹配的元素。

我想你想要这样的东西:

  • 创建地图副本
  • 表示序列中的每个元素
    • 表示地图副本中的每个条目(在此处使用迭代器,因为您必须在其上调用remove()
      • 如果条目与sequ​​enc元素匹配
        • 添加到列表
        • 从地图副本中移除当前条目(这就是您需要副本的原因)
  • 执行此操作后,列表按顺序包含所有匹配的元素,地图副本包含所有不匹配的元素

您的案例中的问题是地图键和序列元素不完全匹配,否则您可以优化它以获得更好的查找。

修改

另一种选择可能是使用TreeMap和查找包装器,如下所示:

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() + ")");
}

输出将是:

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)

请注意,contains(...)调用嵌入在匿名比较器中。这样你就必须只迭代一次,在每次迭代中你都要进行二进制搜索,而不是遍历所有剩余的地图条目。

答案 1 :(得分:1)

  1. 为什么在Java有更好的Iterator
  2. 时使用foreach
  3. 将您的两个if's转为if-else,没有理由在第二个if中写出相反的条件
  4. 将该字符串放入某些ArrayList并从中删除那些已找到的字符串。然后,最后,列出剩下的。

答案 2 :(得分:1)

在两个循环中这样做要容易得多:

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());
}

这会生成输出

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

答案 3 :(得分:0)

java.util.HashMap 是无序的。此类不保证地图的顺序。特别是,它不保证订单会随着时间的推移保持不变。

在您的情况下, java.util.LinkedHashMap 将是最佳选择。一旦排序,它将保持排序并以排序的方式返回所有元素。