0

我有一个字符串序列和一个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

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

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

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

4 回答 4

3

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

我猜你想要这样的东西:

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

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

编辑:

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

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(...)调用嵌入在匿名比较器中。这样,您只需迭代一次,并且在每次迭代中,您将执行二进制搜索,而不是遍历所有剩余的映射条目。

于 2013-09-10T13:17:17.247 回答
1
  1. 为什么Iterator在 Java 有更好的时候使用foreach
  2. 把你的两个if's转成if-else,没有理由在第二个写相反的条件if
  3. 将这些字符串放入其中ArrayList并从中删除那些找到的。然后,最后,只列出剩余的。
于 2013-09-10T13:17:37.853 回答
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
于 2013-09-10T13:20:15.180 回答
0

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

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

于 2013-09-10T13:22:30.173 回答