在特定索引的树形图中插入键值对

时间:2016-05-26 16:16:14

标签: java collections

我需要将元素放在Map中,然后选择TreeMap实现,键将按照升序排序顺序放置在地图中,但其中一个键是"未分配"永远应该是第一个。这可能吗 ? 我当前的代码只将元素放在一个排序的顺序中?

public class TreeMapTest {

    public static void main(String args[]){
        //the treemap sorts by key
        Map<String, String> hm = new TreeMap<String, String>(new StringComparator());
        //add key-value pair to TreeMap
        hm.put("carrot","12");
        hm.put("apple", "34");
        hm.put("domboi","912");
        hm.put("unassigned","?");
        hm.put("banana", "45");  
        hm.put("zucchini","87");
        System.out.println("TreeMap Entries:");
        System.out.println(hm);

    }
}

class StringComparator implements Comparator<String>{

    @Override
    public int compare(String str1, String str2) {
        return str1.compareTo(str2);
    }

}

当前输出

{apple=34, banana=45, carrot=12, domboi=912, unassigned=?, zucchini=87} 

我希望输出为

{unassigned=?,apple=34, banana=45, carrot=12, domboi=912,zucchini=87}

2 个答案:

答案 0 :(得分:6)

只需更改Comparator即可:

class StringComparator implements Comparator<String> {

    @Override
    public int compare(String str1, String str2) {
        if (str1.equals(str2)) {
            return 0;
        } else if ("unassigned".equals(str1)) {
            return -1;
        } else if ("unassigned".equals(str2)) {
            return 1;
        }
        return str1.compareTo(str2);
    }
}

<强>输出:

TreeMap Entries:
{unassigned=?, apple=34, banana=45, carrot=12, domboi=912, zucchini=87}

答案 1 :(得分:1)

实际上,可以在某个位置注入元素。因此,例如,特殊条目可以在迭代中出现在第三位。

为了好玩,我想出了以下憎恶。我没有修改订单,而是将TreeMap与一个额外的伪条目包装在一起。我并不过分对迭代过程中如何处理条目删除过于自信,但希望你能得到这个想法。

我应该指出,此地图将始终具有“未分配”条目,默认值为null。如果您不希望这样,可以使用类似的方法,但等待添加“未分配”键时将entries成员从TreeSet切换为SillySet。或类似的东西。

import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;

final class SillyMap<K, V>
  extends AbstractMap<K, V>
{

  private final SillySet entries;

  SillyMap(K key, int unassigned)
  {
    entries = new SillySet(key, unassigned);
  }

  @Override
  public Set<Map.Entry<K, V>> entrySet()
  {
    return entries;
  }

  @Override
  public V put(K key, V value)
  {
    if (entries.extra.getKey().equals(key))
      return entries.extra.setValue(value);
    else
      return entries.map.put(key, value);
  }

  private final class SillySet
    extends AbstractSet<Map.Entry<K, V>>
  {

    final Map<K, V> map = new TreeMap<>();

    final Map.Entry<K, V> extra;

    private final int unassigned;

    SillySet(K key, int unassigned)
    {
      extra = new SimpleEntry<>(Objects.requireNonNull(key), null);
      if (unassigned < 0)
        throw new IllegalArgumentException();
      this.unassigned = unassigned;
    }

    @Override
    public Iterator<Map.Entry<K, V>> iterator()
    {
      return new Iterator<Map.Entry<K, V>>()
      {

        private final Iterator<Map.Entry<K, V>> i = map.entrySet().iterator();

        private int index = 0;

        @Override
        public boolean hasNext()
        {
          return index < size();
        }

        @Override
        public Map.Entry<K, V> next()
        {
          Map.Entry<K, V> e;
          if (index == Math.min(unassigned, map.size()))
            e = extra;
          else
            e = i.next();
          ++index;
          return e;
        }

        @Override
        public void remove()
        {
          if (index - 1 == unassigned)
            throw new UnsupportedOperationException();
          i.remove();
          --index;
        }

      };
    }

    @Override
    public int size()
    {
      return map.size() + 1;
    }

  };

  public static void main(String... argv)
  {
    final String KEY = "unassigned";
    Map<String, String> hm = new SillyMap<>(KEY, 3);
    hm.put("carrot", "12");
    hm.put("apple", "34");
    hm.put("domboi", "912");
    hm.put(KEY, "?");
    hm.put("banana", "45");
    hm.put("zucchini", "87");
    System.out.println(hm);
  }

}