Counting keys in LinkedHashMap<String, ArrayList<String>> - java

Let's say I have something like this:
LinkedHashMap <String, ArrayList<String>> h
keyOne has
stringOne
stringTwo
stringThree
keyTwo has
stringOne
How do I count the size of ArrayList of the associated key? So for keyOne, it should give me 3.

Did you try:
ArrayList<String> tmp = h.get("keyOne");
if ( tmp != null ) {
return tmp.size();
} else {
return 0;
}

You can just write h.get(key).size()

int count = h.get("keyOne").size();
should do it.

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Set;
public class Test {
public static void main(String[] args) {
LinkedHashMap<String, ArrayList<String>> h = new LinkedHashMap<String, ArrayList<String>>();
ArrayList<String> al1 = new ArrayList<String>();
al1.add("Value11");
al1.add("Value12");
al1.add("Value13");
ArrayList<String> al2 = new ArrayList<String>();
al2.add("Value21");
h.put("key1", al1);
h.put("key2", null);
Set<String> set = h.keySet();
for (String key : set) {
ArrayList<String> al = h.get(key);
if (al != null)
System.out.println (key + " : " + al.size());
else
System.out.println (key + " is empty ");
}
}
}
Output:
key1 : 3
key2 is empty

Related

How to get even values from map and then adding value key to list?

Alright, so my problem here right now is that I can get all the words from a list, find the occurrence and then add key and value pairs to map, but since I need to return a list of words which frequency is even, I get stuck. Any help?
public static List<String> onlyEvenWordsList(List<String> words) {
Map<String, Integer> wordsWithCount = new HashMap<>();
List<String> onlyEvenWords = new ArrayList<>();
for (String word : words) {
Integer count = wordsWithCount.get(word);
if (count == null) {
count = 0;
}
wordsWithCount.put(word, count + 1);
}
for(Integer value: wordsWithCount.values()){
if(value % 2 == 0){
....
}
}
return onlyEvenWords;
}
public static List<String> onlyEvenWordsList(List<String> words) {
Map<String, Integer> wordsWithCount = new HashMap<>();
List<String> onlyEvenWords = new ArrayList<>();
for (String word : words) {
Integer count = wordsWithCount.get(word);
if (count == null) {
count = 0;
}
wordsWithCount.put(word, count + 1);
}
for(Map.Entry<String, Integer> entry: wordsWithCount.entrySet()){
if(entry.getValue()%2==0){
onlyEvenWords.add(entry.getKey());
}
}
return onlyEvenWords;
}
And to print the list in main
System.out.println(Arrays.toString( onlyEvenWordsList(words).toArray()));

How can I convert a String into ArrayList by counting occurrence of each characters?

