避免循环并尝试使用集合API(性能)

时间:2011-10-17 19:21:25

标签: java algorithm design-patterns java-ee

我有一段旧项目的代码。

逻辑(高级别)如下:
用户发送一系列{id,Xi},其中id是数据库中对象的主键 目的是更新数据库,但Xi值系列始终唯一

即。如果用户发送{1,X1}并且在数据库中我们有{1,X2},{2,X1}输入应该被拒绝,否则我们最终会重复,即{1,X1},{2,X1},即我们在不同的行中有X1两次。

在较低级别,用户发送一系列封装此信息的自定义对象。

目前,它的实现使用“强力”,即输入和jdbc结果集上的连续for循环,以确保唯一性。

我不喜欢这种方法,而且实际的实现有微妙的错误,但这是另一个故事。

我正在寻找一种更好的方法,无论是在编码还是性能方面。

我在想的是:

  • 从用户的输入列表中创建Set。如果Set的大小与列表不同,则用户的输入具有重复项。在那里。
  • 从jdbc加载数据。
  • 使用用户的输入创建HashMap<Long,String>。关键是主键。
  • 循环结果集。如果HashMap没有contain与ResultSet的行ID具有相同值的键,则将其添加到HashMap
  • 最后将HashMap的值设为List。如果它包含重复的拒绝输入。

这是我提出的算法。
有比这更好的方法吗? (我假设我对自己的算法没有错误)

3 个答案:

答案 0 :(得分:3)

纯粹从性能的角度来看,为什么不让数据库弄清楚是否存在重复(如{1,X1},{2,X1})?在表中有一个唯一的约束,然后当update语句因抛出异常而失败时,捕获它并处理在这些输入条件下你想要做的事情。如果您需要回滚任何部分更新,您可能还希望将其作为单个事务运行。当然,这是假设您没有任何其他业务规则来推动您在此处未提及的更新。

使用您的算法,您花费了太多时间来迭代HashMapList以删除重复的恕我直言。

答案 1 :(得分:1)

由于您无法更改数据库,如评论中所述。我可能会扩展你的Set想法。创建一个HashMap<Long, String>并将数据库中的所有项目放入其中,然后创建一个HashSet<String>,其中包含数据库中的所有值。

然后,当您浏览用户输入时,检查密钥对照散列图并查看值是否相同,如果它们是,那么很好,您不必做任何事情,因为确切的输入已经在您的数据库中。

如果它们不相同,则检查HashSet的值以查看它是否已存在。如果是,那么你有一个副本。

应该比循环更好。

编辑:

对于多个更新,请执行从您的数据库创建的HashMap的所有更新,然后再次检查Map的值集,以查看其大小是否与密钥集不同。

可能有更好的方法可以做到这一点,但这是我得到的最好的。

答案 2 :(得分:1)

我选择了数据库端解决方案。假设一个包含列idvalue的表,您应该创建一个包含所有“值”的列表,并使用以下SQL:

select count(*) from tbl where value in (:values);

:values参数绑定到值列表但是适合您的环境。 (当使用Spring JDBC和支持in运算符的数据库时很简单,对于较小的设置,则较少。作为最后的手段,您可以动态生成SQL。)您将得到一个包含一行和一列的结果集。数字类型。如果为0,则可以插入新数据;如果为1,则报告违反约束。 (如果是其他任何问题,那么你会遇到一个全新的问题。)

如果您需要检查用户输入中的每个项目,请将查询更改为:

select value from tbl where value in (:values)

将结果存储在一个集合中(称为duplicates),然后遍历用户输入项并检查当前项的值是否在duplicates中。

这应该比将整个数据集整理到内存中更好。