Find the most common String in ArrayList() - java

Is there a way to find the most common String in an ArrayList?
ArrayList<String> list = new ArrayList<>();
list.add("test");
list.add("test");
list.add("hello");
list.add("test");
Should find the word "test" from this list ["test","test","hello","test"]

Don't reinvent the wheel and use the frequency method of the Collections class:
public static int frequency(Collection<?> c, Object o)
Returns the number of elements in the specified collection equal to
the specified object. More formally, returns the number of elements e
in the collection such that (o == null ? e == null : o.equals(e)).
If you need to count the occurrences for all elements, use a Map and loop cleverly :)
Or put your list in a Set and loop on each element of the set with the frequency method above. HTH
EDIT / Java 8: If you fancy a more functional, Java 8 one-liner solution with lambdas, try:
Map<String, Long> occurrences =
list.stream().collect(Collectors.groupingBy(w -> w, Collectors.counting()));

In statistics, this is called the "mode". A vanilla Java 8 solution looks like this:
Stream.of("test","test","hello","test")
.collect(Collectors.groupingBy(s -> s, Collectors.counting()))
.entrySet()
.stream()
.max(Comparator.comparing(Entry::getValue))
.ifPresent(System.out::println);
Which yields:
test=3
jOOλ is a library that supports mode() on streams. The following program:
System.out.println(
Seq.of("test","test","hello","test")
.mode()
);
Yields:
Optional[test]
(disclaimer: I work for the company behind jOOλ)

As per question, Specifically just to get word, not the number of times (i.e. value of key).
String mostRepeatedWord
= list.stream()
.collect(Collectors.groupingBy(w -> w, Collectors.counting()))
.entrySet()
.stream()
.max(Comparator.comparing(Entry::getValue))
.get()
.getKey();

You can make a HashMap<String,Integer>. If the String already appears in the map, increment its key by one, otherwise, add it to the map.
For example:
put("someValue", 1);
Then, assume it's "someValue" again, you can do:
put("someValue", get("someValue") + 1);
Since the key of "someValue" is 1, now when you put it, the key will be 2.
After that you can easily go through the map and extract the key that has the highest value.
I didn't write a full solution, try to construct one, if you have problems post it in another question. Best practice is to learn by yourself.

I think the best way to do it is using maps containing counts.
Map<String, Integer> stringsCount = new HashMap<>();
And iterate over your array filling this map:
for(String s: list)
{
Integer c = stringsCount.get(s);
if(c == null) c = new Integer(0);
c++;
stringsCount.put(s,c);
}
Finally, you can get the most repeated element iterating over the map:
Map.Entry<String,Integer> mostRepeated = null;
for(Map.Entry<String, Integer> e: stringsCount.entrySet())
{
if(mostRepeated == null || mostRepeated.getValue()<e.getValue())
mostRepeated = e;
}
And show the most common string:
if(mostRepeated != null)
System.out.println("Most common string: " + mostRepeated.getKey());

You could use a HashMap<String,Integer>. Looping through the array, you can check for each String if it is not already a Key of your HashMap, add it and set the value to 1, if it is, increase its value by 1.
Then you have a HashMap with all unique Strings and an associated number stating their amount in the array.

If somebody need to find most popular from usual String[] array (using Lists):
public String findPopular (String[] array) {
List<String> list = Arrays.asList(array);
Map<String, Integer> stringsCount = new HashMap<String, Integer>();
for(String string: list)
{
if (string.length() > 0) {
string = string.toLowerCase();
Integer count = stringsCount.get(string);
if(count == null) count = new Integer(0);
count++;
stringsCount.put(string,count);
}
}
Map.Entry<String,Integer> mostRepeated = null;
for(Map.Entry<String, Integer> e: stringsCount.entrySet())
{
if(mostRepeated == null || mostRepeated.getValue()<e.getValue())
mostRepeated = e;
}
try {
return mostRepeated.getKey();
} catch (NullPointerException e) {
System.out.println("Cannot find most popular value at the List. Maybe all strings are empty");
return "";
}
}
case non-sensitive

i know this takes more time to implement but you can use heap data structure by storing in the nodes the count and the string information