I have a Input String as :
String str="1,1,2,2,2,1,3";
I want count each id occurrence and store them into List,and I want output Like this:
[
{
"count": "3",
"ids": "1, 2"
}
{
"count": "1",
"ids": "3"
}
]
I tried by using org.springframework.util.StringUtils.countOccurrencesOf(input, "a"); like this. But after counting not getting the things like I want.
This will give you the desired result. You first count the occurrences of each character, then you group by count each character in a new HashMap<Integer, List<String>>.
Here's a working example:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Test {
public static void main(String[] args) {
String str = "1,1,2,2,2,1,3";
String[] list = str.split(",");
HashMap<String, Integer> occr = new HashMap<>();
for (int i = 0; i < list.length; i++) {
if (occr.containsKey(list[i])) {
occr.put(list[i], occr.get(list[i]) + 1);
} else {
occr.put(list[i], 1);
}
}
HashMap<Integer, List<String>> res = new HashMap<>();
for (String key : occr.keySet()) {
int count = occr.get(key);
if (res.containsKey(count)) {
res.get(count).add(key);
} else {
List<String> l = new ArrayList<>();
l.add(key);
res.put(count, l);
}
}
StringBuffer sb = new StringBuffer();
sb.append("[\n");
for (Integer count : res.keySet()) {
sb.append("{\n");
List<String> finalList = res.get(count);
sb.append("\"count\":\"" + count + "\",\n");
sb.append("\"ids\":\"" + finalList.get(0));
for (int i = 1; i < finalList.size(); i++) {
sb.append("," + finalList.get(i));
}
sb.append("\"\n}\n");
}
sb.append("\n]");
System.out.println(sb.toString());
}
}
EDIT: A more generalised solution
Here's the method that returns a HashMap<Integer,List<String>>, which contains the number of occurrences of a string as a key of the HashMap where each key has a List<String> value which contains all the strings that occur key number of times.
public HashMap<Integer, List<String>> countOccurrences(String str, String delimiter) {
// First, we count the number of occurrences of each string.
String[] list = str.split(delimiter);
HashMap<String, Integer> occr = new HashMap<>();
for (int i = 0; i < list.length; i++) {
if (occr.containsKey(list[i])) {
occr.put(list[i], occr.get(list[i]) + 1);
} else {
occr.put(list[i], 1);
}
}
/** Now, we group them by the number of occurrences,
* All strings with the same number of occurrences are put into a list;
* this list is put into a HashMap as a value, with the number of
* occurrences as a key.
*/
HashMap<Integer, List<String>> res = new HashMap<>();
for (String key : occr.keySet()) {
int count = occr.get(key);
if (res.containsKey(count)) {
res.get(count).add(key);
} else {
List<String> l = new ArrayList<>();
l.add(key);
res.put(count, l);
}
}
return res;
}
You need to do some boring transfer, I'm not sure if you want to keep the ids sorted. A simple implementation is:
public List<Map<String, Object>> countFrequency(String s) {
// Count by char
Map<String, Integer> countMap = new HashMap<String, Integer>();
for (String ch : s.split(",")) {
Integer count = countMap.get(ch);
if (count == null) {
count = 0;
}
count++;
countMap.put(ch, count);
}
// Count by frequency
Map<Integer, String> countByFrequency = new HashMap<Integer, String>();
for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
String chars = countByFrequency.get(entry.getValue());
System.out.println(entry.getValue() + " " + chars);
if (chars == null) {
chars = "" + entry.getKey();
} else {
chars += ", " + entry.getKey();
}
countByFrequency.put(entry.getValue(), chars);
}
// Convert to list
List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
for (Map.Entry<Integer, String> entry : countByFrequency.entrySet()) {
Map<String, Object> item = new HashMap<String, Object>();
item.put("count", entry.getKey());
item.put("ids", entry.getValue());
result.add(item);
}
return result;
}
Hey check the below code, it help you to achieve your expected result
public class Test
{
public static void main(String args[])
{
String str = "1,1,2,2,2,1,3"; //Your input string
List<String> listOfIds = Arrays.asList(str.split(",")); //Splits the string
System.out.println("List of IDs : " + listOfIds);
HashMap<String, List<String>> map = new HashMap<>();
Set<String> uniqueIds = new HashSet<>(Arrays.asList(str.split(",")));
for (String uniqueId : uniqueIds)
{
String frequency = String.valueOf(Collections.frequency(listOfIds, uniqueId));
System.out.println("ID = " + uniqueId + ", frequency = " + frequency);
if (!map.containsKey(frequency))
{
map.put(frequency, new ArrayList<String>());
}
map.get(frequency).add(uniqueId);
}
for (Map.Entry<String, List<String>> entry : map.entrySet())
{
System.out.println("Count = "+ entry.getKey() + ", IDs = " + entry.getValue());
}
}
}
One of the approach i can suggest you is to
put each "character" in hashMap as a key and "count" as a value.
Sample code to do so is
String str = "1,1,2,2,2,1,3";
HashMap<String, String> map = new HashMap();
for (String c : str.split(",")) {
if (map.containsKey( c)) {
int count = Integer.parseInt(map.get(c));
map.put(c, ++count + "");
} else
map.put(c, "1");
}
System.out.println(map.toString());
}
<!--first you split string based on "," and store into array, after that iterate array end of array lenght in side loop create new map and put element in map as a Key and set value as count 1 again check the key and increase count value in map-->
like....
String str="1,1,2,2,2,1,3";
String strArray=str.split(",");
Map strMap= new hashMap();
for(int i=0; i < strArray.length(); i++){
if(!strMap.containsKey(strArray[i])){
strMap.put(strArray[i],1)
}else{
strMap.put(strArray[i],strMap.get(strArray[i])+1)
}
}
String str="1,1,2,2,2,1,3";
//Converting given string to string array
String[] strArray = str.split(",");
//Creating a HashMap containing char as a key and occurrences as a value
Map<String,Integer> charCountMap = new HashMap<String, Integer>();
//checking each element of strArray
for(String num :strArray){
if(charCountMap.containsKey(num))
{
//If char is present in charCountMap, incrementing it's count by 1
charCountMap.put(num, charCountMap.get(num)+1);
}
else
{
//If char is not present in charCountMap, and putting this char to charCountMap with 1 as it's value
charCountMap.put(num, 1);
}
}
//Printing the charCountMap
for (Map.Entry<String, Integer> entry : charCountMap.entrySet())
{
System.out.println("ID ="+entry.getKey() + " count=" + entry.getValue());
}
}
// Split according to comma
HashMap<String, Integer> hm = new HashMap<String, Integer>();
for (String key : tokens) {
if (hm.containsKey(key)) {
Integer currentCount = hm.get(key);
hm.put(key, ++currentCount);
} else {
hm.put(key, 1);
}
}
// Organize info according to ID
HashMap<Integer, String> result = new HashMap<Integer, String>();
for (Map.Entry<String, Integer> entry : hm.entrySet()) {
Integer newKey = entry.getValue();
if (result.containsKey(newKey)) {
String newValue = entry.getKey() + ", " + result.get(newKey);
result.put(newKey, newValue);
} else {
result.put(newKey, entry.getKey());
}
}
And here is a complete Java 8 streaming solution for the problem. The main idea is to first build a map of the occurances of each id, which results in:
{1=3, 2=3, 3=1}
(first is ID and second the count) and then to group by it by the count:
public static void main(String[] args) {
String str = "1,1,2,2,2,1,3";
System.out.println(
Pattern.compile(",").splitAsStream(str)
.collect(groupingBy(identity(), counting()))
.entrySet().stream()
.collect(groupingBy(i -> i.getValue(), mapping( i -> i.getKey(), toList())))
);
}
which results in:
{1=[3], 3=[1, 2]}
This is the most compact version I could come up with. Is there anything even smaller?
EDIT: By the way here is the complete class, to get all static method imports right:
import static java.util.function.Function.identity;
import java.util.regex.Pattern;
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;
public class Java8StreamsTest6 {
public static void main(String[] args) {
String str = "1,1,2,2,2,1,3";
System.out.println(
Pattern.compile(",").splitAsStream(str)
.collect(groupingBy(identity(), counting()))
.entrySet().stream()
.collect(groupingBy(i -> i.getValue(), mapping(i -> i.getKey(), toList())))
);
}
}

Reversing a HashMap storing words and their line numbers

I have a HashMap
HashMap<String, LinkedList<Integer>> indexMap;
which is storing all words in a file and their corresponding line numbers where they appear.
Example -
This is just an example
to demonstrate what I am saying an is
Would display
This [1]
demonstrate [2]
an [1 2]
is [1 2]
...
....
And so on. I want to reverse this HashMap so that it displays the words stored at each line number.
For the particular example above, it should display
1 [This, an, just, example, is]
2 [demonstrate, what, to, I, am, saying, is, an]
For this particular task, this is what I have done -
import java.io.FileReader;
import java.io.LineNumberReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
public class ReverseIndex {
private static Map<String, LinkedList<Integer>> indexMap = new HashMap<String, LinkedList<Integer>>();
public static LinkedList<Integer> getIndex(String word) {
return indexMap.get(word);
}
public static void main(String[] args) {
try {
LineNumberReader rdr = new LineNumberReader(
new FileReader(
args[0]));
String line = "";
int lineNumber = 0;
//CREATING THE INITIAL HASHMAP WHICH WE WANT TO REVERSE
while ((line = rdr.readLine()) != null) {
lineNumber++;
String[] words = line.split("\\s+");
for (int i = 0; i < words.length; i++) {
LinkedList<Integer> temp = new LinkedList<Integer>();
if (getIndex(words[i]) != null)
temp = getIndex(words[i]);
temp.add(lineNumber);
indexMap.put(words[i], temp);
}
}
//FINISHED CREATION
Map<Integer, LinkedList<String>> myNewHashMap = new HashMap<Integer, LinkedList<String>>();
for(Map.Entry<String, LinkedList<Integer>> entry : indexMap.entrySet()){
LinkedList<Integer> values = entry.getValue();
String key = entry.getKey();
LinkedList<String> temp = new LinkedList<String>();
for(int i = 0; i <= lineNumber; i++) {
if(values.contains(i)) {
if(!temp.contains(key))
temp.add(key);
myNewHashMap.put(i, temp);
}
}
}
for(Map.Entry<Integer, LinkedList<String>> entry : myNewHashMap.entrySet()){
Integer tester = entry.getKey();
LinkedList<String> temp2 = new LinkedList<String>();
temp2 = entry.getValue();
System.out.print(tester + " ");
for(int i = 0; i < temp2.size(); i++) {
System.out.print(temp2.get(i) + " ");
}
System.out.println();
}
rdr.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
However the problem with this is, for the example that we had above, it would print -
1 example
2 an
How could I reverse it so that it works perfectly with the expected output?
Just replace the first for loop in your main with the below code. I have made some changes to you original code as per convention like moved variable declaration out of loop and changed the logic in a way it checks if the LinkedList<'String'> already exists for the line number if so add it to the list or else create a new LinkedList<'String'> and then add word.
LinkedList<Integer> values = null;
String key = null;
LinkedList<String> temp = null;
for(Map.Entry<String, LinkedList<Integer>> entry : indexMap.entrySet())
{
values = entry.getValue();
key = entry.getKey();
temp = new LinkedList<String>();
for(int value : values)
{
temp = myNewHashMap.get(value);
if(temp == null )
{
temp = new LinkedList<String>();
myNewHashMap.put(value,temp);
}
temp.add(key);
}
}

WordCount with treemap

I am writing a program to read a text file, store in a treeMap and then print out the word frequences(wordcount) to the console. I keep getting the FileNotFoundException "I THINK" I'm pretty much almost done, with the remainder of the code. Any help, pointers, suggestions and tips would be appreciated. thx. Code Below
import java.util.*;
/**
*
* #author
*
*/
public class WordCount {
public static void main(String[] args) {
// TODO Auto-generated method stub
TextFileInput take = new TextFileInput("noteFile.txt");
String m = take.readLine();
String [] input = m.split("[ \n\t\r,.;:!?(){}}]");
TreeMap <String, Integer> myMap = new TreeMap <String, Integer> ();
/**Set set = myMap.entrySet();
Iterator i = set.iterator();
Map.Entry <String, Integer> me; **/
for(int f = 0; f < input.length; f++) {
String key = input[f].toUpperCase();
if(input[f].length() > 1) {
if(myMap.get(key) == null) {
myMap.put(key, 1);
}
else {
int value = myMap.get(key).intValue();
value++;
myMap.put(key, value);
}
}
}
/**while(i.hasNext()) {
me = (Map.Entry)i.next();
System.out.print(me.getKey() + ": ");
System.out.println(me.getValue()); **/
for(Map.Entry<String, Integer> entry : myMap.entrySet()) {
System.out.println(entry.getKey() + " : "+ entry.getValue());
}
}
}
}
TextFileInput - I am not sure about this. You can use File and Scanner to read from the file.
Give the absolute path of the file. eg. C://notepad.txt (for windows)
Moreover you are reading one line from the file. You can add it in while loop. And to print the TreeMap you can do as follows,
for(String entry : myMap.keySet()) {
System.out.println(entry + " : "+ myMap.get(entry));
}
And the complete code is below,
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
public class WordCount {
public static void main(String[] args) throws FileNotFoundException {
File file = new File("C://notepad.txt");
Scanner scanner=new Scanner(file);
TreeMap <String, Integer> myMap = new TreeMap <String, Integer> ();
while(scanner.hasNext())
{
String m = scanner.nextLine();
String [] input = m.split("[ \n\t\r,.;:!?(){}}]");
for(int f = 0; f < input.length; f++) {
String key = input[f].toUpperCase();
if(input[f].length() > 1) {
if(myMap.get(key) == null) {
myMap.put(key, 1);
}
else {
myMap.put(key, (myMap.get(key))+1);
}
}
}
}
for(String entry : myMap.keySet()) {
System.out.println(entry + " : "+ myMap.get(entry));
}
}
}

How to Count Repetition of Words in Array List?

I've these code for searching occurrence in Array-List but my problem is how I can get result
out side of this for loop in integer type cause I need in out side , may be there is another way for finding
occurrence with out using for loop can you help me ?
thank you...
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("aaa");
Set<String> unique = new HashSet<String>(list);
for (String key : unique) {
int accurNO = Collections.frequency(list, key);
System.out.println(key + ": " accurNO);
}
You should declare a map like Map<String, Integer> countMap = new HashMap<String, Integer>(); before the loop, and populate it within the loop.
Map<String, Integer> countMap = new HashMap<String, Integer>();
for (String key : unique) {
int accurNO = Collections.frequency(list, key);
coutMap.put(key, accurNO);
//...
}
//now you have a map with keys and their frequencies in the list
Set unique = new HashSet(list);
and
Collections.frequency(list, key);
are too much overhead.
Here is how i would do it
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("aaa");
Map<String, Integer> countMap = new HashMap<>();
for (String word : list) {
Integer count = countMap.get(word);
if(count == null) {
count = 0;
}
countMap.put(word, (count.intValue()+1));
}
System.out.println(countMap.toString());
Output
{aaa=2, bbb=1}
EDIT output one by one: iterate over the set of entries of the map
for(Entry<String, Integer> entry : countMap.entrySet()) {
System.out.println("frequency of '" + entry.getKey() + "' is "
+ entry.getValue());
}
Output
frequency of 'aaa' is 2
frequency of 'bbb' is 1
EDIT 2 No need for looping
String word = null;
Integer frequency = null;
word = "aaa";
frequency = countMap.get(word);
System.out.println("frequency of '" + word + "' is " +
(frequency == null ? 0 : frequency.intValue()));
word = "bbb";
frequency = countMap.get(word);
System.out.println("frequency of '" + word + "' is " +
(frequency == null ? 0 : frequency.intValue()));
word = "foo";
frequency = countMap.get(word);
System.out.println("frequency of '" + word + "' is " +
(frequency == null ? 0 : frequency.intValue()));
Output
frequency of 'aaa' is 2
frequency of 'bbb' is 1
frequency of 'foo' is 0
Note that you will always have a collection and you need extract the count from it for a particular word one way or another.
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("aaa");
Map<String,Integer> countMap = new HashMap();
Set<String> unique = new HashSet<String>(list);
for (String key : unique) {
int accurNO = Collections.frequency(list, key);
countMap.put(key,accurNO);
System.out.println(key + ": " accurNO);
}
The Map answers work, but you can extend this answer to solve more problems.
You create a class that has the field values you need, and put the class in a List.
import java.util.ArrayList;
import java.util.List;
public class WordCount {
private String word;
private int count;
public WordCount(String word) {
this.word = word;
this.count = 0;
}
public void addCount() {
this.count++;
}
public String getWord() {
return word;
}
public int getCount() {
return count;
}
}
class AccumulateWords {
List<WordCount> list = new ArrayList<WordCount>();
public void run() {
list.add(new WordCount("aaa"));
list.add(new WordCount("bbb"));
list.add(new WordCount("ccc"));
// Check for word occurrences here
for (WordCount wordCount : list) {
int accurNO = wordCount.getCount();
System.out.println(wordCount.getWord() + ": " + accurNO);
}
}
}
I would sort the list first to avoid going thru the whole list with Collections.frequency every time. The code will be longer but much more efficient
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("aaa");
Map<String, Integer> map = new HashMap<String, Integer>();
Collections.sort(list);
String last = null;
int n = 0;
for (String w : list) {
if (w.equals(last)) {
n++;
} else {
if (last != null) {
map.put(last, n);
}
last = w;
n = 1;
}
}
map.put(last, n);
System.out.println(map);
output
{aaa=2, bbb=1}

Categories