Read a file into Map<Integer, ArrayList<Double>> - java

I saw some similar questions, but mine is a little different.
I define a
Map<Integer, ArrayList<Double>> fl;
My input .txt file:
1 0.56 0.57 0.73 ..
2 2.3 3.50 ...
9 4.98 0.99 ..
How to read the file into the map fl?
Thanks!

Use a Scanner and first call Scanner.readInt() that will give you the first integer.
Then call Scanner.readLine() that will give you all the remaining double in the line as a String. Split it and parse everything to double.
Repeat the same till end of file.

Here's a try.
I've compiled and run the code.
Make sure the input file is in the same directory as your project if you use an IDE.-- This only applies if you do not modify the path below.
package fileread;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
public class FileRead {
private static HashMap<Integer, ArrayList<Double>> map = new HashMap<>();
private static BufferedReader reader;
public static void main(String[] args) {
try
{
reader = new BufferedReader(new FileReader("input"));
//or reader = new BufferedReader(new FileReader("C:\\full-path-to-your-file));
String line;
while((line = reader.readLine()) != null)
{
String[] tokens = line.split(" ");
Integer i;
Double d;
ArrayList<Double> list = new ArrayList<>();
i = Integer.valueOf(tokens[0]);
for(int j = 1; j < tokens.length; j++)
list.add(Double.valueOf(tokens[j]));
map.put(i, list);
}
}catch(IOException ex)
{
//break execution
}finally
{
if(reader != null)
try
{
reader.close();
}catch (IOException ex) {
//don't break :)
}
}
for(Integer i : map.keySet())
{
ArrayList<Double> l = map.get(i);
System.out.print("Line " + i + ": ");
for(Double d: l)
System.out.print(d + " ");
System.out.println();
}
}
}