You can use Guava's Multiset:
ArrayList<String> names = ...
// count names
HashMultiset<String> namesCounts = HashMultiset.create(names);
Set<Multiset.Entry<String>> namesAndCounts = namesCounts.entrySet();
// find one most common
Multiset.Entry<String> maxNameByCount = Collections.max(namesAndCounts, Comparator.comparing(Multiset.Entry::getCount));
// pick all with the same number of occurrences
List<String> mostCommonNames = new ArrayList<>();
for (Multiset.Entry<String> nameAndCount : namesAndCounts) {
if (nameAndCount.getCount() == maxNameByCount.getCount()) {
mostCommonNames.add(nameAndCount.getElement());
}
}

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class StringChecker {
public static void main(String[] args) {
ArrayList<String> string;
string = new ArrayList<>(Arrays.asList("Mah", "Bob", "mah", "bat", "MAh", "BOb"));
Map<String, Integer> wordMap = new HashMap<String, Integer>();
for (String st : string) {
String input = st.toUpperCase();
if (wordMap.get(input) != null) {
Integer count = wordMap.get(input) + 1;
wordMap.put(input, count);
} else {
wordMap.put(input, 1);
}
}
System.out.println(wordMap);
Object maxEntry = Collections.max(wordMap.entrySet(), Map.Entry.comparingByValue()).getKey();
System.out.println("maxEntry = " + maxEntry);
}

With this method, if there is more than one most common elements in your ArrayList, you get back all of them by adding them to a new ArrayList.
public static void main(String[] args) {
List <String> words = new ArrayList<>() ;
words.add("cat") ;
words.add("dog") ;
words.add("egg") ;
words.add("chair") ;
words.add("chair") ;
words.add("chair") ;
words.add("dog") ;
words.add("dog") ;
Map<String,Integer> count = new HashMap<>() ;
for (String word : words) { /* Counts the quantity of each
element */
if (! count.containsKey(word)) {
count.put(word, 1 ) ;
}
else {
int value = count.get(word) ;
value++ ;
count.put(word, value) ;
}
}
List <String> mostCommons = new ArrayList<>() ; /* Max elements */
for ( Map.Entry<String,Integer> e : count.entrySet() ) {
if (e.getValue() == Collections.max(count.values() )){
/* The max value of count */
mostCommons.add(e.getKey()) ;
}
}
System.out.println(mostCommons);
}
}

There are a lot of answers suggesting HashMaps. I really don't like them, because you have to iterate through them once again anyway. Rather, I would sort the List
Collections.sort(list);
and then loop through it. Something similar to
String prev = null, mostCommon=null;
int num = 0, max = 0;
for (String str:list) {
if (str.equals(prev)) {
num++;
} else {
if (num>max) {
max = num;
mostCommon = str;
}
num = 1;
prev = str;
}
}
should do it.

Related

How can I get the count of most duplicated value in a list after sorting it alphabetically?

