映射按值集合的大小排序

时间:2015-12-28 17:17:43

标签: java dictionary java-7 treemap sortedmap

我试图拥有一个有序的地图Map<Integer,Set<Integer>>,它会根据值集的size()对元素进行排序。

实际上,这是连接到该节点的其他节点的节点映射。我想快速(O(logn))访问边缘的节点,而不必每次都排序

例如,订单应为:

3 => {1,2,4,5}
12 => {1,2,3}
14 => {3,2,3}
65 => {3,8}
6 => {2}
2 => {5}

由于TreeMap因为我无法根据值进行排序,所以function User($resource) { return $resource("http://localhost:8080/api/users", {id: "@_id"}, { update: { method: "PUT" } }); } 不会这样做,我可能需要自定义一些内容。

编辑: Set的大小确实可能会发生变化,这可能使事情变得更加复杂

实现这一目标的最简单方法是什么?

2 个答案:

答案 0 :(得分:1)

这是一个如何为此使用两个集合的示例。一组按Set :: size排序,另一组只是一个带整数索引的普通Map。要使用它,您必须在两个映射中保持相同的键/值对。

我不确定我是否建议尝试制作单个地图。它按索引和大小进行了两次查找,因此它并不像常规地图那样工作。这取决于您的使用模式。

package quicktest;

import static java.util.Comparator.comparing;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeMap;

public class TreeMapTest
{
   public static void main(String[] args) {
      TreeMap<Integer,Set<Integer>> index = new TreeMap<>();
      TreeMap<Set<Integer>,Integer> size = new TreeMap<>( comparing( Set::size ) );

      for( int i = 0; i < 5; i++ ) { 
         Set<Integer> set = new HashSet<>();
         for( int val = 0; val <= i; val++ ) {
            set.add( val );
         }
         index.put( i, set );
         size.put( set, i );
      }
      System.out.println( size.lastEntry() ); // largest set size
      System.out.println( index.get( 2 ) );  // random index
   }
}

答案 1 :(得分:1)

这个怎么样?

public class MapAndPriority {
    Map<Integer, Set<Integer>> sets = new HashMap<Integer, Set<Integer>>();
    PriorityQueue<Set<Integer>> byLength = new PriorityQueue<Set<Integer>>(1, new Comparator<Set<Integer>>() {
        @Override
        public int compare(Set<Integer> o1, Set<Integer> o2) {
            // Compare in the reverse order!
            return o2.size() - o1.size();
        }
    });

    public void add(int i, Set<Integer> set) {
        sets.put(i, set);
        byLength.offer(set); // or Add, depending on the behavior you want
    }

    public Set<Integer> get(int i) {
        return sets.get(i);
    }

    public Set<Integer> mostNodes() {
        return byLength.peek();
    }

    public void remove(int i) {
        // sets.remove will return the removed set, so that will be removed from byLength. 
        // Need to handle case when i does not exist as a key in sets
        byLength.remove(sets.remove(i));

    }
}

如果我理解你想要什么,那么这将是:

  1. 在o(nlog(n))
  2. 中添加新集
  3. 常规地图get()
  4. 将获得o(log(n))
  5. 中的最大集合(mostNodes()

    我所做的是将所有集合放在优先级队列中(沿着地图),然后给优先级队列一个比较器,该比较器根据大小进行比较,以便更小的尺寸更大&#34;。这样,当您拨打peek()时,它会返回“最小”字样。优先级队列中的值,由于我们的比较器,它将是最长的集合。 我没有处理各种边缘情况(比如空的时候删除)。

    您可以查看documentation了解更多详情和复杂性。