The code for parsing the file and populating the map should be like below
try {
BufferedReader bReader = new BufferedReader(new FileReader(new File("c:/input .txt")));
String line = "";
Map<Integer, ArrayList<Double>> fl = new HashMap<Integer, ArrayList<Double>>();
while ((line = bReader.readLine()) != null) {
String[] strArray = line.split(" ");
for (int i=0;i<strArray.length;i++) {
ArrayList<Double> value = new ArrayList<Double>();
int key=0;
if(i==0){
key =Integer.valueOf(strArray[0]);
}
else{
value.add(Double.valueOf(strArray[i]));
}
fl.put(key, value);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Related

I need to print all unique words in an array of strings but not sure how

so the full program reads a story from a file and stores each word in an array of strings. After the story is read, I need to print all unique words in the story but I don't know how. Here is what I have
import java.util.*;
import csci1140.*;
import java.io.*;
public class Story{
public static final void main(String[] args){
String[] storyArray = new String[28203];
String fileName = "MultiLineStory.txt";
BufferedReader reader = null;
try{
reader = new BufferedReader(new FileReader(fileName));
}catch(FileNotFoundException fnfe){
System.out.println("Unable to find file: " + fileName);
}
try{
String input = null;
for(int i = 0; i < storyArray.length; i++){
if((input = reader.readLine()) != null){
String fill = input;
storyArray[i] = fill;
}
// System.out.print(storyArray[i] + " ");
}
} catch(IOException ioe){
ioe.printStackTrace(System.err);
} finally {
try{
reader.close();
}catch(Exception e){}
}
long start = System.nanoTime();
Arrays.sort(storyArray);
long end = System.nanoTime();
System.out.println("\n\nArrays.sort took " +((end - start)/1E9) + " Sec");
distinctValues(storyArray);
}
public static boolean distinctValues(String[] array){
int count = 0;
for (int i = 0; i < array.length - 1; i++) {
if (array[i] == array[i + 1]) {
count++;
return true;
}
}
System.out.println(count);
return false;
}
}
You can use a HashSet<String> and put all elements of the array into it. Then just print them out one by one.
String[] allWordsArray = ...;
HashSet<String> uniqueWordsSet = new HashSet<>(Arrays.asList(allWordsArray));
for (String word : uniqueWordsSet)
{
System.out.println(word);
}
Try this:
package com;
import java.util.*;
import java.io.*;
/*to print unique words which are not repeated*/
public class UniqueWords {
public static final void main(String[] args){
ArrayList<String> allWords = new ArrayList<String>();
Map<String, Integer> map = new HashMap<String, Integer>();
String fileName = "C:\\TestFiles\\MultiLineStory.txt";
BufferedReader reader = null;
try{
reader = new BufferedReader(new FileReader(fileName));
String input = null;
if((input = reader.readLine()) != null){
String arr[] = input.split(" ");
allWords.addAll(Arrays.asList(arr));
}
System.out.println(allWords.size());
}catch(FileNotFoundException fnfe){
System.out.println("Unable to find file: " + fileName);
} catch(IOException ioe){
ioe.printStackTrace(System.err);
} finally {
try{
reader.close();
}catch(Exception e){}
}
for(String word : allWords)
{
if(!map.containsKey(word))
map.put(word, 1);
else
map.put(word, map.get(word)+1);
}
Set<String> keySet = map.keySet();
for(String key : keySet)
if(map.get(key)==1)
System.out.println(key);
}
}

How to print and remove integers from a file on computer

I am trying to read a file from my computer, and have the system print out the file only containing the letters, and not printing the numbers. I have other functions in my code already so please look near the bottom where I am stuck with arraylist. How do I ignore the integers when printing?
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
public class BufferedReaderExample {
public static void main(String[] args) {
BufferedReader reader = null;
ArrayList <String> myFileLines = new ArrayList <String>();
try {
String sCurrentLine;
reader = new BufferedReader(new FileReader("/Users/wolftrek/Downloads/example.txt"));
while ((sCurrentLine = reader.readLine()) != null) {
myFileLines.add(sCurrentLine);
System.out.println(sCurrentLine);
}
} catch (IOException e) {
e.printStackTrace();
System.out.print(e.getMessage());
} finally {
try {
if (reader != null)reader.close();
} catch (IOException ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
for (int i = 0; i < myFileLines.size(); i++) {
if (myFileLines.get(i).contains("example word")) {
System.out.println(myFileLines.get(i));
}
}
Scanner myScanner = new Scanner (System.in);
String enteredString = "";
System.out.println("Please enter the characters to search for: ");
enteredString = myScanner.nextLine();
for(int i = 0; i < myFileLines.size(); i++) {
if (myFileLines.get(i).contains(enteredString)) {
System.out.println(myFileLines.get(i));
}
}
ArrayList<String> input = myFileLines;
String extract = input.replaceAll("[^a-zA-Z]+", "");
System.out.println(extract);
}
}
The error is you are applying replaceAll on a list and also the regex is not correct. Something like below will do the job. I am not clear if that's what you want though.
ArrayList<String> input = myFileLines;
for (String e : input) {
String extract = e.replaceAll("\\d+", "");
System.out.println(extract);
}

Sorting .csv Id's in natural order Java

I'm trying to write some code that will take in a list of IDs (numbers and letters) from a .csv file and output them to a new file with the IDs in "natural order". My files are compiling, but I am getting the error:
java.lang.NumberFormatException: For input string: "Alpha"
I think the issue is I am not accounting for both number and letter values in the .csv file. What am I doing wrong?! Sorry if my variable Id's are confusing...
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
public class IdReader {
public static String CSV_FILE_PATH = "/Users/eringray/Desktop/idreader/idData.csv";
public static void main(String[] args){
try {
BufferedReader br = new BufferedReader(new FileReader(CSV_FILE_PATH));
BufferedWriter bw = new BufferedWriter(new FileWriter(CSV_FILE_PATH + ".tsv"));
ArrayList<String> textIds = new ArrayList<>();
ArrayList<Integer> numberIds = new ArrayList<>();
String line = "";
while((line = br.readLine()) != null) {
String[] values = line.split(" ");
if(values.length == 1) {
String idAsString = values[0];
try{
int id = Integer.parseInt(idAsString);
numberIds.add(id);
}
catch(NumberFormatException e){
textIds.add(idAsString);
}
}
}
Collections.sort(textIds);
Collections.sort(numberIds);
for(int i = 0; i < textIds.size(); i++){
String stu = textIds.get(i);
String lineText = stu.toString();
bw.write(lineText);
bw.newLine();
}
for(int i = 0; i < numberIds.size(); i++){
int numValues = numberIds.get(i);
bw.write(numValues);
bw.newLine();
}
br.close();
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The exception is coming at this line
int id = Integer.parseInt(idAsString);
Clearly alpha is not an integer, so it will throw NumberFormatException. In a case, where you encounter such Strings which cannot be converted into numbers, you can either skips them or throw an exception.
Update
//Use two seperate lists, one for maintaining numbers and other for text
ArrayList<String> textIds = new ArrayList<>();
ArrayList<Integer> numberIds = new ArrayList<>();
String line = "";
while((line = br.readLine()) != null) {
String[] values = line.split(" ");
if(values.length == 1) {
String idAsString = values[0];
try {
//Parse the value. If successful, it means it was a number. Add to integer array.
int id = Integer.parseInt(idAsString);
numberIds.add(id);
}catch (NumberFormatException e){
//If not successful, it means it was a string.
textIds.add(idAsString);
}
}
}
//In the end sort both the list
Collections.sort(textIds);
Collections.synchronizedList(numberIds);
for(int i = 0; i < textIds.size(); i++){
String stu = textIds.get(i);
bw.write(stu);
bw.newLine();
}
for(int i = 0; i < numberIds.size(); i++){
int numValues = numberIds.get(i);
bw.write(numValues+"");
bw.newLine();
}
br.close();
bw.close();
I am not putting code for writing this data to a new file. I hope you can do that.
Sample Input
4
6
33
2
5632
23454
Alpha
So after running my code
numberIds will have [ 2,4,6,33,5632,23454]
textIds will have ["Alpha"]
NumberFormatException occurs because of AlphaNumeric characters in the input.
Please use isNumeric(str) metod in https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringUtils.html api to verify whether the input is numeric or not and convert to int , only it is numeric

Word frequency count in 2 files

I have wrote Java code to count sum of occurrences. It uses 2 .txt files as input and gives words and frequencies as output.
I would also like to print, which file how many times contains a given word. Do you have any idea how to do this?
public class JavaApplication2
{
public static void main(String[] args) throws IOException
{
Path filePath1 = Paths.get("test.txt");
Path filePath2 = Paths.get("test2.txt");
Scanner readerL = new Scanner(filePath1);
Scanner readerR = new Scanner(filePath2);
String line1 = readerL.nextLine();
String line2 = readerR.nextLine();
String text = new String();
text=text.concat(line1).concat(line2);
String[] keys = text.split("[!.?:;\\s]");
String[] uniqueKeys;
int count = 0;
System.out.println(text);
uniqueKeys = getUniqueKeys(keys);
for(String key: uniqueKeys)
{
if(null == key)
{
break;
}
for(String s : keys)
{
if(key.equals(s))
{
count++;
}
}
System.out.println("["+key+"] frequency : "+count);
count=0;
}
}
private static String[] getUniqueKeys(String[] keys)
{
String[] uniqueKeys = new String[keys.length];
uniqueKeys[0] = keys[0];
int uniqueKeyIndex = 1;
boolean keyAlreadyExists = false;
for(int i=1; i<keys.length ; i++)
{
for(int j=0; j<=uniqueKeyIndex; j++)
{
if(keys[i].equals(uniqueKeys[j]))
{
keyAlreadyExists = true;
}
}
if(!keyAlreadyExists)
{
uniqueKeys[uniqueKeyIndex] = keys[i];
uniqueKeyIndex++;
}
keyAlreadyExists = false;
}
return uniqueKeys;
}
Firstly, instead of using an array for unique keys, use a HashMap<String, Integer>. It's a lot more efficient.
Your best option is to run your processing over each line/file separately, and store these counts separately. Then merge the two counts to get the overall frequencies.
More Detail:
String[] keys = text.split("[!.?:;\\s]");
HashMap<String,Integer> uniqueKeys = new HashMap<>();
for(String key : keys){
if(uniqueKeys.containsKey(key)){
// if your keys is already in map, increment count of it
uniqueKeys.put(key, uniqueKeys.get(map) + 1);
}else{
// if it isn't in it, add it
uniqueKeys.put(key, 1);
}
}
// You now have the count of all unique keys in a given text
// To print them to console
for(Entry<String, Integer> keyCount : uniqueKeys.getEntrySet()){
System.out.println(keyCount.getKey() + ": " + keyCount.getValue());
}
// To merge, if you're using Java 8
for(Entry<String, Integer> keyEntry : uniqueKeys1.getEntrySet()){
uniqueKeys2.merge(keyEntry.getKey(), keyEntry.getValue(), Integer::add);
}
// To merge, otherwise
for(Entry<String, Integer> keyEntry : uniqueKeys1.getEntrySet()){
if(uniqueKeys2.containsKey()){
uniqueKeys2.put(keyEntry.getKey(),
uniqueKeys2.get(keyEntry.getKey()) + keyEntry.getValue());
}else{
uniqueKeys2.put(keyEntry.getKey(), keyEntry.getValue());
}
}
UPDATE : code for word(s) occurences (thanks #George)
This example is for a file, you can use it for multiple files :
public class MyTest {
Map<String,Integer> mapTable;
public MyTest(List<String> wordList){
//initialize map
makeMap(wordList);
}
public void makeMap(List<String> wordList){
mapTable = new HashMap();
for(int i = 0; i < wordList.size(); i++){
//fill the map up
mapTable.put(wordList.get(i), 0);
}
}
//update occurences in a map
public void updateMap(String [] _words){
for(int i = 0; i < _words.length; i++){
updateWordCount(_words[i]);
}
}
public void updateWordCount(String _word){
int value = 0;
//check if a word present
if(mapTable.containsKey(_word)){
value = mapTable.get(_word);
value++;
mapTable.put(_word, value);
}
}
public void DisplayCounts(){
for( String key : mapTable.keySet()){
System.out.println("Word : "+key+"\t Occurrence(s) :"+mapTable.get(key));
}
}
public void getWordCount(){
String filePath = "C:\\Users\\Jyo\\Desktop\\help.txt";
String line = "";
try {
// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader(filePath);
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader = new BufferedReader(fileReader);
String _words[] = null;
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
_words = line.split(" ");
updateMap(_words);
}
// Always close files.
bufferedReader.close();
} catch (Exception e) {
System.out.println("Error :"+e.getMessage());
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
List<String> wordList = new ArrayList<>();
wordList.add("data");
wordList.add("select");
MyTest mt = new MyTest(wordList);
mt.getWordCount();
mt.DisplayCounts();
}
}
import java.io.;
import java.util.;
public class file1{
public static void main(String[] args) throws Exception{
HashMap<String,Integer> words_fre = new HashMap<String,Integer>();
HashSet<String> words = new HashSet<String>();
try{
File folder = new File("/home/jsrathore/Dropbox/Semester 6th/IR_Lab/lab_01/one");
File[] listOfFiles = folder.listFiles();
BufferedReader bufferedReader=null;
FileInputStream inputfilename=null;
BufferedWriter out= new BufferedWriter(new OutputStreamWriter(new FileOutputStream("outfilename.txt",false), "UTF-8"));
for(File file : listOfFiles){
inputfilename= new FileInputStream(file);
/*System.out.println(file); */
bufferedReader= new BufferedReader(new InputStreamReader(inputfilename, "UTF-8"));
String s;
while((s = bufferedReader.readLine()) != null){
/*System.out.println(line);*/
s = s.replaceAll("\\<.*?>"," ");
if(s.contains("॥") || s.contains(":")|| s.contains("।")||
s.contains(",")|| s.contains("!")|| s.contains("?")){
s=s.replace("॥"," ");
s=s.replace(":"," ");
s=s.replace("।"," ");
s=s.replace(","," ");
s=s.replace("!"," ");
s=s.replace("?"," ");
}
StringTokenizer st = new StringTokenizer(s," ");
while (st.hasMoreTokens()) {
/*out.write(st.nextToken()+"\n");*/
String str=(st.nextToken()).toString();
words.add(str);
}
for(String str : words){
if(words_fre.containsKey(str)){
int a = words_fre.get(str);
words_fre.put(str,a+1);
}else{
words_fre.put(str,1);/*uwords++;//unique words count */
}
}
words.clear();
/*out.write("\n");
out.close();*/
}
Object[] key = words_fre.keySet().toArray();
Arrays.sort(key);
for (int i = 0; i < key.length; i++) {
//System.out.println(key[i]+"= "+words_fre.get(key[i]));
out.write(key[i]+" : "+words_fre.get(key[i]) +"\n");
}
}
out.close();
bufferedReader.close();
}catch(FileNotFoundException ex){
System.out.println("Error in reading line");
}catch(IOException ex){
/*System.out.println("Error in reading line"+fileReader );*/
ex.printStackTrace();
}
}
}
Late answer, however below code will count word frequency efficiently if there are multiple files
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
public class WordCounter implements Runnable {
private final Scanner scanner;
private Map<String, AtomicLong> sharedCounter;
public WordCounter(Scanner scanner, Map<String, AtomicLong> sharedCounter) {
this.scanner = scanner;
this.sharedCounter = sharedCounter;
}
public void run() {
if (scanner == null) {
return;
}
while (scanner.hasNext()) {
String word = scanner.next().toLowerCase();
sharedCounter.putIfAbsent(word, new AtomicLong(0));
sharedCounter.get(word).incrementAndGet();
}
}
public static void main(String[] args) throws IOException {
// Number of parallel thread to run
int THREAD_COUNT = 10;
List<Path> paths = new ArrayList<>();
// Add path
paths.add(Paths.get("test1.txt"));
paths.add(Paths.get("test2.txt"));
// Shared word counter
Map<String, AtomicLong> sharedCounter = new ConcurrentHashMap<>();
ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT);
for (Path path : paths) {
executor.execute(new WordCounter(new Scanner(path), sharedCounter));
}
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
System.out.println(sharedCounter);
}
}

Adding numbers to arraylist from text file java

My data file looks like this( 1st column-x; 2nd-y; 3rd-type):
46 80 2
95 75 2
78 85 2
59 54 1
81 52 2
57 78 1
72 46 2
I am trying to save x and y coordinates in two different arraylists of points depending on their type.
import java.util.*;
import java.util.ArrayList;
import java.io.*;
import java.awt.Point;
public class program {
public static void main(String []args) {
ArrayList knots = new ArrayList<Point>();
ArrayList zeros = new ArrayList<Point>();
List<Integer> list = new ArrayList<Integer>();
String line = null;
String file = "hepatitis_data1.txt";
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(file));
while((line = reader.readLine()) != null) {
String tmp[] = line.split(" +");
System.out.println(line);
for (String s:tmp) {
s = s.trim();
if(s.length() > 0) {
int i = Integer.parseInt(s.trim());
int r = Integer.parseInt(tmp[1].trim());
int g = Integer.parseInt(tmp[2].trim());
if (tmp[3].equals("1")) {
knots.add(new Point(r,g));
}
else if(tmp[3].equals("2")) {
zeros.add(new Point(r,g));
}
}
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
int total = knots.size() + zeros.size();
System.out.println("knot size" + knots.size());
System.out.println("zero size" + zeros.size());
System.out.println("total size" + total);
}
}
It doesn't show any error, but its not doing the right thing either. Total value should be 83 as I have 83 pairs of x-y coordinates, but total comes 240.
Any help??
you are doing a while statement to read the file, and in it, for each line you do a for loop. for each line the for loop is happening 3 times(!!!!) that's exactly the problem right there. do:
import java.util.*;
import java.util.ArrayList;
import java.io.*;
import java.awt.Point;
public class program {
public static void main(String []args) {
ArrayList knots = new ArrayList<Point>();
ArrayList zeros = new ArrayList<Point>();
List<Integer> list = new ArrayList<Integer>();
String line = null;
String file = "hepatitis_data1.txt";
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(file));
while((line = reader.readLine()) != null) {
String tmp[] = line.split(" +");
System.out.println(line);
String s = tmp[0];
s = s.trim();
if(s.length() > 0) {
int i = Integer.parseInt(s.trim());
int r = Integer.parseInt(tmp[1].trim());
int g = Integer.parseInt(tmp[2].trim());
if (tmp[3].equals("1")) {
knots.add(new Point(r,g));
}
else if(tmp[3].equals("2")) {
zeros.add(new Point(r,g));
}
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
int total = knots.size() + zeros.size();
System.out.println("knot size" + knots.size());
System.out.println("zero size" + zeros.size());
System.out.println("total size" + total);
}
}
I think below code repeats three time every lines it add data into either knots and zeros (3 times). So you get 240 is total value;
for (String s:tmp) {
s = s.trim();
if(s.length() > 0) {
int i = Integer.parseInt(s.trim());
int r = Integer.parseInt(tmp[1].trim());
int g = Integer.parseInt(tmp[2].trim());
if (tmp[3].equals("1")) {
knots.add(new Point(r,g));
}
else if(tmp[3].equals("2")) {
zeros.add(new Point(r,g));
}
}
it may help
thanks
I got it to work with the sample data you provided, as stated before it had to do with the enhanced for loop you were using it was running through more times than it needed increasing the size of your ArrayLists. My revision:
import java.util.*;
import java.util.ArrayList;
import java.io.*;
import java.awt.Point;
public class program {
public static void main(String []args) {
ArrayList knots = new ArrayList<Point>();
ArrayList zeros = new ArrayList<Point>();
List<Integer> list = new ArrayList<Integer>();
String line = null;
String file = "hepatitis_data1.txt";
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(file));
while((line = reader.readLine()) != null) {
String tmp[] = line.split(" +");
System.out.println(line);
int x = Integer.parseInt(tmp[1].trim());
int y = Integer.parseInt(tmp[2].trim());
int type = Integer.parseInt(tmp[3].trim());
if(type == 1)
knots.add(new Point(x,y));
if(type == 2)
zeros.add(new Point(x,y));
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
int total = knots.size() + zeros.size();
System.out.println("knot size " + knots.size());
System.out.println("zero size " + zeros.size());
System.out.println("total size " + total);
}
}
A suggestion I could make to you is to you Scanner instead of BufferedReader in this particular case. Scanner has the nextInt() method you could use to directly read the ints without having to parse any Strings

Categories