Skip to content

Instantly share code, notes, and snippets.

@sofusalbertsen
Created September 20, 2014 09:08
Show Gist options
  • Save sofusalbertsen/7cf4bf4cac0328dedab3 to your computer and use it in GitHub Desktop.
Save sofusalbertsen/7cf4bf4cac0328dedab3 to your computer and use it in GitHub Desktop.
//I need to identify if i have send and email or not within a subject-keyed hashmap containing arraylist of Email messages
private ConcurrentHashMap<String, ArrayList<Message>> cleanOneWayCOnversations(
ConcurrentHashMap<String, ArrayList<Message>> conversations2) {
conversations2.forEach((k,v)->{
//every conversation
boolean meSender,meReciever;
meSender=false;
meReciever=false;
//Every mail
v.forEach((m)->{
try {
List<Address>tmp =Arrays.asList(m.getFrom());
for(Address from:tmp) //Here i get the "local variable meSender defined in an enclosing scope must be final or effectively final" error
meSender=from.toString().equalsIgnoreCase(account);
} catch (Exception e) { }
});
});
return null;
}
@Jegp
Copy link

Jegp commented Sep 20, 2014

What about something like:

boolean didISendThis = conversations2.values().stream().reduce(false, (Boolean meSender, Message message) -> {
    return meSender || 
           Arrays.asList(message.getFrom()).stream()
                 .filter(address -> address.toString().equalsIgnoreCase(account)).findFirst().isPresent();
}

I haven't compiled it, so I don't know if it'll work. But the idea is that we store a meSender boolean that is initialised to false. For each message, we look through the from addresses, and filter away any from-addresses that does not equal the account string. We only take the first element because we're just interested in the boolean. This gives us an Optional<Boolean> type, and the isPresent() method only returns true -- tadaaa -- if the value is present (that is, any element equals the account). The result is returned to the reduce method. Any subsequent results will be returned immediately if previous call was true, thus eliminating any unnecessary iterations.

@sofusalbertsen
Copy link
Author

I need to remove the conversations (arraylist) from the hashmap that doesn't have me in it.
Right now i only know whether the total hashmap has me or not as i understand your code.
And i get the following vommit from eclipse: http://i.imgur.com/vhTUy3k.png

@Jegp
Copy link

Jegp commented Sep 20, 2014

Ahaa. Then it's just a matter of turning the reduce method into filter and filter out any message that doesn't return true in check for the from-address. So maybe this is closer:

List<Message> conversationsWithSofus = conversations2.values().stream().filter((Message message) -> {
    return Arrays.asList(message.getFrom()).stream()
                 .filter(address -> address.toString().equalsIgnoreCase(account)).findFirst().isPresent();
}

.. If not let me know. I'll try it in an editor

@sofusalbertsen
Copy link
Author

Tried like this, but list returns 0 which i know is not the real resault:

public ConcurrentHashMap<String, ArrayList<Message>> cleanConversations() {

        conversations.forEach((k, v) -> {
            if (v.size() < 2) {
                conversations.remove(k);
                // System.out.println("removed from conversations:" + k);
            }
        });
         conversations= cleanOneWayCOnversations(conversations);
        return conversations;
    }

    private ConcurrentHashMap<String, ArrayList<Message>> cleanOneWayCOnversations(
            ConcurrentHashMap<String, ArrayList<Message>> conversations2) {
        System.out.println(conversations2.size());
        Stream<ArrayList<Message>> trueConversations = conversations2
                .values()
                .stream()
                .filter(m -> {
                    return m.stream()
                            .filter(address -> address.toString()
                                    .equalsIgnoreCase(account)).findFirst()
                            .isPresent();
                });
System.out.println(trueConversations.count());
System.out.println(conversations2.size());
return conversations2;
    }

@Jegp
Copy link

Jegp commented Sep 20, 2014

Solution:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Test {

    static class Message {

        List<String> getFrom() {
            List<String> list = new ArrayList<String>();
            list.add("sofus@itu.dk");
            return list;
        }

    }
    static String account = "sofus@itu.dk";

    private static Map<String, ArrayList<Message>> cleanOneWayCOnversations(
            Map<String, ArrayList<Message>> conversations2) {
        System.out.println(conversations2.size());
        Map<String, ArrayList<Message>> trueConversations = conversations2
                .entrySet().stream()
                .filter(keySet -> {
                    ArrayList<Message> messageList = keySet.getValue();
                    return messageList.stream()
                        .filter(message -> {
                            return message.getFrom().stream().filter(address -> {
                                    return address.toString().equalsIgnoreCase(account);
                            }).findFirst().isPresent();
                        }).findFirst().isPresent();
                }).collect(Collectors.toMap(set -> set.getKey(), set -> set.getValue()));

        System.out.println(trueConversations.size());
        return conversations2;
    }

    public static void main(String[] args) {
        Map<String, ArrayList<Message>> m = new HashMap<String, ArrayList<Message>>();
        ArrayList<Message> a = new ArrayList<>();
        a.add(new Message());
        m.put("test", a);
        System.out.println(cleanOneWayCOnversations(m));
    }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment