java—如何计算一个arraylist中的元素在另一个arraylist中出现的频率?

mzmfm0qo  于 2021-07-11  发布在  Java
关注(0)|答案(3)|浏览(276)

我想计算arraylist“list1”中的元素在另一个arraylist“list2”中出现的频率。
我想要这个输出:

A 2
B 0
C 1
D 2

我得到这个输出:

A 0
B 0
C 0
D 69

你能帮我做这个吗?谢谢您!

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());
    }
pobjuy32

pobjuy321#

使用方法 frequency ,即:

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());
    }

如果你是单行道的粉丝:

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

包括元素的打印:

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

顺便说一句,你最初的回答几乎是正确的,你只需要重新考虑一下条件,以及它们的顺序:

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);
        } 
    } 
}

另一个建议是,如果不需要显式地使用循环索引,那么最好使用习惯用法 for (Character c1 : list1) 而不是 for(int i = 0; i < list1.size(); i++) . 第一个版本比第二个版本更干净,更不容易出错。此外,还可以使用变量 c1 而不是 list1.get(i) 总是。

jei2mxaa

jei2mxaa2#

您可以使用Java8中引入的流api来完成此任务。下面是解决问题的示例代码:

final List<Character> list1 = new ArrayList<Character>();
        final List<Character> list2 = new ArrayList<Character>();

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

        final Map<Character, Integer> map = new HashMap<>();
        for (final Character c : list1) {
            final int occurrences = (int) list2.stream().filter(c::equals).count();
            map.put(c, occurrences);
        }

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

注意:对于这组问题,我建议您从编写一些单元测试开始实现。

cs7cruho

cs7cruho3#

没有额外循环的更干净的java 8解决方案是:

List<Character> list1 = Arrays.asList('A', 'B', 'C', 'D');
List<Character> list2 = Arrays.asList('D', 'A', 'C', 'A', 'D');

Map<Character, Integer> map = list1.stream()
                                   .collect(Collectors.toMap(
                                       c -> c, 
                                       c -> Collections.frequency(list2, c)
                                   ));

// print entire map
System.out.println(map);

// print formatted map
map.entrySet().forEach(e -> System.out.printf("%s %d%n", e.getKey(), e.getValue()));

如果特定任务是打印频率,则可以完全跳过中间Map:)

list1.stream()
     .map(c -> new StringBuilder()
                       .append(c).append(' ')
                       .append(Collections.frequency(list2, c))
     )
     .forEach(System.out::println);

相关问题