Java O(1)的映射搜索键和值

Java O(1)的映射搜索键和值,java,algorithm,data-structures,kotlin,hashmap,Java,Algorithm,Data Structures,Kotlin,Hashmap,假设我有一门课: data class User(val userId: String, val roles: List<String>) 数据类用户(val userId:String,val角色:List) 另外,我有一些字符串sessionId,我需要O(1)时间来通过sessionId和userId检索数据 我原以为BiMap可以解决我的问题,但按用户搜索不是O(1),因为我需要先将User转换为userId 另一个解决方案是覆盖User的hashcode/equals,

假设我有一门课:

data class User(val userId: String, val roles: List<String>)
数据类用户(val userId:String,val角色:List)
另外,我有一些字符串
sessionId
,我需要
O(1)
时间来通过
sessionId
userId
检索数据

我原以为
BiMap
可以解决我的问题,但按用户搜索不是
O(1)
,因为我需要先将
User
转换为
userId


另一个解决方案是覆盖
User
的hashcode/equals,它只考虑
userId
,但这是一个肮脏的攻击。

User
转换为
userId
O(1)
。如果你在做复杂度分析,你只需要取指数最大的项,去掉其余项

如果您执行相同的操作1000次,如果总是执行1000次操作,则仍然是
O(1)
。如果操作的数量是恒定的,并且不取决于输入的大小
O(1)
复杂度,但您有高恒定因子

至于你的问题:

您可以使用任意数量的
Map
s来查找
用户
s,但仍然是
O(1)

val sessionLookup=mapOf()
val userIdLookup=mapOf()
这里有两个
Map
s,它们将会话ID和用户ID映射到
user
本身

这里重要的是为
用户
-
用户
会话ID
-
用户
创建查找(例如:在
用户
会话ID之间的映射),并且通过会话ID或用户ID获取用户的操作是
O(1)
,因为您不必搜索。您可以将空间复杂度(映射的大小)转换为时间复杂度(将
O(n)
搜索转换为
O(1)
查找)


如果你真的想进行渐进复杂性分析,我建议。

sessionId
userId
Map
和从
userId
User
的第二个
Map
怎么样?“按用户搜索不是O(1),因为我需要先将用户转换为userId。”这是没有意义的。强制转换的复杂性是O(1)。并且有两个O(1)操作仍然会使整个算法也是O(1)。@ErwinBolwidt我需要迭代所有元素,强制转换它们(N),然后进行搜索(1),还是我错了?你能详细说明一下吗?你需要更多地了解复杂性。即使你按顺序组合1000个步骤,每个步骤都是O(1),结果仍然是O(1)。当你想“按用户搜索”时,你的输入是什么若要获取会话id?角色列表是否是搜索输入的必要部分?如果否,则拥有从UserId到SessionID的第二个映射是一个有效的解决方案。如果愿意,可以将这两个映射包装在facade类中,以保持同步。或者,使用equals()正如您所建议的,如果它适合您的其余业务逻辑,也会很好。的确,但现在出现了两个映射的同步问题,不是吗?这始终是一个折衷办法。您可以执行搜索
O(n)
或查找
O(1)
。因为您已经维护了一个
用户列表(我猜)维护两个
Map
s也不难。
val sessionLookup = mapOf<String, User>()
val userIdLookup = mapOf<String, User>()