【问题标题】:Rapid way to represent Map<K, V> as Map <U, List<V>>将 Map<K, V> 表示为 Map <U, List<V>> 的快速方法
【发布时间】:2014-02-24 15:10:38
【问题描述】:

我有: Map&lt;Long, Peer&gt;,其中键是 peerUidvaluePeer。每个Peer 类似于用户会话容器并包含UserAuthorities

public class Peer {
  private UserAuthorities authorities;
  //...
}

我需要:

快点做:

  1. [in half of requests] 获取所有对等点:List&lt;Peer&gt;
  2. [在每个请求中] 获取按UserAuthorities 分组的所有对等点:Map&lt;UserAuthorities, List&lt;Peer&gt;&gt;
  3. [一次用于浏览器选项卡] 添加新对等点(使用 null UserAuthorities 并在一段时间后设置用户权限)
  4. [arrely] 通过peerUid 删除对等体或通过UserAuthorities 删除所有对等体
  5. 最终在并发环境中实现以上四个语句

问题:

当我在地图上添加新的Peer 时,我还没有UserAuthorities。这意味着UserAuthorities 是可变的。

问题:

  1. 有什么方法可以快速从Map&lt;Long, Peer&gt; 得到Map&lt;UserAuthorities, List&lt;Peer&gt;&gt;? (对等点的大约数量约为 20;但该操作将针对每个用户请求进行)
  2. 如果不是,如果 Peer.userAuthorities 是可变字段,我该如何实现?

P.S:UserAuthorities 何时更改?

答案很简单——只登录一次。用户进入主页,他在服务器端得到Peer,但还没有任何权限。所以他登录并获取它们。

【问题讨论】:

  • 您的意思是 group by UserAuthorities?
  • @RohitJain 是那个 API 方法吗?
  • 没有。只是问问而已。你说的是sort,但这看起来更像是分组。
  • @RohitJain 是的,我提到了groupBy。谢谢
  • 我认为“权威”的可变性是一个关键点(这不是政治声明)。只要没有内置的通知机制,就无法通知任何集合有关此字段的更改。因此,唯一的选择是每次从头开始“透明地”创建查询数据(与此字段相关),这可能是您想要避免的。您能否详细说明如何/何时修改 authorities 字段?或者是否有一些可能的通知机制(例如可以添加interface PeerListener { void authorityChanged() }

标签: java collections map concurrency


【解决方案1】:

这不是一个答案,所以从技术上讲,它可能必须被删除 - 但是这样的事情很难在评论中讨论......:

所以我假设数据结构应该是这个接口LoginDatastructure,这样对吗?

import java.util.List;
import java.util.Map;

class UserAuthorities {}
class Peer 
{
    private UserAuthorities authorities;
}

interface LoginDatastructure
{
    // 1. Get all peers
    List<Peer> getAllPeers();

    // 2. Get all peers grouped by UserAuthorities
    Map<UserAuthorities, List<Peer>> getPeersByUserAuthority();

    // 3. Add new peer (with null UserAuthorities 
    // and after some time set user authorities)
    void addPeer(Peer peer);

    // 4a Remove peer by peerUid 
    void removePeer(long peerUid);

    // 4b. Remove peer by peerUid or all peers by UserAuthorities
    void removePeers(UserAuthorities u);
}

你的Map&lt;Long, Peer&gt;在这个例子中出现在哪里?

关于3.:当peer被添加时,它有一个nullUserAuthority,它应该包含在方法1返回的列表中吗?它是否应该包含在方法 2 返回的地图中?

List<Peer> peersWithNull = map.get(null);

?

关于更改的 UserAuthority:当 User Authority 更改时,是否可以通知此数据结构?也就是说,LoginDatastructure 是否可以有一个额外的方法,比如

void userAuthorityWasSet(Peer peer);

当给定对等体的 UserAuthority 更改时将调用该函数?

关于第 5 点,并发:有什么理由不公然制作所有这些方法synchronized


编辑:关于同步:你期望什么样的线程安全?例如,当添加一个 Peer 时,这是否应该自动在某人可能从方法 2 的 Map 获得的所有 Lists 中可见?设置权限时是否也应该更新这些列表?无论如何,到目前为止,这些方法主要是在数据结构中添加/删除元素,所以我认为将它们设为synchonrized 不会对性能产生任何显着影响(当然,除非数据结构,如地图,在每次通话期间从头开始重建 - 但我认为您无论如何都想避免这种情况。

无论如何,我觉得 StackOverflow 可能不适合进行这种讨论....

【讨论】:

  • 关于#3 的回答是:应包括具有null 权限的同行。更改 UserAuthorities 的方法也在我的班级中,我可以修改它。最后一个 - 对我来说,让所有方法 synchronized 似乎是个坏主意,因为我的应用程序基于非阻塞 io (websockets),并且会有许多用户同时使用相同的 peers 集合进行操作。
  • @Volodymyr Bakhmatiuk 添加了一个编辑,但认为这里很难快速找到解决方案......
【解决方案2】:
  1. 检查Map API:Map#values()
  2. ?
  3. 检查Map API:Map#remove()
  4. ?
  5. ?

【讨论】:

  • 我熟悉地图 API。 map@values() 返回列表。比起按 UserDetails 参数对该列表进行排序,我应该遍历所有列表 O(n) 并执行 O(n) equals 调用。很慢
  • 是的,如果这能显着提高您的速度,您可以在地图值上保留另一个视图,按某些参数排序并由具体值支持。
猜你喜欢
  • 2019-01-23
  • 1970-01-01
  • 2018-11-23
  • 2011-12-02
  • 2022-01-23
  • 2019-10-10
  • 2013-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多