I am doing an android app, where i read the text from an image and i get an output string like below,
NAME : michael /nPHONE NO: 771234521/n e-Mail: michael#gmai|.com /nCompany:
Google/n
I want to extract them individually as a string, and assign to a variable like,
String Name = "michael";
String Phone = "771234521";
how can i achieve like this,here is my piece of code,
input.setText(recognizedText);
String[] separated = recognizedText.split("/");
for (String s: separated)
{
}
I think want to parse your fields into a Map, and that they are separated on the newline character (\n). Perhaps like this -
// Convert the string in to a Map<String, String>.
public static Map<String, String> toMap(String in) {
// the return map.
Map<String, String> map = new HashMap<String, String>();
// a tokenizer on newline
StringTokenizer st = new StringTokenizer(in, "\n");
while (st.hasMoreTokens()) { // while there are lines.
String token = st.nextToken(); // get the line.
String[] kv = token.split(":"); // split on colon.
if (kv.length > 1) { // check that there's a key and a
// value.
map.put(kv[0].trim(), kv[1].trim()); // add it to
// the map.
}
}
return map; // return the map.
}
public static void main(String[] args) {
String str = "NAME : michael \nPHONE NO: 771234521\n"
+ " e-Mail: michael#gmai|.com \nCompany: Google\n";
Map<String, String> map = toMap(str);
System.out.println(map);
}
Which outputs this here -
{NAME=michael, e-Mail=michael#gmai|.com, Company=Google, PHONE NO=771234521}
public static void main(String... args) {
String s = "NAME : michael /nPHONE NO: 771234521/n e-Mail: michael#gmai|.com /nCompany: Google/n";
String[] str = s.split("/n");
for(int i=0;i<str.length;i++)
{
str[i]=str[i].trim();
}
for (int k = 0; k < 4; k++) {
System.out.println(str[k]);
}
}
O/P :
NAME : michael
PHONE NO: 771234521
e-Mail: michael#gmai|.com
Company: Google
You should use String Tokenizer like this
Tokenize the string based on your delimeter /
String src = "NAME : michael /nPHONE NO: 771234521/n e-Mail: michael#gmai|.com /nCompany: Google/n";
String noLineSrc = src.replace("/n", ",");
String[] couples = noLineSrc.split(",");
Map<String, String> result = new HashMap<String, String>();
for(String couple : couples) {
String[] coupleValue = couple.split(":");
result.put(coupleValue[0].trim(), coupleValue[1].trim());
}
The keys are: "NAME:", "PHONE NO:", "e-Mail:", and "Company:".
After splitting the string with split("/n"), you can do a str[i].contains("Name:") to check for the key.
The value comes after the ":". So, int pos = str[i].indexof(":") + 1 will be the starting position of the value.
String value = str[i].substring(pos) gives you the value.
Then value.trim() to remove spaces.
Related
In my program, I am reading data from a CSV file which follows the pattern of dance group and then the dancers in the group. I am struggling to sort the dancers names alphabetically.
public String listAllDancesAndPerformers() {
// get CSV file for dances Data
ArrayList<String> dancesData = getCSV("src/csvFiles/danceShowData_dances.csv");
int lineNumber = 0;
String result = "";
//for each line in dances csv file
for (String line : dancesData) {
//split into two sections - [0] is name of dance & [1] is dancers
String[] splitByTab = line.split("\t");
//take the dancers [1] of splitByTab and split it by commas
// this makes that seperatedNames[1], [2] etc are all the dancers
//and i am supposed to sort the seperated names to print out alphabetticaly
String[] separatedNames = splitByComma(splitByTab[1]);
lineNumber++;
result += lineNumber + ": ";
result += (splitByTab[0].trim()) + "\n";
result += (listAllDancersIn(splitByTab[0].trim())) + "\n";
}
return result;
}
list all dancers method which takes an input of a dance name and then prints out the dance name followed by the dancers inside reading from the CSV file
public String listAllDancersIn(String dance) {
// get CSV file for dances Data
ArrayList<String> dancesData = getCSV("src/csvFiles/danceShowData_dances.csv");
String result = "";
// for each line in dances csv file
for (String line : dancesData) {
// split into two sections - [0] is name of dance & [1] is dancers
String[] splitByTab = line.split("\t");
splitByTab[0] = splitByTab[0].trim();
// if name of dance matches given dance name
if (splitByTab[0].equals(dance)) {
// split names of dancers into individual strings
String[] separatedNames = splitByComma(splitByTab[1]);
// iterate through names
for (int i = 0; i < separatedNames.length; i++) {
// append result with output of getDanceGroupMembers (and trim input)
result += ", " + getDanceGroupMembers(separatedNames[i].trim());
}
}
}
// remove leading comma and space
result = result.substring(2);
return result;
}
In your listAllDancersIn method, use an ArrayList instead of your result += instructions.
Then at end, you can use the default sorter, which will sort alphabetically:
Collections.sort(resultAsList);
ANd if you still want this method to return a sorted string, instead of a sorted list, you can do it this way, using Join method:
return String.join(", ", resultAsList);
Marius, see whether below code works as you intended.
import java.util.ArrayList;
import java.util.Collections;
public class SortDancers {
public static void main(String[] args) {
System.out.println(new SortDancers().listAllDancesAndPerformers());
}
public String listAllDancesAndPerformers() {
ArrayList<String> dancesData = new ArrayList<String>();
dancesData.add("Dance1 \t Kelly, Andrew, Nathan");
dancesData.add("Dance2 \t John, Sally, Kevin, Abby");
dancesData.add("Dance3 \t Laura, Benny, Jane");
// I assume you get this kind of data from getCSV()
int lineNumber = 0;
String result = "";
for (String line : dancesData) {
String[] splitByTab = line.split("\t");
String[] separatedNames = splitByTab[1].split(",");
lineNumber++;
result += lineNumber + ": ";
result += (splitByTab[0].trim()) + "\n";
ArrayList<String> separatedNamesList = new ArrayList<String>();
for (int i = 0; i < separatedNames.length; i++) {
separatedNamesList.add(separatedNames[i].trim());
}
Collections.sort(separatedNamesList);
result += String.join(", ", separatedNamesList);
result += "\n";
}
return result;
}
}
I think you should split your code:
Read CSV file and build correct data structure;
Print data structure to console or String.
public static Map<String, Set<String>> listAllDancesAndPerformers() {
final Pattern pattern = Pattern.compile("(?<group>\\w+)\\t+(?<dancers>.+)");
final Pattern comma = Pattern.compile("\\s*,\\s*");
Map<String, Set<String>> groups = new TreeMap<>();
for (String line : getCSV("src/csvFiles/danceShowData_dances.csv")) {
Matcher matcher = pattern.matcher(line);
if (matcher.matches())
groups.put(matcher.group("group"), new TreeSet<>(Arrays.asList(comma.split(matcher.group("dancers")))));
}
return groups;
}
If danceShowData_dances.csv file content is:
beginners anna,maria,olga
mature bob,marvin,peter
Then result Map will contain:
"beginners" : ["anna", "maria", "olga"]
"mature" : ["bob", "marvin", "peter"]
And finally you can create method that convert given Map into String with required format:
public static String printToString(Map<String, Set<String>> groups) {
int count = 1;
StringBuilder buf = new StringBuilder();
for (Map.Entry<String, Set<String>> entry : groups.entrySet()) {
if (buf.length() > 0)
buf.append('\n');
buf.append(count++).append(':');
buf.append(entry.getKey());
if (!entry.getValue().isEmpty())
buf.append('\n').append(String.join(", ", entry.getValue()));
}
return buf.toString();
}
Output:
1:beginners
anna, maria, olga
2:mature
bob, marvin, peter
I'm about working with Junit test , hashmap in java .
My code looks like :
HashMap <String,String> var = new HashMap <String,String>();
var.put("key1","value1");
var.put("key2","value2");
var.put("key3","value3");
var.put("key4","value4");
Iterator<String> itKey = var.keySet().iterator();
String Existing_coaches = "" ;
while(itKey.hasNext()){
String key = (String)itKey.next();
// Existing_coaches = i use concat function
}
return Existing_coaches ;
What i want to do is to return the itkeys as this forms :
key1, key2, key3, key4
we start with the first key + comma etc .
so i need to know what's the first key and the last one .
Any idea on how we can do that ?
Join the keys with a comma and a space:
import java.util.*;
public class MyClass {
public static void main(String args[]) {
Map<String, String> m = new LinkedHashMap<>();
m.put("key1", "val1");
m.put("key2", "val2");
m.put("key3", "val3");
m.put("key4", "val4");
System.out.println(String.join(", ", m.keySet()));
}
}
Output:
key1, key2, key3, key4
Map<String, String> map = new LinkedHashMap<>();
// Approach 1 : use advanced for (foreach) loop
StringBuilder keyString = new StringBuilder();
for(String key: map.keySet()){
keyString = keyString.append(key + ", ");
}
String resultStr = keyString.toString().substring(0, keyString.toString().length()-2); // deducting 2 for comma and space
System.out.println(resultStr);
// Approach 2: use for loop
StringBuilder keyString2 = new StringBuilder();
Object[] keySet = (Object[]) map.keySet().toArray();
for(int i=0; i < keySet.length; i++) {
if(i == keySet.length-1) {
keyString2 = keyString2.append(keySet[i].toString());
} else {
keyString2 = keyString2.append(keySet[i].toString() + ", ");
}
}
System.out.println(keyString2.toString());
// Approach 3: Use String join
System.out.println(String.join(", ", map.keySet()));
If you are not familiar with String.join, use the first one, or use the second if you like it. Both ways work:
import java.util.HashMap;
import java.util.Iterator;
public class Hash {
public static void main(String args[]) {
HashMap <String, String> var = new HashMap <String, String>();
var.put("A", "1");
var.put("B", "2");
var.put("C", "3");
var.put("D", "4");
System.out.println("method 1: " + myHash(var));
System.out.println("method 2: " + myHash2(var));
}
public static String myHash(HashMap var) {
Iterator<String> itKey = var.keySet().iterator();
String Existing_coaches = "" ;
while(itKey.hasNext()){
String key = (String)itKey.next();
Existing_coaches = Existing_coaches + key + ", ";
}
return Existing_coaches.substring(0, Existing_coaches.length() -2) ;
}
public static String myHash2(HashMap var) {
return String.join(", ", var.keySet());
}
}
Output is:
method 1: A, B, C, D
method 2: A, B, C, D
I'm working on a project where I enter a URL, the file is read and the amount of lines, characters, and words are outputted in a text file. I'm not having an issue with that. Code below will be pretty long, sorry in advance.
I also have to output to the same text file all of the words in the file, and the amount of times each word is displayed in the file. I've been working on it for a while and I've gotten to the point where all the lines/characters/words are outputted to the text file, but I can't figure out how to display the actual words and the amount of times they are in the file.
String[] wordSubstrings = line.replaceAll("\\s+", " ").split(" ");
List<String> uniqueWords = new ArrayList<String>();
for (int i = 0; i < wordSubstrings.length; i++) {
if (!(uniqueWords.contains(wordSubstrings[i]))) {
uniqueWords.add(wordSubstrings[i]);
You could use a Multiset
Multiset<String> words = HashMultiset.create();
for (String word : wordList)
words.add(word);
for (String word : words.elementSet())
System.out.println(word + ": " + words.count(word));
I've tested something with a HashMap which seems to work pretty well.
Here is my code that I used to test it, I hope it helps:
String[] wordSubstrings = new String[]{"test","stuff","test","thing","test","test","stuff"};
HashMap<String,Integer> uniqueWords = new HashMap<>();
for ( int i = 0; i < wordSubstrings.length; i++)
{
if(!(uniqueWords.containsKey(wordSubstrings[i])))
{
uniqueWords.put(wordSubstrings[i], 1);
}
else
{
int number = uniqueWords.get(wordSubstrings[i]);
uniqueWords.put(wordSubstrings[i],number + 1);
}
}
for (Map.Entry<String, Integer> entry : uniqueWords.entrySet()) {
String key = entry.getKey();
int value = entry.getValue();
//Do Something with the key and value
}
You can use arraylist of class which will contain word and count as member variables.
List <MyClass> uniqueWords = new ArrayList<MyClass> ();
MyClass()
{
String uniqueword;
int count;
}
I want to display only the words that appear more than once in a string, single appearance of string should not be printed. Also i want to print strings whose length is more than 2 (to eliminate is,was,the etc)..
The code which I tried..prints all the strings and shows is occurrence number..
Code:
public static void main(String args[])
{
Map<String, Integer> wordcheck = new TreeMap<String, Integer>();
String string1="world world is new world of kingdom of palace of kings palace";
String string2[]=string1.split(" ");
for (int i=0; i<string2.length; i++)
{
String string=string2[i];
wordcheck.put(string,(wordcheck.get(string) == null?1: (wordcheck.get(string)+1)));
}
System.out.println(wordcheck);
}
Output:
{is=1, kingdom=1, kings=1, new=1, of=3, palace=2, world=3}
single appearance of string should not be printed...
also i want to print strings whose length is more than 2 (to eliminate is,was,the etc)..
Use it
for (String key : wordcheck.keySet()) {
if(wordcheck.get(key)>1)
System.out.println(key + " " + wordcheck.get(key));
}
Keeping track of the number of occurrences in a map will allow you to do this.
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;
public class Test1
{
public static void main(String[] args)
{
String string1="world world is new world of kingdom of palace of kings palace";
String string2[]=string1.split(" ");
HashMap<String, Integer> uniques = new HashMap<String, Integer>();
for (String word : string2)
{
// ignore words 2 or less characters long
if (word.length() <= 2)
{
continue;
}
// add or update the word occurrence count
Integer existingCount = uniques.get(word);
uniques.put(word, (existingCount == null ? 1 : (existingCount + 1)));
}
Set<Entry<String, Integer>> uniqueSet = uniques.entrySet();
boolean first = true;
for (Entry<String, Integer> entry : uniqueSet)
{
if (entry.getValue() > 1)
{
System.out.print((first ? "" : ", ") + entry.getKey() + "=" + entry.getValue());
first = false;
}
}
}
}
To get only the words occurring more then once, you have to filter your map.
Depending on your Java version you can use either this:
List<String> wordsOccuringMultipleTimes = new LinkedList<String>();
for (Map.Entry<String, Integer> singleWord : wordcheck.entrySet()) {
if (singleWord.getValue() > 1) {
wordsOccuringMultipleTimes.add(singleWord.getKey());
}
}
or starting with Java 8 this equivalent Lambda expression:
List<String> wordsOccuringMultipleTimes = wordcheck.entrySet().stream()
.filter((entry) -> entry.getValue() > 1)
.map((entry) -> entry.getKey())
.collect(Collectors.toList());
Regarding the nice printing, you have to do something similar while iterating over your result.
Use the below code
for (String key : wordcheck.keySet()) {
if(wordcheck.get(key)>1)
System.out.println(key + " " + wordcheck.get(key));
}
public static void main(String args[])
{
Map<String, Integer> wordcheck = new TreeMap<String, Integer>();
String string1="world world is new world of kingdom of palace of kings palace";
String string2[]=string1.split(" ");
HashSet<String> set = new HashSet<String>();
for (int i=0; i<string2.length; i++)
{
String data=string2[i];
for(int j=0;j<string2.length;j++)
{
if(i != j)
{
if(data.equalsIgnoreCase(string2[j]))
{
set.add(data);
}
}
}
}
System.out.println("Duplicate word size :"+set.size());
System.out.println("Duplicate words :"+set);
}
TreeMap.toString() is inherited from AbstractMap and the documentation states that
Returns a string representation of this map. The string representation consists of a list of key-value mappings in the order returned by the map's entrySet view's iterator, enclosed in braces ("{}"). Adjacent mappings are separated by the characters ", " (comma and space). Each key-value mapping is rendered as the key followed by an equals sign ("=") followed by the associated value. Keys and values are converted to strings as by String.valueOf(Object).
So better you write your own method that prints out the TreeMap in a way you want.
I am trying to create a program that counts the number of times a word appears in a text and also tell you how many times it appears on each line. I have managed to find the number of times the word appears and the number of lines in the text, but I cannot find on which line the word appears in and how many times. Could you please help me? This is my code so far:
FileReader file = new FileReader("C:/Users/User/Desktop/test.txt");
BufferedReader buffer = new BufferedReader(file);
String line = buffer.readLine();
Map<String, Integer> hash = new HashMap<String, Integer>();
int counter = 0; //number of lines
while (line != null){
String[] words = line.split(" ");
for (String s : words) {
Integer i = hash.get(s);
hash.put(s, (i==null)? 1: i+1);
}
line = buffer.readLine();
counter = counter + 1;
}
System.out.println(hash);
System.out.println(counter);
It is additional information to each row. You just need an information of count on each line, therefore simple Map is not enough, you need Map of Map at each row.
There are two basic ways :
Map<Integer, Map<String, Integer>> hashOfHash = new HashMap<>();
List<Map<String, Integer>> list = new ArrayList<>();
First line creates Map of your Map based on integer key value - which would be the line.
Second line is creating list of your Maps, because the order in list is stored, you can now which line is which just by iterating through it.
I would recommend second line.
You need also modify your while cycle a bit to be able to create new map for each line (think about it that you need to do the same as it does at first line).
For example this should do the same as your program, but it will show results for each row :
public static void main(String[] args) throws FileNotFoundException, IOException {
FileReader file = new FileReader("C:/Users/User/Desktop/test.txt");
BufferedReader buffer = new BufferedReader(file);
String line = buffer.readLine();
List<Map<String, Integer>> list = new ArrayList<>();
while (line != null) {
Map<String, Integer> hash = new HashMap<String, Integer>();
String[] words = line.split(" ");
for (String s : words) {
Integer i = hash.get(s);
hash.put(s, (i == null) ? 1 : i + 1);
}
line = buffer.readLine();
list.add(hash);
}
int i=0;
for (Map<String, Integer> mapAtRow : list) {
i++;
System.out.println("at row " + i + "we found this: " + mapAtRow);
}
}
Here is a recursive method that will allow you, using String.indexOf to count how many times a word appears in a line.
You have read the line from your bufferedReader
String line = buffer.readLine();
then in your loop you have
for (String s : words) {
int numberOfOccurencesOfS = countNumberOfTimesInALine(line,s);
}
the countNumberOfTimesInALinereceives the original line and the word your are counting as arguments. To use it you should also declare a class variable like this:
private static int numberOfLineOccurences;
Here is the method
public static int countNumberOfTimesInALine(String line, String word) {
if (line.indexOf(word) == -1) {
return numberOfLineOccurences;
} else {
numberOfLineOccurences++;
if (line.indexOf(word) + word.length() > line.length() -1 ) {
return numberOfLineOccurences;
}
return countNumberOfTimesInALine(
line.substring(line.indexOf(word) + word.length()), word );
}
}
Here is a usage example:
String line = "DEMO TEST DEMO TEST DEMO TEST ALPHA BETA GAMMA";
System.out.println("Number of occurences of TEST is " + countNumberOfTimesInALine(line, "TEST"));
Here is the result
Number of occurences of TEST is 3
I have published an answer to a similar question as yours here