I have a string but cannot parse it into Map
string s="sakib hasan : 3 : sumon ali : 4 : tutul : 100
I need to create a HashMap from above string. sakib hasan,sumon ali,tutul,shila akter should be KEY of HashMap and 3,4,100,1, should be VALUEs of KEYs.
I have tried with the flowing code but unable to solve the problem
Map<String, Integer>amap=new HashMap<String,Integer>();
String[] splt=s.split(":");
for (String string : splt)
{
String[] pair=string.split(" ");
amap.put(pair[0])+Integer.parseInt(pair[1]);
}
Is there a way can I do this without hard coding
Try this.
Your split on ":" will return each item individually.
Then you just have to take each group as a set of two which you can account for in the for loop with i+=2
Map < String, Integer > amap = new HashMap < String, Integer > ();
String[] splt = s.split(" : ");
for (int i = 0; i < splt.length; i += 2) {
amap.put(splt[i],Integer.parseInt(splt[i + 1]));
}
In your code, your for loop is going through each element that you split and every single time, adding the hashmap only index 0 & 1. You need to increment the indices.
String s = "sakib hasan : 3 : sumon ali : 4 : tutul : 100 : shila akter : 1";
Map<String, Integer> amap = new HashMap<String, Integer>();
String[] splt = s.split(":");
for(int i = 1; i < splt.length;i+=2)
amap.put(splt[i-1].trim(), Integer.parseInt(splt[i].trim()));
Here is a similar solution using streams instead of a for loop:
IntStream.range(0, splt.length / 2)
.forEach(i -> map.put(splt[i], Integer.parseInt(splt[i + 1]));
Or you could turn the .forEach into a collector that creates the map.
At least,I got the answer
Map<String, Integer>amap=new HashMap<String,Integer>();
String[] splt=s.split(":");
try {
for (int i = 0; i <= pair.length; i +=2) {
amap.put(pair[i].trim(), Integer.parseInt(pair[(1 + i)].trim()));
}
} catch (Exception e) {
}
Related
Need help to sort and efficiently print the same occurrences of the words in the below string.
Here is the occurrence for the string: {java=2, occurences=1, program=3, sample=1, the=2}
Expected output:
java=2,occurences=1,sample=1,the=2
String str = "sample program java program the occurences the java program";
String[] inputstr = str.split(" ");
TreeMap<String,Integer> map = new TreeMap<>();
for(String input: inputstr) {
if(map.containsKey(input)) {
int value = map.get(input);
map.put(input,value+1);
} else {
map.put(input,1);
}
}
You can simply convert the above code to a single line using java-8
Map<String, Long> countMap = Arrays.stream(inputstr)
.collect(Collectors.groupingBy(Object::toString, Collectors.counting()));
EDIT :
We need to find values in the map that have an occurrence of more than one. Achieved so using the following code :
// inversed the map using "google-guava.jar"
Multimap<Long, String> inverseMap = HashMultimap.create();
for (Entry<String, Long> entry : countMap .entrySet()) {
inverseMap.put(entry.getValue(), entry.getKey());
}
for (Entry<Long, Collection<String>> entry : inverseMap.asMap().entrySet()) {
// split the values into an array
Object[] split = entry.getValue().stream().toArray();
if (split != null && split.length > 1) {
for (int j = 0; j < split.length; j++) {
System.out.println(String.valueOf(split[j]) + " : "
+ countMap.get(String.valueOf(split[j])));
}
}
}
I have a Map with key as String and value as List as below
<Key>Path1 Value=[164,123,111,131]
<Key>Path2 Value=[164,122,135,133]
<Key>Path3 Value=[190,144,100,126]
<Key>Path4 Value=[113,122,453,117]
I want to compare each Key's Value with other Key's Value like Path1 Value with rest of Path's values and so on,
and also no duplicate comparision should happen, like if Path1 value is compared in 1st iteration . It should not compare Path2 with Path1 in 2nd iteration.
Am stuck with this problem . Please help me with any solution. Thanks in advance .
I have started with following code :
for (Map.Entry<String, List<String>> entry : map1.entrySet()) {
String key = entry.getKey();
for (String val : entry.getValue()) {
// do something with key and each val
}
}
Only compare keys where the first is less than the second, or some similar simple strategy.
for (String key1 : map.keySet()) {
for (String key2 : map.keySet()) {
if (key1.compareTo(key2) < 0) {
// compare key1 to key2
}
}
}
Maybe, this would be a better strategy than one suggested by Peter Lawrey cause it's not O(N*N)
Map<String, List<String>> map = new HashMap<>();
map.put("Path1", new ArrayList<>(Arrays.asList("164","123","111","131")));
map.put("Path2", new ArrayList<>(Arrays.asList("164","122","135","133")));
map.put("Path3", new ArrayList<>(Arrays.asList("190","144","100","126")));
map.put("Path4", new ArrayList<>(Arrays.asList("113","122","453","117")));
List<String> list = new LinkedList<>(map.keySet());
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
List<String> temp = new ArrayList<>(map.get(list.get(i)));
if (temp.removeAll(map.get(list.get(j)))) {
// do what you want
System.out.println(list.get(i) + " has duplicates with " + list.get(j));
}
}
}
i am a newbie in Java (coming from JavaScript developing on Adobe LiveCycle) and facing the following problem:
I have a String array with several items. I want to put only the items with the value "a" to a HashMap. But instead of 3 "a" values in the HashMap i get 1 null value there. Why is that?
String[] s = {"a", "a", "b", "a"};
Map m = new HashMap();
for (int i = 0; i < s.length; i++) {
if (s[i].equals("a")) {
m.put(i, s[i]);
}
}
for (int i = 0; i < m.size(); i++) {
System.out.println(m.get(i));
}
// Prints
//a
//a
//null
You are putting the items in the map with key 0, 1 and 3.
You are taking them out with key 0, 1, an 2.
Use:
for (Object o : m.keySet()) {
System.out.println(m.get(o));
}
or - better:
Map<Integer, String> m = new HashMap<>();
...
for (Integer i : m.keySet()) {
System.out.println(i + " -> " + m.get(i));
}
You put the items with their corresponding index in array s in the Map, i.e. you have a Map with content {0=a, 1=a, 3=a}. Therefore if you try to access the map with key 2 (m.get(2)), you get a null since key 2 is not found in m.
Instead of using a for-loop over m's size, I recommend iteration over m's keySet() via a foreach-loop:
for (Object key : m.keySet()) {
System.out.println("key: " + key + ", value: " + m.get(key));
}
On a sidenote: you are using raw types. You should bind the types of the Map and HashMap properly (see the Javadoc of Map for details): Map<Integer, String> m = new HashMap<Integer, String>();. With properly bound types, key in the for-loop can be of type int or Integer. I recommend type Integer to avoid unnecessary Auto(un)boxing.
Your code is working correctly, but you are accessing it not correctly.
String[] s = {"a", "a", "b", "a"};
for (int i = 0; i < s.length; i++) {
if (s[i].equals("a")) {
m.put(i, s[i]);
}
}
This puts it like this
First iteration : m.put(0, "a");
Second iteration : m.put(1, "a");
Third iteration : "b" doest not equal "a" but still counts the index i up
Fourth iteration: m.put(3, "a");
Apart from the other answers you can still use your range based loop and access it with an Iterator
Iterator<String> it = m.values().iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
This question already has answers here:
How can I count and print duplicate strings in a string array in Java?
(7 answers)
Closed 7 years ago.
I have a list of user inputted names like this
String [] names = new String[x];
Then let's say they entered these names
names = {John, Bill, Sam, John, Joe, Bill};
How do I check for duplicates in this array?
and then how do I print out what names are duplicates??
I have this so far, but it is not working
boolean duplicatenames = false;
for (int i = 0; i < names.length; i++) {
for (int j = 0; j < names.length -1; j++) {
if (names[i].equals(names[j])) {
duplicatenames = true;
}
}
}
I think its just checking if there is a duplicate. but how I do I make it print out which names are duplicates?
For example:
"There are duplicate names. These names are: John, Bill"
You could iterate over the array, save the values to a map of frequencies, and then filter out only the keys that have more than a single occurrence. Java 8's streaming API allows for quite an elegant syntax to do so:
List<String> duplicates =
Arrays.stream(names)
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting()))
.entrySet()
.stream()
.filter(e -> e.getValue() > 1)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
Hint:
loop over the array and find the match. If found add that entry in a list.
Iterate over the list of duplicate element and print it.
Build a Map of name to counter. In order to have an updatable counter, use AtomicInteger. Then print all map entries with a counter >= 2. If you use a LinkedHashMap, then values will be listed in the original order of first seen.
String[] names = {"John", "Bill", "Sam", "John", "Joe", "Bill", "John"};
Map<String, AtomicInteger> nameCount = new LinkedHashMap<>(names.length * 4 / 3 + 1);
for (String name : names) {
AtomicInteger count = nameCount.get(name);
if (count == null)
nameCount.put(name, new AtomicInteger(1));
else
count.incrementAndGet();
}
StringBuilder buf = new StringBuilder();
for (Entry<String, AtomicInteger> entry : nameCount.entrySet()) {
String name = entry.getKey();
int count = entry.getValue().get();
if (count > 1) {
if (buf.length() == 0)
buf.append("There are duplicate names. These names are: ");
else
buf.append(", ");
buf.append(name);
if (count > 2)
buf.append(" (").append(count).append(" times)");
}
}
if (buf.length() != 0)
System.out.println(buf);
else
System.out.println("There are no duplicate names.");
Output
There are duplicate names. These names are: John (3 times), Bill
String[] names = {"John","Doe","John","Doe","Hello"};
Set<String> duplicatesNames = new HashSet<String>();
Set<String> testSet = new HashSet<String>();
for(String name : names){
boolean check = testSet.add(name);
if(!check){
duplicatesNames.add(name);
}
}
System.out.println("Duplicates names are " + duplicatesNames);
Use a Set to save duplicate names as they occur. Print them as you wish.
Set<String> duplicateNameSet = new HashSet<String>();
for (int i = 0; i < names.length; i++)
for (int j = 0; j < names.length -1; j++) {
if (names[i].equals(names[j])) {
duplicateNameSet.add(names[j])
}
if(duplicateNameSet.isEmpty())
System.out.println( "There are duplicate names.");
else
System.out.println( "There are duplicate names. These names are: "+duplicateNameSet);
I am trying to count occurrence of each character in a string.
So if I input aaabbbccc I am expecting o/p as {a=3, b=3, c=3} but instead I keep on getting it as {a=1, b=1, c=1} as my hashtable contains method fails and returns false. What is wrong in the code?
I also know that there is a HashMap collection quite similar to hashtable. but as I am learing java I want to try the same code with all datastructures just to get an idea of methods. The code with map is not much different than what I am doing here still this code fails. and I am not able to figure out where is the bug in the code.
I have following code:
Hashtable<Character, Integer> stringHash = new Hashtable<Character, Integer>();
This stringHash is a class level variable.
for(int i=0; i<s.length(); i++){
if(stringHash ==null || stringHash.size()==0){
stringHash.put(s.charAt(i), 1);
}
else{
if(! stringHash.contains(s.charAt(i)) ){
System.out.println(s.charAt(i));
stringHash.put(s.charAt(i), 1);
}
else{
int count = stringHash.get(s.charAt(i));
stringHash.put(s.charAt(i), count++);
}
}
System.out.println(stringHash + " " + s.charAt(i) + " "+ stringHash.contains(s.charAt(i)));
}
This code works for me:
String s = "aaabbbccc";
Map<Character, Integer> stringHash = new HashMap<Character, Integer>();
for (char ch : s.toCharArray())
stringHash.put(ch, stringHash.containsKey(ch) ? (stringHash.get(ch) + 1) : 1);
System.out.println(stringHash);
// output: "{a=3, b=3, c=3}"
I am using a Map<K, V> instead of HashTable<K, V>, but this is more common.
Try something like this....The reason your code is failing is that you are checking contains() on HashTable instead of its keySet. Hope that helps
public static void main(String[] args) {
// TODO Auto-generated method stub
String s = "aaaaabbcccc";
Hashtable<Character, Integer> counter = new Hashtable<Character, Integer>();
int count = 0;
for(int i=0;i<s.length();i++){
if(!counter.keySet().contains(s.charAt(i))){
counter.put(s.charAt(i), 1);
} else {
count = counter.get(s.charAt(i));
counter.put(s.charAt(i), ++count);
}
}
for(char c:counter.keySet()) {
System.out.println("Character : "+c+" - Occurences : "+counter.get(c));
}
}
o/p
Character : b - Occurences : 2
Character : c - Occurences : 4
Character : a - Occurences : 5
Your code
if(stringHash ==null || stringHash.size()==0){
stringHash.put(s.charAt(i), 1);
}
would throw NPE if somehow the hashmap is null. Luckily it seems that you have initialized it properly. The block rather should have been
if(stringHash ==null){
stringHash = new HashMap()
stringHash.put(s.charAt(i), 1);
}
Again, that would not have fixed your bug. You should use containsKey instead of contains that checks for value in HashTable. What you are looking to implement can be summarized in following pseudocode.
initialize hashmap
for each character c in inputString
count = 0
if hashmap has a key for c
count = get value for c from hashmap
end if
put in to hashmap c, count + 1
end for
In Java this would look like :
Map<Character, Integer> charCountMap = new HashMap<>();
for(char c : inputString.toCharArray()){
int count = 0;
if(charCountMap.containsKey(c)){
count = charCountMap.get(c);
}
charCountMap.put(c,count+1);
}
Or for the adventurous, here is Java8 version
Map<Character,Long> map = s.chars().mapToObj(i->(char)i)
.collect(Collectors
.groupingBy(e -> e,
Collectors.counting()));
System.out.println(map);
Finally, do not use HashTable its a legacy class, no one uses it now a days. Stick with HashMap or other flavors of Map implementations.
Debug my code questions are discouraged, but in the way of solving the general problem of counting characters in a string I can suggest a much simpler method:
public static int[] countCharacters( String s ){
int[] count = new int[ 256 ];
for( int xChar = 0; xChar < s.length(); xChar++ ) count[ s.charAt( xChar ) ]++;
return count;
}
This assumes you have single byte characters.
Why do you use hashMap for counting character occurance?
I would use integer array of size 255 like so:
int[] counter = new int[256];
String s = "aaabbbcccc";
for(int i = 0; i < s.length(); i++){
counter[s.charAt(i)]++;
}
for(int i = 0; i < counter.length; i++)
if(counter[i] > 0)
System.out.println(((char)i) + " occurs " + counter[i] + " times");
that coude would give an output:
a occurs 3 times
b occurs 3 times
c occurs 4 times
Don't use Hashtable, you can simplify that code a lot, something like this should work:
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
public class Main {
public static void main(String[] args) {
Map<Character, Long> countMap = count("aabbbcccc");
for (Map.Entry<Character, Long> entry : countMap.entrySet()) {
System.out
.println(MessageFormat.format("Char ''{0}'' with count ''{1}''", entry.getKey(), entry.getValue()));
}
}
private static Map<Character, Long> count(String value) {
Map<Character, Long> countMap = new HashMap<Character, Long>();
if (StringUtils.isNotBlank(value)) {
for (int i = 0; i < value.length(); i++) {
Long count = countMap.get(value.charAt(i));
count = count == null ? 1 : count + 1;
countMap.put(value.charAt(i), count);
}
}
return countMap;
}
}