Java Collections.frequency 方法
上次修改时间:2025 年 4 月 20 日
Collections.frequency
方法是 Java Collections 框架提供的一个实用方法。它用于计算给定集合中特定元素出现的次数。此方法是 java.util.Collections
类的一部分,它简化了诸如统计数据结构中出现的次数之类的任务。
该方法的签名是 public static int frequency(Collection<?> c, Object o)
。它接受两个参数:一个集合和一个要搜索的对象。集合可以是任何实现 Collection
接口的类型,例如 List
、Set
或 Queue
。该方法返回一个整数,表示集合中指定对象的总出现次数。如果集合为空或未找到指定的元素,则返回 0
。
Collections.frequency 的基本用法
此示例演示了 Collections.frequency
的最简单用法。我们创建一个字符串列表,并计算特定字符串出现了多少次。该方法适用于任何 Collection 实现。
package com.zetcode; import java.util.Collections; import java.util.List; public class BasicFrequencyExample { public static void main(String[] args) { List<String> colors = List.of("Red", "Green", "Blue", "Red", "Yellow"); int redCount = Collections.frequency(colors, "Red"); int blueCount = Collections.frequency(colors, "Blue"); int blackCount = Collections.frequency(colors, "Black"); System.out.println("Red appears " + redCount + " times"); System.out.println("Blue appears " + blueCount + " times"); System.out.println("Black appears " + blackCount + " times"); } }
此代码创建了一个颜色列表,其中包含一些重复项。然后,我们使用 Collections.frequency
计算“Red”、“Blue”和“Black”的出现次数。该方法返回“Red”为 2,“Blue”为 1,“Black”为 0。
该示例表明该方法正确地计算了现有元素,并为集合中不存在的元素返回 0。它区分大小写,并使用 equals() 进行比较。
计数自定义对象
此示例演示了将 Collections.frequency
与自定义对象一起使用。为了使该方法正常工作,这些对象必须正确实现 equals
方法。我们将创建一个简单的 Person 记录并计算出现的次数。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; record Person(String name, int age) {} public class CustomObjectFrequency { public static void main(String[] args) { List<Person> people = new ArrayList<>(); people.add(new Person("Alice", 25)); people.add(new Person("Bob", 30)); people.add(new Person("Alice", 25)); people.add(new Person("Charlie", 35)); people.add(new Person("Alice", 30)); Person alice25 = new Person("Alice", 25); Person alice30 = new Person("Alice", 30); Person dave40 = new Person("Dave", 40); System.out.println("Alice (25) appears " + Collections.frequency(people, alice25) + " times"); System.out.println("Alice (30) appears " + Collections.frequency(people, alice30) + " times"); System.out.println("Dave (40) appears " + Collections.frequency(people, dave40) + " times"); } }
此示例演示了如何使用记录来计算集合中自定义对象的数量。Person
记录根据其组件(例如,姓名和年龄)自动实现 equals
、hashCode
和 toString
方法。这消除了手动实现 equals
的需要,确保了 Collections.frequency
的正常功能。
我们定义了几个 Person
记录并计算特定实例的出现次数。输出显示了相同的记录(相同的姓名和年龄)被正确计数,而未匹配的记录返回 0。由于 equals
方法由记录生成,因此它在确定对象相等性方面起着至关重要的作用。
不同集合类型的频率
Collections.frequency
方法适用于任何 Collection 实现。此示例演示了它与 ArrayList、HashSet 和 LinkedList 的使用。在不同的集合类型中,行为保持一致。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; public class DifferentCollectionTypes { public static void main(String[] args) { // ArrayList example List<Integer> arrayList = new ArrayList<>(); Collections.addAll(arrayList, 1, 2, 3, 2, 4, 2, 5); System.out.println("ArrayList count of 2: " + Collections.frequency(arrayList, 2)); // HashSet example (no duplicates) Set<Integer> hashSet = new HashSet<>(arrayList); System.out.println("HashSet count of 2: " + Collections.frequency(hashSet, 2)); // LinkedList example List<Integer> linkedList = new LinkedList<>(); Collections.addAll(linkedList, 1, 1, 1, 2, 3); System.out.println("LinkedList count of 1: " + Collections.frequency(linkedList, 1)); } }
此示例显示了 Collections.frequency
与不同集合类型的配合使用。我们使用一个包含重复项的 ArrayList、一个 HashSet(它消除了重复项)和一个 LinkedList。该方法在所有实现中表现一致。
ArrayList 显示包含重复项的计数(值 2 为 3)。HashSet 无法包含重复项,显示为 0 或 1。LinkedList 演示了在另一个 List 实现中进行计数。
带有 Null 值的频率
此示例探讨了 Collections.frequency
如何处理集合中的 null 值。如果集合包含 null 值,则该方法可以计算 null 出现的次数。我们将通过不同的场景演示此行为。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class NullFrequencyExample { public static void main(String[] args) { List<String> words = new ArrayList<>(); words.add("apple"); words.add(null); words.add("banana"); words.add(null); words.add(null); words.add("cherry"); System.out.println("Null appears " + Collections.frequency(words, null) + " times"); System.out.println("\"apple\" appears " + Collections.frequency(words, "apple") + " times"); List<String> noNulls = new ArrayList<>(); noNulls.add("one"); noNulls.add("two"); System.out.println("In noNulls, null appears " + Collections.frequency(noNulls, null) + " times"); } }
此示例演示了 Collections.frequency
如何处理 null 值。我们创建一个包含几个 null 和一些字符串的列表。该方法正确地计算了 null 的出现次数(在本例中为 3)。
我们还表明,它在非 null 值下的工作方式正常,并且对于不包含 null 的集合中的 null 计数返回 0。该方法安全地处理集合中的 null 元素和作为搜索参数的 null。
性能注意事项
此示例检查 Collections.frequency
的性能特征。该方法执行线性搜索,使其具有 O(n) 复杂度。对于大型集合,这可能会影响性能。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class FrequencyPerformance { public static void main(String[] args) { // Create a large list List<Integer> numbers = new ArrayList<>(); for (int i = 0; i < 1_000_000; i++) { numbers.add(i % 100); // Numbers 0-99 repeated } long startTime = System.nanoTime(); int count = Collections.frequency(numbers, 50); long endTime = System.nanoTime(); System.out.println("Count of 50: " + count); System.out.println("Time taken: " + (endTime - startTime) / 1_000_000 + " ms"); // Compare with alternative approaches startTime = System.nanoTime(); long streamCount = numbers.stream().filter(n -> n == 50).count(); endTime = System.nanoTime(); System.out.println("\nStream count of 50: " + streamCount); System.out.println("Stream time taken: " + (endTime - startTime) / 1_000_000 + " ms"); } }
此示例创建了一个大型列表并测量了计算出现次数所花费的时间。我们将 Collections.frequency
与 Java 8 流方法进行比较。这两种方法都具有相似的 O(n) 性能特征。
输出显示,对于大型集合,计数可能需要花费明显的时间。如果频率计数是一项频繁的操作,请考虑使用备用数据结构,例如多重集或维护单独的计数器。
具有多维集合的频率
此示例演示了如何将 Collections.frequency
与嵌套集合一起使用。该方法仅在顶层进行计数 - 它不会递归地搜索嵌套集合。我们将展示如何处理此类情况。
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class NestedCollectionsFrequency { public static void main(String[] args) { // Declare matrix with generic type List<List<Integer> matrix = new ArrayList<>(); matrix.add(List.of(1, 2, 3)); matrix.add(List.of(4, 5, 6)); matrix.add(List.of(1, 2, 3)); matrix.add(List.of(7, 8, 9)); // Declare searchList explicitly List<Integer> searchList = List.of(1, 2, 3); // Use Collections.frequency to count occurrences of searchList in the matrix System.out.println("Outer list count: " + Collections.frequency(matrix, searchList)); // To count all occurrences of a specific number in nested lists long totalCount = matrix.stream() .flatMap(List::stream) .filter(n -> n == 2) // Replace "2" with any number to search for .count(); System.out.println("Total count of 2 in all lists: " + totalCount); } }
此示例演示了 Collections.frequency
如何对嵌套集合进行操作。该方法计算外部集合中完整内部列表的出现次数。例如,在这种情况下,它标识了内部列表 [1, 2, 3]
的两次出现。但是,它不考虑内部列表本身的单个元素。
要在嵌套集合中搜索并计算所有内部列表中各个元素的数量,我们使用基于流的替代方法。通过使用 flatMap
展平嵌套结构,我们可以处理和过滤所有子列表中的元素。对于需要在深度嵌套数据中对搜索和计数进行细粒度控制的场景,此方法至关重要。
真实示例:词频计数器
此示例展示了 Collections.frequency
的一个实际应用 - 一个简单的词频计数器。我们将读取文本,将其拆分为单词,并计算特定单词的出现次数。
package com.zetcode; import java.util.Collections; import java.util.Comparator; import java.util.List; public class WordFrequencyCounter { public static void main(String[] args) { String text = """ The quick brown fox jumps over the lazy dog. The quick fox is very quick indeed. The dog is not quick."""; // Normalize and split into words String[] words = text.toLowerCase().split("\\W+"); List<String> wordList = List.of(words); // Count specific words System.out.println("Word frequencies:"); System.out.println("the: " + Collections.frequency(wordList, "the")); System.out.println("quick: " + Collections.frequency(wordList, "quick")); System.out.println("fox: " + Collections.frequency(wordList, "fox")); System.out.println("dog: " + Collections.frequency(wordList, "dog")); System.out.println("lazy: " + Collections.frequency(wordList, "lazy")); // Find most frequent word String mostFrequent = wordList.stream() .distinct() .max(Comparator.comparingInt(a -> Collections.frequency(wordList, a))) .orElse(""); System.out.println("\nMost frequent word: " + mostFrequent + " (" + Collections.frequency(wordList, mostFrequent) + " times)"); } }
此示例演示了 Collections.frequency
在文本分析中的实际应用。我们将文本字符串处理成单词,然后计算特定单词的出现次数。该示例还显示了查找最常用的单词。
代码首先规范化文本(转换为小写)并将其拆分为单词。然后,我们使用 frequency
计算特定单词并将其与流结合起来查找最常用的单词。这表明 frequency
可以成为更复杂文本处理的一部分。
来源
在本教程中,我们深入探讨了 Java Collections.frequency
方法。我们涵盖了基本用法、计数自定义对象、不同的集合类型、处理 null 值、性能注意事项、嵌套集合以及一个实用的词频计数器应用程序。此方法对于有效地计算任何集合类型中的元素出现次数非常有用。
作者
列出所有Java教程。