我正在使用Java邮件API从多个Gmail帐户接收邮件。不同的帐户正在处理不同的帐户,我使用LinkedBlockingQueue
来存储电子邮件。但是,我不希望将同一封电子邮件重复添加到Queue
。
这是我到目前为止的代码:
public synchronized void readMail(){
try {
boolean alreadyAdded = false;
Folder inbox = store.getFolder("Inbox");
inbox.open(Folder.READ_ONLY);
Message [] received = inbox.getMessages();
if(messages.isEmpty()){
for(Message newMessage:received){
System.out.println("Queue empty, adding messages");
messages.put(newMessage);
}
}
else{
for(Message existingMessage:messages){
for(Message newMessage:received){
if (alreadyAdded == true)
break;
else{
if(existingMessage.getSubject().equals(newMessage.getSubject())){
alreadyAdded = true;
System.out.println("boolean changed to true, message "+newMessage.getSubject()+"won't be added");
}
else{
alreadyAdded = false;
System.out.println("Non-duplicate message "+newMessage.getSubject());
messages.put(newMessage);
}
}
}
}
}
}
catch (MessagingException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
我遇到的问题是在else
块后if
阻止队列是否为空。我希望它检查刚刚读入的消息集,并将它们与Queue
中已有的消息进行比较。如果消息在Queue
中,请不要再次添加。我不能简单地使用.contains()
,因为每次下载消息时,它们都被赋予不同的内存位置,因此尽管Message
对象实际上可能是相同的(例如具有相同的主题,内容等)它不会有相同的签名(例如,第一次下载时它可能是Messagehgshsh676767
,但下次可能是Messageyyetwt8965
)。
我撞到了一堵砖墙,有人可以建议一种方法来确保没有添加重复项吗?
答案 0 :(得分:1)
您可以为邮件创建一个包装类,其中包含一个正确的equals方法,基于例如受试者
public class MyMessage {
final private Message msg;
public MyMessage (final Message msg) {
this.msg = msg;
}
public boolean equals (final Object other) {
if (!(other instanceof MyMessage)) {
return false;
}
final MyMessage otherMessage = (MyMessage) other;
return msg.getSubject ().equals (otherMessage.getSubject ());
}
public Message getMessage () {
return msg;
}
}
如果您不关心订单,可以使用一些线程安全的Set实现
final Set<MyMessage> messages = Collections.synchronizedSet (new HashSet<MyMessage> ());
Message [] received = inbox.getMessages();
for (final Message msg : reveived) {
messages.add (msg);
}
这样你就不会有重复。
如果您关心订单,请使用一些SortedSet,例如:
public class MyMessage implements Comparable<MyMessage> {
... //the same as above
public int compareTo (final MyMessage otherMessage) {
return msg.getReceivedDate ().compareTo (otherMessage.getReceivedDate ());
}
}
final Set<MyMessage> messages = Collections.synchronizedSet (new TreeSet<MyMessage> ());
答案 1 :(得分:-1)
if(!queue.contains(element)) {
queue.add(element);
}
如果你想要一个Set,你可以扩展LinkedBlockingQueue并覆盖add:
public boolean add(E e)
if(!this.contains(e)) {
return super.add(e);
} else {
return false;
}
}
但是你应该制作它并使用它或者正确地覆盖它 - 所有可以向它添加元素的方法和构造函数。
关于包含问题,请在收到的Message上创建一个包装器并正确实现public boolean equals(Object o)
方法。当您收到消息时,将其放入此包装器中并将此包装器放入集合中。