What is the easiest way to get the most duplicated value in a list and sorted in descending order...
for example:
List<String> list = new ArrayList<>(List.of("Renault","BMW","Renault","Renault","Toyota","Rexon","BMW","Opel","Rexon","Rexon"));
`
"renault" & "rexon" are most duplicated and if sorted in descending order alphabetically I would like to get the rexon.
I think one of the most readable and elegant way would be to use the Streams API
strings.stream()
.collect(Collectors.groupingBy(x -> x, Collectors.counting()))
.entrySet().stream()
.max(Comparator.comparingLong((ToLongFunction<Map.Entry<String, Long>>) Map.Entry::getValue).thenComparing(Map.Entry::getKey))
.map(Map.Entry::getKey)
.ifPresent(System.out::println);
Create a map of names with their corresponding number of occurrences.
Get names and sort them in descending order.
Print the first name that has the highest number of occurrences.
class Scratch {
public static void main(String[] args) {
List<String> list = List.of("Renault","BMW","Renault","Renault","Toyota","Rexon","BMW","Opel","Rexon","Rexon");
Map<String, Integer> duplicates = new HashMap<>();
// 1. Create a map of names with their corresponding
// number of occurrences.
for (String s: list) {
duplicates.merge(s, 1, Integer::sum);
}
// 2. Get names and sort them in descending order.
List<String> newList = new ArrayList<String>(duplicates.keySet());
newList.sort(Collections.reverseOrder());
// 3. Print the first name that has the highest number of
// occurrences.
Integer max = Collections.max(duplicates.values());
newList.stream().filter(name -> duplicates.get(name).equals(max))
.findFirst()
.ifPresent(System.out::println);
}
}
After some time this is what I came with (I only tested it with your example and it worked):
public class Duplicated {
public static String MostDuplicated(String[] a) {
int dup = 0;
int position = -1;
int maxDup = 0;
for(int i = 0; i < a.length; i++) { //for every position
for(int j = 0; j < a.length; j++){ //compare it to all
if(a[i].equals(a[j])) { dup++; } // and count how many time is duplicated
}
if (dup > maxDup) { maxDup = dup; position = i;}
//if the number of duplications
//is greater than the maximum you have got so far, save this position.
else if (dup == maxDup) {
if( a[i].compareTo(a[position]) > 0 ){ position = i; }
//if its the same, keep the position of the alphabetical last
// (if u want the alphabetical first, just change the "<" to ">")
}
}
return a[position]; //return the position you saved
}
}
You are asking to sort the list and then find the most common item.
I would suggest that the easiest way to sort the list is using the sort method that is built into list.
I would then suggest finding the most common by looping with the for..each construct, keeping track of the current and longest streaks.
I like Yassin Hajaj's answer with streams but I find this way easier to write and easier to read. Your mileage may vary, as this is subjective. :)
import java.util.*;
public class SortingAndMostCommonDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>(List.of("Renault","BMW","Renault","Renault","Toyota","Rexon","BMW","Opel","Rexon","Rexon"));
list.sort(Comparator.reverseOrder());
System.out.println(list);
System.out.println("The most common is " + mostCommon(list) + ".");
}
private static String mostCommon(List<String> list) {
String mostCommon = null;
int longestStreak = 0;
String previous = null;
int currentStreak = 0;
for (String s : list) {
currentStreak = 1 + (s.equals(previous) ? currentStreak : 0);
if (currentStreak > longestStreak) {
mostCommon = s;
longestStreak = currentStreak;
}
previous = s;
}
return mostCommon;
}
}
The fast algorithm takes advantage of the fact that the list is sorted and finds the list with the most duplicates in O(n), with n being the size of the list. Since the list is sorted the duplicates will be together in consecutive positions:
private static String getMostDuplicates(List<String> list) {
if(!list.isEmpty()) {
list.sort(Comparator.reverseOrder());
String prev = list.get(0);
String found_max = prev;
int max_dup = 1;
int curr_max_dup = 0;
for (String s : list) {
if (!s.equals(prev)) {
if (curr_max_dup > max_dup) {
max_dup = curr_max_dup;
found_max = prev;
}
curr_max_dup = 0;
}
curr_max_dup++;
prev = s;
}
return found_max;
}
return "";
}
Explanation:
We iterate through the list and keep track of the maximum of duplicates found so far and the previous element. If the current element is the same as the previous one we increment the number of duplicates found so far. Otherwise, we check if the number of duplicates is the bigger than the previous maximum of duplicates found. If it is we update accordingly
A complete running example:
public class Duplicates {
private static String getMostDuplicates(List<String> list) {
if(!list.isEmpty()) {
list.sort(Comparator.reverseOrder());
String prev = list.get(0);
String found_max = prev;
int max_dup = 1;
int curr_max_dup = 0;
for (String s : list) {
if (!s.equals(prev)) {
if (curr_max_dup > max_dup) {
max_dup = curr_max_dup;
found_max = prev;
}
curr_max_dup = 0;
}
curr_max_dup++;
prev = s;
}
return found_max;
}
return "";
}
public static void main(String[] args) {
List<String> list = new ArrayList<>(List.of("Renault","BMW","Renault","Renault","Toyota","Rexon","BMW","Opel","Rexon","Rexon"));
String duplicates = getMostDuplicates(list);
System.out.println("----- Test 1 -----");
System.out.println(duplicates);
list = new ArrayList<>(List.of("Renault","BMW"));
duplicates = getMostDuplicates(list);
System.out.println("----- Test 2 -----");
System.out.println(duplicates);
list = new ArrayList<>(List.of("Renault"));
duplicates = getMostDuplicates(list);
System.out.println("----- Test 3 -----");
System.out.println(duplicates);
}
}
Output:
----- Test 1 -----
Rexon
----- Test 2 -----
Renault
----- Test 3 -----
Renault
Actually, I found a solution which works:
public static void main(String[] args) {
List<String> list = new ArrayList<>(List.of("Renault", "BMW", "BMW", "Renault", "Renault", "Toyota",
"Rexon", "BMW", "Opel", "Rexon", "Rexon"));
Map<String, Integer> soldProducts = new HashMap<>();
for (String s : list) {
soldProducts.put(s, soldProducts.getOrDefault(s, 0) + 1);
}
LinkedHashMap<String, Integer> sortedMap = soldProducts.entrySet()
.stream()
.sorted(VALUE_COMPARATOR.thenComparing(KEY_COMPARATOR_REVERSED))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));
String result = "";
for (Map.Entry<String, Integer> s : sortedMap.entrySet()) {
result = s.getKey();
}
System.out.println(result);
}
static final Comparator<Map.Entry<String, Integer>> KEY_COMPARATOR_REVERSED =
Map.Entry.comparingByKey(Comparator.naturalOrder());
static final Comparator<Map.Entry<String, Integer>> VALUE_COMPARATOR =
Map.Entry.comparingByValue();

Find the how much unique values in a list of vectors - Java

I have to write a code to parse a list of sublist and return how much unique values I have in each subList, I have written this code:
public static Map<Integer,Set<String>> findAllFrequencies(List<List<String>> data){
// main key is the column index
Map<Integer,Set<String>> frequency = new HashMap<>();
for (Integer i = 0; i < data.size(); i++) {
List<String> line = data.get(i);
for (String cell : line) {
frequency.putIfAbsent(i, Sets.newHashSet(cell));
frequency.computeIfPresent(i, (k, v) -> {
v.add(cell);
return v;
});
}
}
return frequency;
}
Assuming My input is a File and not a List of List is there a better solution?
The idea is to get a File and parse each columns and find total unique values per column.
You have several ways to know if a String is unique in a list of Strings.
1) The lazy solution : use Streams and compute a Map of occurrences of each String :
Map<String, Long> occurrences = strings.stream()
.collect(Collectors.groupingBy(s -> s, Collectors.counting()));
Then, each entry which has a value of 1 is unique.
2) Compute the duplicates and remove all duplicates from the original list :
Set<String> alreadySeen = new HashSet<>();
Set<String> duplicates = new HashSet<>();
for (String s : strings) {
if(alreadySeen.contains(s)) {
duplicates.add(s);
}
alreadySeen.add(s);
}
List<String> result = new ArrayList<>(strings)
result.removeAll(duplicates);
3) If you don't want to create intermediate collections, sort the List. Each element which is different from its predecessor and successor is unique (the cleanest one imho) :
Set<String> uniques = new HashSet<>();
strings.sort(Comparator.naturalOrder());
for(int i = 0; i< strings.size(); i++) {
String predecessor = i > 0 ? strings.get(i - 1) : null;
String successor = i < strings.size() - 1 ? strings.get(i + 1) : null;
String current = strings.get(i);
if(!current.equals(predecessor) && !current.equals(successor)) {
uniques.add(current);
}
}

First Unique String in an String array

Given a String Array how would you find the first unique String element in the array
public static String UniqueString(String[] s) {
String str ="";
for(int i=0;i<s.length;i++) {
for(int j=i+1;j<s.length;j++) {
System.out.println(s[i]+" "+s[j]);
str = s[i];
if(str==s[j]) {
break;
}
}if(!(str==s[i+1])){
return str;
}
}
return str;
}
so a String array of {Dog,Cat,Dog,Wolf,lion} would return as Cat
Your approach grows quadratically with the size of the list. There's a better approach that is essentially linear in the list size, which is to use an ordered map from strings to the number of occurrences. Use one pass through the list to build the map and then one pass through the map to find the first element (if any) with a count of 1. You can use a LinkedHashMap to implement this.
public static String uniqueString(String[] list) {
Integer ZERO = 0; // to avoid repeated autoboxing below
final LinkedHashMap<String, Integer> map = new LinkedHashMap<>(list.size());
// build the map
for (String s : list) {
Integer count = map.getOrDefault(s, ZERO);
map.put(s, count + 1);
}
// find the first unique entry. Note that set order is deterministic here.
for (Set.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 1) {
return entry.getKey();
}
}
// if we get this far, there was no unique string in the list
return "";
}
Note that you could use any kind of Map implementation (including HashMap) and forgo the ordering property of LinkedHashMap by replacing the second loop with a loop through the original list:
for (String s : list) {
if (map.get(s) == 1) {
return s;
}
}
However, if the list has lots of repeated strings then iterating through the
map will probably require significantly fewer iterations. So might as well use the added functionality of LinkedHashMap, which you get for very little performance penalty compared to HashMap.
You were very close to a working solution, you need a flag to indicate whether you found the String again in s (not sure where you got names). Also we compare String(s) with .equals (not ==). And method names start with a lower case letter. Something like,
public static String uniqueString(String[] s) {
for (int i = 0; i < s.length; i++) {
boolean unique = true;
for (int j = i + 1; j < s.length; j++) {
if (s[j].equals(s[i])) {
s[j] = s[s.length - 1]; // <-- handle bug, ensure that dupes aren't
// found again.
unique = false;
break;
}
}
if (unique) {
return s[i];
}
}
return "";
}
Java 8
public static String uniqueString(String[] s) {
StringBuilder result = new StringBuilder();
Stream.of(s)
.collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))
.entrySet()
.stream()
.filter(entry -> entry.getValue() == 1)
.findFirst()
.ifPresent(entry -> result.append(entry.getKey()));
return result.toString();
}
Update, after 2 years:
Not sure why I had used a StringBuilder when I could just do it all in a single statement:
public static String uniqueString(String[] s) {
return Stream.of(s)
.collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))
.entrySet()
.stream()
.filter(entry -> entry.getValue() == 1)
.findFirst()
.map(Map.Entry::getKey)
.orElse(null);
}
Perhaps there is another solution that can also solve your problem in a more java-8 way:
using a map to record the count of the duplicated strings and then
directly traverse the array from the very beginning till the end and
once the string is not duplicated, we get it right there.
That could be like:
public static void main(String... args) {
String[] arr = {"Dog", "Cat", "Dog", "Wolf", "lion"};
Map<String, Long> stringCountMap = Arrays.stream(arr)
.collect(Collectors.groupingBy(s -> s, Collectors.counting()));
for (String s : arr) {
if (stringCountMap.get(s) == 1) {
System.out.println("The first non-duplicate string: " + s);
break;
}
}
}
Also you can turn to LinkedHashMap as others mentioned to keep the order to avoid traverse the original array again as:
private static void another(String[] arr) {
Map<String, Long> stringCountMap = Arrays.stream(arr)
.collect(Collectors.groupingBy(s -> s, LinkedHashMap::new, Collectors.counting()));
for (String s : stringCountMap.keySet()) {
if (stringCountMap.get(s) == 1) {
System.out.println("The first non-duplicate string: " + s);
break;
}
}
}
The output will always be:
The first non-duplicate string: Cat
The above answer does not work in all cases.
for instance {"Dog","Dog",Cat} would return dog. the problem being that It does not check the entire array for duplicates.
private static String getFirstUniqueString(String[] names) {
for(int x=0;x<names.length;x++)
{
if(countOccurences(names[x],names) == 1 )
return names[x];
}
return "No Unique Strings";
}
private static int countOccurences(String string, String[] names)
{
int count=0;
for(int y = 0; y<names.length;y++)
{
if(names[y].equals(string))
{
count++;
if(count >1 )
return count;
}
}
return count;
}
Instead maybe break it into two pieces.
One method to find the unique string the other to count occurrences this way we count exactly how many times the word is mentioned through the entire array. If you simply want to know there more then one and you want to save run time, uncomment the if statement.
public static String FirstUniqueString(String[] strs) {
List<String> list = new LinkedList<>();
for (String s: strs) {
if (list.contains(s)) {
list.remove(s);
} else {
list.add(s);
}
}
return list.get(0);
}
We can use a simple LinkedList to keep a track of the duplicates. For example, if the input is new String[] {Dog, Cat, Dog, Wolf, Lion, Dog}, the first unique element would still be Cat. The list after for-each loop will be in the following sequence: {Cat, Wolf, Lion, Dog}. Big O runtime will be O(N ^ 2) as the for-each loop and contains() requiring O(N) respectively.

Find the bytes that are most often found in the file

so basically i have C:/180301.txt file in which i have 1 1 2 2 3 4 5 numbers\bytes and output(49) is correct i think. my qustion is how to print out all elements which coming repetiteve times, now i have only one its 49
private static ArrayList<Integer> list1 = new ArrayList<>();
private static ArrayList<Integer> list2 = new ArrayList<>();
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
FileInputStream fileReader = new FileInputStream(br.readLine());
while (fileReader .available() > 0)
{
list1.add(fileReader .read());
}
int element = 0;
int count = 0;
for (int i = 0; i < list1.size(); i++)
{
if (same_element(list1.get(i)))
{
for (int j = 0; i < list1.size(); i++)
{
if (list1.get(i).equals(list1.get(j)))
{
count++;
element = list1.get(j);
list2.add(list1.get(i));
}
}
}
}
if (count > 1)
System.out.println(element);
fileReader.close();
}
private static boolean same_element(int list_i) {
for (Integer aList2 : list2) if (list_i == aList2) return false;
return true;
}
}
In same_element you have to switched true and false. 49 is prtinted because you never increase j. So the inner loop is buggy, too. But it should be deleted anyway because same_element now should do that job. The third problem is that you add the recent value only to the list of already seen value if it's already in there. That can't ever happen. So with some slight reworks your code might look like this:
List<Integer> fromFile = new ArrayList<>();
InputStream fileReader = new ByteArrayInputStream("71123456".getBytes("utf-8"), 0, 8);
while (fileReader.available() > 0)
{
fromFile.add(fileReader.read());
}
int element = 0;
int count = 0;
List<Integer> seen = new ArrayList<>();
for (int i = 0; i < fromFile.size(); i++)
{
Integer recent = fromFile.get(i);
if (seen.contains(recent))
{
count++;
element = recent;
}
seen.add(recent);
}
if (count > 1) System.out.println(element);
fileReader.close();
This prints the last duplicate, but still not the byte with most occurences. Today we write it like this:
Map<Byte, Integer> counters = new HashMap<>();
Path path = FileSystems.getDefault().getPath(args[0]);
// build a map with byte value as a key refering to a counter in the value
for (Byte b: Files.readAllBytes(path)) {
Integer old = counters.get(b);
counters.put(b, (old == null ? 1 : old + 1));
}
// create a comparator that orders Map.Entry objects by their value. I.E. the
// occurences of the respective byte. The order is ascending.
Comparator<Entry<Byte, Integer>> byVal = Comparator.comparingInt(e -> e.getValue());
// create a stream of Map.Entry objects. The stream is a new concept of Java8.
// That's somehow like a collection, but more powerful. While the collection
// stores data he stream has a focus on manipulating
counters.entrySet().stream()
// Use the comaparator in reversed form. That means the number of
// occurences is now descending
.sorted(byVal.reversed())
// only use the first Map.Entry. I.E. the one with most occurences
// a similar functionality is by filter.
// .filter(e -> e.getValue() > 1) would use all duplicates
.limit(1)
// print out the results. Of course the argument for println can be
// concatenated from several parts like:
// e.getKey() + "\tcount: " + e.getValue()
.forEach(e -> System.out.println(e.getKey()));
Java 8 helps a lot for problems like this. Tying to write the same with former versions take quite a bit more code.

Using Java's built-in Set classes to count EACH(keyword) unique element in List values from a list

Given a list that could contain duplicates (like the one below), I need to be able to count Each(keyword) number of unique elements.
List<String> list = new ArrayList<String>();
Set<String> set = new HashSet<String>();
list.add("M1");
list.add("M1");
list.add("M2");
list.add("M3");
set.addAll(list);
System.out.println(set.size());
How do I get the count each unique element from the List?
That means i want to know how many "M1" contains in List(list), how many "M2", etc.
The result should be the following:
2 M1
1 M2
1 M3
You are looking for Map<String, Integer> data structure, not Set
Something like
for(iterating over something){
Integer count =map.get(value);
if( count == null){
map.put(value, 1);
} else{
count++;
map.put(value, count);
}
}
Map is the data structure that maps unique to value
I think you are looking for something like this (I didn't compile it, but it should get you going in the right direction):
List<String> list = ArrayList<>();
Map<String, Integer> counts = new HashMap<>();
// Fill list with values....
for (String item:list) {
Integer count = counts.get(item);
if (count == null) {
// This is the first time we have seen item, so the count should be one.
count = 1;
} else {
// Increment the count by one.
count = count + 1;
}
counts.put(item, count);
}
// Print them all out.
for (Entry<String, Integer> entry : counts.entrySet()) {
System.out.println(entry.getValue() + " " + entry.getKey());
}
Set won't help you in this case, you need a Map:
List<String> list = new ArrayList<String>();
Set<String> set = new HashSet<String>();
list.add("M1");
list.add("M1");
list.add("M2");
list.add("M3");
// ...
Map<String, Integer> counts = new HashMap<String, Integer>();
for(String element: list) {
int currentCount;
if(counts.contains(element)) {
currentCount = counts.get(element) + 1;
} else {
currentCount = 1;
}
counts.put(element, currentCount);
}
// ...
for(String element: counts.keySet()) {
System.out.println("element: " + element + ", times appeared: " + counts.get(element));
}
means You want to know how many "M1" contains in List(list), how many "M2", instead of using set interface, you can use the Map interface because Map contain the key, value pair format ,i.e. Map data structure.
Map<key,Value>
Much easier way: use Collections.frequency()
System.out.println("M2: "+Collections.frequency(list,"M2");
will output
M2: 1

Categories