gpt4 book ai didi

java - 正确的循环方式以避免创建双对象

转载 作者:行者123 更新时间:2023-12-02 00:07:05 28 4
gpt4 key购买 nike

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

在我上一个问题中,我询问了一个执行问题,其中一个答复让我重新思考循环的想法链接到旧问题: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);

}

}
}

最佳答案

说明

不要将队列设为ArrayList,而将其设为HashSet或某种其他类型的Set。这将在 O(1) 时间内为您捕获重复项,而不是 O(n)。加载完查询后,您始终可以从 HashSet 中取出数据并将其放入 ArrayList 中以供将来使用(这还有一个额外的优点:将确切地知道创建 ArrayList 需要多长时间。这将是一个 O(n) 副本,但您只需要做一次,而不是像下面那样每次都做其他方式。

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

错误??

顺便说一句,我假设query是一个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);

关于java - 正确的循环方式以避免创建双对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13616076/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com