0

我有一个从数据库收集信息的程序。

在我之前的问题中,我询问了一个执行,其中一个响应让我重新思考我的循环的想法链接到旧问题:ConcurrentModificationExecption

所以这里是我从数据库中收集的大量信息的背景,其中一个信息是存储在我的数据库中的呼叫类型的名称,例如:邮件、电话等。将是不同类型的联系信息(我们称之为 CallQueues)

由于我提取的信息超过了几天,因此许多呼叫类型都会重复。以下是数据库中行的示例:

ID 姓名 日期 NoC NoAC

1 邮件 2012-11-27 3 3

其中 NoC = 呼叫数,NoAC = 应答呼叫数。

现在我的问题。

我最初的想法是遍历队列列表并查看名称是否重新出现,但这不起作用,因为我无法在循环时更改列表。所以这是我从while循环开始的新想法,我想知道的是:这是在这种情况下避免重复的最佳方法吗?如果不是,请向我解释我应该怎么做?

** 代码 **

    ArrayList<CallQueue> queues = new ArrayList<>();
    while (query.next()) {

        boolean isNew = true;
        if (!queues.isEmpty()) {
            for (CallQueue callQueue : queues) {
                if (callQueue.getType().equals(query.getString("NAME"))) {
                    double decimalTime = query.getDouble("DATE");
                    int hourOfDay = (int)Math.round(24 * decimalTime);
                    int callAmount = query.getInteger("NoC");
                    if (hourOfDay > 19) {
                        hourOfDay = 19;
                    }

                    callQueue.addCallsByTime(hourOfDay, callAmount);
                    isNew = false;
                }else {
                    isNew = true;
                }
            } 

            /* Out side the foreach loop, checks if the boolean isNew is true if it is create a new object and insert into the list*/
            if (isNew) {
                String queueName = query.getString("NAME");
                if (!queueName.equalsIgnoreCase("PrivatOverflow")) {
                    CallQueue cq = new CallQueue(query.getString("NAME"));
                    double decimalTime = query.getDouble("DATE");
                    int hourOfDay = (int)Math.round(24 * decimalTime); 
                    int callAmount = query.getInteger("NoC");
                    if (hourOfDay > 19) {
                        hourOfDay = 19;
                    }
                    cq.addCallsByTime(hourOfDay, callAmount);
                    queues.add(cq);
                }
            }
            /* if queues is empty which it will be the first time*/
        }else {
            String queueName = query.getString("NAME");
            if (!queueName.equalsIgnoreCase("PrivatOverflow")) {
                CallQueue cq = new CallQueue(query.getString("NAME"));
                double decimalTime = query.getDouble("DATE");
                int hourOfDay = (int)Math.round(24 * decimalTime); 
                int callAmount = query.getInteger("NoC");
                if (hourOfDay > 19) {
                    hourOfDay = 19;
                }
                cq.addCallsByTime(hourOfDay, callAmount);
                queues.add(cq);

            }

        }
    }
4

2 回答 2

2

解释

不要做queues一个ArrayList,做一个HashSet或其他类型的Set这将在O(1)而不是O(n)时间内为您捕获重复项。完成加载查询后,您始终可以将数据从 中取出HashSet并将其放入以ArrayList供将来使用(这还有一个额外的好处是您将确切知道制作 . 的ArrayList时间。这将是一个O(n )复制,但您只需要执行一次,而不是像其他方式那样每次都执行。

要正确执行此操作,您可能必须覆盖CallQueue.hashCode()and .equals(),但这很容易,只需返回字段的.hashCode()and.equals()方法String name

漏洞??

顺便说一句,我认为那query是 a java.sql.ResultSet,但ResultSet没有getInteger,它有getInt。你的代码编译了吗?

编码

这是代码,看看我的意思:

HashMap<String, CallQueue> queues = new HashMap<String, CallQueue>(); 

while (query.next()) {
  if (!queues.isEmpty()) {
    if (queues.containsKey(query.getString("NAME"))) {
      CallQueue oldQueue = queues.get(query.getString("NAME"));
      double decimalTime = query.getDouble("DATE");
      int hourOfDay = (int)Math.round(24 * decimalTime);
      int callAmount = query.getInt("NoC");
      if (hourOfDay > 19) {
        hourOfDay = 19;
      }

      oldQueue.addCallsByTime(hourOfDay, callAmount);
    } else {
      String queueName = query.getString("NAME");
      if (!queueName.equalsIgnoreCase("PrivatOverflow")) {
        CallQueue cq = new CallQueue(query.getString("NAME"));
        double decimalTime = query.getDouble("DATE");
        int hourOfDay = (int)Math.round(24 * decimalTime); 
        int callAmount = query.getInt("NoC");
        if (hourOfDay > 19) {
          hourOfDay = 19;
        }
        cq.addCallsByTime(hourOfDay, callAmount);
        queues.put(query.getString("NAME"), cq);
      }
    }
  }
}

// you could return this if you just want a collection...
Collection<CallQueue> values = queues.values();

// Or this if you MUST have an ArrayList...
return new ArrayList(values);
于 2012-11-28T23:14:19.790 回答
1

您也可以在 sql 中使用 group by name 或 select distinct 来执行此操作。

于 2012-11-28T23:16:08.290 回答