Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I count how often an element from an ArrayList occurs in the another ArrayList?

I want to count how often an element from ArrayList "list1" occurs in the other ArrayList "list2".

I want this output:

A 2
B 0
C 1
D 2

I get this output:

A 0
B 0
C 0
D 69

Coud you please help me to do this? Thank you!

enter code here

    HashMap<Character, Integer> map = new HashMap<Character, Integer>();
    ArrayList<Character> list1 = new ArrayList<Character>();
    ArrayList<Character> list2 = new ArrayList<Character>();

    Collections.addAll(list1, 'A', 'B', 'C', 'D');
    Collections.addAll(list2, 'D', 'A', 'C', 'A', 'D');

    for (int i = 0; i < list1.size(); i++) {

        for (int j = 0; j < list2.size(); j++) {
            

            if (list1.get(i) == list2.get(j)) {
                map.put(list1.get(i), 1);
            } 
            
            if (list1.get(i) == list2.get(j) && (map.containsKey(list1.get(i)))) {
                map.replace(list1.get(i), list1.get(i) + 1);
            } 
            
            if (list1.get(i) != list2.get(j)) {
                map.put(list1.get(i), 0);
            }
            
        } 
    }

    
    System.out.println("Map: ");
    for (Map.Entry<Character, Integer> entry : map.entrySet()) {
        System.out.println(entry.getKey() + " " + entry.getValue());
    }
like image 589
alvira Avatar asked Nov 21 '20 10:11

alvira


1 Answers

Use the method frequency, from Collection, namely:

    for (Character c : list1)
       map.put(c, Collections.frequency(list2, c));

    System.out.println("Map: ");
    for (Map.Entry<Character, Integer> entry : map.entrySet()) {
        System.out.println(entry.getKey() + " " + entry.getValue());
    }

If you are a fan of one liners :

    list1.forEach(c -> map.put(c, Collections.frequency(list2, c)));

Including the printing of the elements:

list1.forEach(c ->  System.out.printf("%s %d%n", c, Collections.frequency(list2, c)));

By the way, your original answer was almost correct, you just had to rethink a bite the conditionals, and their order:

 for (Character c1 : list1) {
    for (Character c2 : list2) {
        if(map.containsKey(c1) && c1 == c2 ){
           map.put(c1, map.get(c1) + 1);
        }
        else if (!map.containsKey(c1) && c1 != c2 ) {
            map.put(c1, 0);
        } 
        else if (!map.containsKey(c1) && c1 == c2) {
            map.put(c1, 1);
        } 
    } 
}

Another advice is, if you do not explicitly need the loop index, it is better to use the idiom for (Character c1 : list1) rather than for(int i = 0; i < list1.size(); i++). The first is cleaner, and less error-prone than the second version. Moreover, you can use the variable c1 instead of having to do list1.get(i) all the time.

like image 148
dreamcrash Avatar answered Nov 02 '22 22:11

dreamcrash