我正在使用Java开发一些财务算法。我有一个复杂的数据结构,有许多属性需要在算法的生命周期内更新。有时这个数据结构更新超过1000次......
为了提高性能,特别是get(search)/update/insert
,我决定使用TreeMap
作为容器,在这方面非常有效。
现在是充满挑战的部分。我需要更新我需要从容器中检索它的数据结构属性,这需要:
这个过程需要三个x log(n),即check,get和put。我想在SINGLE log(n)时间内执行此操作。
为此,我的解决方案是:
我总是使用insert/update/get
在地图中添加对象(put
)。 put
返回旧对象,我使用旧值更新当前对象,这会解决log(n)但不同对象丢失对前一个对象的引用,因为新值已在地图中替换。
是否有更好的解决方案或更好的容器来更新数据结构。我可以使用List
并使用二进制搜索集合,但为此我需要再次对数据结构进行排序,因为列表未排序。
请指导
答案 0 :(得分:1)
我觉得你做得很好。
O(k.log(n))= O(log(n))
其中k是常数。所以你的时间复杂度实际上是O(log(n))
答案 1 :(得分:1)
如果切换到ConcurrentMap.computeIfAbsent(...),您可以在一次点击中获得1
和2
。它返回新/旧对象,以便您可以更新它。
如果Java-7那么putIfAbsent但是需要额外的new
- 如果构造很昂贵,也许是件坏事。
答案 2 :(得分:1)
如果你不害怕周围有可变物体(你似乎给出了你提出的解决方案),你可以用1-2次操作来做。而不是
1. contains()
2a. exists? get(), modify, put()
2b. doesn't exist? create, put()
你可以做到
1. get()
2a. null? create put()
2b. not-null? modify object contents, as you already have reference
通过这种方式,您可以对现有对象进行1次搜索操作,对不存在的对象进行2次搜索操作。
如果你想进一步改进它,你可能想要使用ConcurrentHashMap(在你克服了对哈希码的不信任之后;)和putIfAbsent
1. old = putIfAbsent(createFresh())
2. old not null? update old
说这一切,我通常试图避免可变对象的事情比单一方法的生命周期更长。在某些时候,您可能希望多线程处理您的处理,并且具有可变的东西将使其变得更加复杂。但是存在各种权衡(例如记忆压力),所以这取决于你。但请认真研究一下哈希图,它们可能是你在这里可以做到的最大优化,无论对象(im)是否可变。