Reading text from file and comparing it to seriers of characters - java

can I get recommendation or like an advice for what should be used or be known to complete this task (in the most rudimentary way I guess). if someone would be willing to write a code that would be fantastic but vague answers on the neccesary knowledge or technique will suffice.
I would like a program where at the start you input characters either seperataed by pressing enter or a string that could be like chopped up into separate items of an array (I guess) - characters separated by a comma - and that would be then compared to a txt file that contains series of entries and only those that contain some of (meaning shorter) or all of the characters that have been provided at the start would be printed, perhaps even the print would be separated by a length of the entry (word).
Any ideas on how to do this? Also, can the results be printed somewhere else than the command line, like another txt file? Need to do this in java. Thanks.

Take a look at following example:
public class SimpleExample {
public static void main(String[] args) throws ClassNotFoundException {
Scanner inputNumbers = new Scanner(System.in);
List<Integer> listOfNumbersToStore = new ArrayList<>();
List<Integer> listOfNumbersToCheck = new ArrayList<>();
int number;
String answer;
boolean flag = true;
// do code within a loop while flag is true
do {
// print message to screen
System.out.print("Would you like to put new number to your file list (Y/N): ");
// get answer (Y/N) to continue
answer = inputNumbers.next();
// if answer is Y or y
if ("Y".equalsIgnoreCase(answer)) {
// print message
System.out.print("Put your number: ");
// get input integer and assign it to number
number = inputNumbers.nextInt();
// add that number to a list of numbers to store to file
listOfNumbersToStore.add(number);
} else if ("N".equalsIgnoreCase(answer)) {
flag = false;
}
} while (flag);
writeToFile(listOfNumbersToStore);
System.out.println("---------- Check numbers ----------");
flag = true; // set it again to true
//do code within a loop while flag is true
do {
System.out.print("Would you like to put new number to your check list (Y/N) : ");
answer = inputNumbers.next();
if ("Y".equalsIgnoreCase(answer)) {
System.out.print("Put your number: ");
number = inputNumbers.nextInt();
listOfNumbersToCheck.add(number);
} else if ("N".equalsIgnoreCase(answer)) {
flag = false;
}
} while (flag);
// get a list from a file
List<Integer> readFromFile = readFromFile();
// check if there are any common elements within compared lists
boolean areThereAnyCommonElements = !Collections.disjoint(
listOfNumbersToCheck, readFromFile);
//create a new treeset used for containing unique elements and ordering it naturally, from 0 to n
Set<Integer> set = new TreeSet<>(listOfNumbersToCheck);
set.retainAll(readFromFile);
// print these messages
System.out.println("Are there any common integers between a list from a file and checking list? " + areThereAnyCommonElements);
System.out.println("Those integers are: " + set.toString());
}
/**
* List implements Seriazable interface, therefore store it to a file
* serialized
*
* #param numberOfIntegers
*/
public static void writeToFile(List<Integer> numberOfIntegers) {
try {
// create a file output stream to write to the file with the specified name.
FileOutputStream fileOutputStream = new FileOutputStream("tekstDataOutputStream");
// writes the serialization stream header to the underlying file stream;
ObjectOutputStream dataOutputStream = new ObjectOutputStream(new BufferedOutputStream(fileOutputStream));
// write a list to object output stream
dataOutputStream.writeObject(numberOfIntegers);
//close them
dataOutputStream.close();
fileOutputStream.close();
} catch (IOException ioE) {
System.err.println("JVM reported an error! Take a look: " + ioE);
}
}
public static List<Integer> readFromFile() throws ClassNotFoundException {
//create an empty list of integers
List<Integer> result = new ArrayList<>();
try {
//opening a connection to an actual file
FileInputStream fis = new FileInputStream("tekstDataOutputStream");
//used for reading from a specified input stream
ObjectInputStream reader = new ObjectInputStream(fis);
//get that list
result = (List<Integer>) reader.readObject();
//close streams
reader.close();
fis.close();
} catch (IOException ioE) {
System.err.println("JVM reported an error! Take a look: " + ioE);
}
return result;
}
}

Related

How to get Max and Min values from CSV file in Java

Here is my CSV file: marks.csv and it contains with the student number on the left and the marks on the right:
B00123,55
B00783,35
B00898,67
I need to be able to search through this file and find the maximum mark and the minimum mark. I have this code that returns the values but I don't know what to do afterwards:
public static void MaxAndMin()
{
// .csv files are comma separated
String fileName = "src\\data\\marks.csv";
File file = new File(fileName);
try
{
Scanner inputStream = new Scanner(file);
while(inputStream.hasNext())
{
String data = inputStream.next();
String [] values = data.split(",");
int mark = Integer.parseInt(values[1]);
System.out.println(mark);
}
inputStream.close();
}
catch (FileNotFoundException ex)
{
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
And this returns the following:
55
35
67
What can I try next?
A shorter, clearer and less verbose answer to this could be the following:
private static void minAndMax() {
try (Stream<String> stream = Files.lines(Paths.get(FILE_PATH))) {
IntSummaryStatistics statistics = stream
.map(s -> s.split(",")[1])
.mapToInt(Integer::valueOf)
.summaryStatistics();
System.out.println("Lowest:: " + statistics.getMin());
System.out.println("Highest:: " + statistics.getMax());
} catch (IOException e) {
e.printStackTrace();
}
}
Simply read the file's lines, open up a Stream<String>, map and split it on the comma, map to an Integer and create an IntSummaryStatistics object out of it. Then simply use the getMin and getMax values. Clean and simple. Note also that this answer uses try-with-resources to auto manager the various actions that may require manual handling.
public static void MaxAndMin()
{
// .csv files are comma separated
String fileName = "src\\data\\marks.csv";
File file = new File(fileName);
TreeSet<Integer> ts1 = new TreeSet<Integer>();
try
{
Scanner inputStream = new Scanner(file);
while(inputStream.hasNext())
{
String data = inputStream.next();
String [] values = data.split(",");
int mark = Integer.parseInt(values[1]);
ts1.add(mark);
}
inputStream.close();
System.out.println("Min Marks"+ts1.first());
System.out.println("Max Marks"+ts1.last());
}
catch (FileNotFoundException ex)
{
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
You can store values in Treeset and then fetch first and last element.
Treeset stores element in sorted order.
You are on the right track by reading the lines of the file and splitting each line by the separator (comma in your locale).
In order to find the maximum value, you have several possibilities. A simple one would be a class attribute, let's say private int maxValue = -1; which you can use to store the current maximum in your loop. Check if maxValue is less than the current value (mark in your code) and if yes, set maxValue = mark;.
You can alternatively store all the values in a data structure for primitives and Strings or make objects of a proper custom class and store those in a List, for example. Then iterate the structure afterwards or use the up-to-date stream API. A small example is this:
public static void main(String[] args) {
// use java.nio to access the file system object
Path csvPath = Paths.get("U:\\temp\\stackoverflow\\some_file.csv");
// create a data structure that stores the values read from csv file
Map<String, Integer> lineValues = new HashMap<String, Integer>();
try {
// read the file content (this does not take care of a header line!)
List<String> lines = Files.readAllLines(csvPath, StandardCharsets.ISO_8859_1);
// split each line into the values
lines.forEach(line -> {
String[] values = line.split(",");
// put the values into the data structure
lineValues.put(values[0], Integer.parseInt(values[1]));
});
// use the stream api to get the maximum value from the data structure
int max = lineValues.values().stream().max(Integer::compareTo).get();
// print the result
System.out.println("The maximum value in " + csvPath.toAbsolutePath().toString() + " is " + max);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You can do something like this, keep in mind that I used streams of Integers in Java 8 to find the min and max from List :
public static void maxAndMin() {
// .csv files are comma separated
String fileName = "src\\data\\marks.csv";
File file = new File(fileName);
try(Scanner inputStream = new Scanner(file)) {
ArrayList<Integer> listNumbers = new ArrayList<>();
while(inputStream.hasNext()) {
String data = inputStream.next();
listNumbers.add(Integer.valueOf(data.split(",")[1]));
}
int maxValue = listNumbers.stream().max(Comparator.comparing(Integer::valueOf)).get();
int minValue = listNumbers.stream().min(Comparator.comparing(Integer::valueOf)).get();
System.out.println("Max value is : "+maxValue);
System.out.println("Min value is : "+minValue);
}
catch (FileNotFoundException ex)
{
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}

Java : How do I print an ascending column and next to that column the same set of integers except in descending order all in one single text file

I need some help in how to do a certain step as I can not seem to figure it out.
I was given a text file with 100 numbers in it all random, I am supposed to sort them either in ascending order, descending order, or both depending on the user input. Then which ever the user inputs the set of integers will be sorted and printed in a text file. I am having trouble printing the both file. Here is my code up until the both statement.
public static void print(ArrayList<Integer> output, String destination){
try {
PrintWriter print = new PrintWriter(destination);
for(int i = 0; i < output.size(); i++){
print.print(output.get(i) + " ");
}
print.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
BufferedReader br = null;
ArrayList<Integer> words = new ArrayList<>();
BufferedReader reader;
String numbers;
try {
reader = new BufferedReader(new FileReader("input.txt"));
while((numbers = reader.readLine()) != null)
{
words.add(Integer.parseInt(numbers));
}
System.out.println("How would you like to sort?");
System.out.println("Please enter asc(For Ascending), desc(For Decending), or both");
String answer = input.next();
Collections.sort(words);
if(answer.equals("asc")){
Collections.sort(words);
System.out.println(words);
print(words,"asc.txt");
}
else if(answer.equals("desc")){
Collections.reverse(words);
System.out.println(words);
print(words,"desc.txt");
When I type in "both" the text file that is created only has one column set of integers that is going in descending order, not both and I have no idea how to print both sets. If someone could shed some light I would really appreciate it.
else if(answer.equals("both")){
System.out.println(words);
print(words,"both.txt");
Collections.reverse(words);
System.out.println(words);
print(words,"both.txt");
You need to use FileOutputStreams#Constructor where you can pass a boolean value to tell whether to append to my file or not.
So use like this:
PrintWriter print = new PrintWriter(new FileOutputStream(destination, true));
/\
||
||
To append to the file
From JavaDocs
public FileOutputStream(File file,
boolean append)
throws FileNotFoundException
Parameters:
file - the file to be opened for writing.
append - if true, then bytes will be written to the end of the file
rather than the beginning

JAVA Sort lines in ascending order in new file and display it

I'm writing a simple game guessing in java using eclipse. Now I want to print out the details in ascending order. I tried many ways that I found on this forum,but couldn't solve it. That's why I need your help.
My code are as follows :
File f = new File ("scores.txt");
// name of the folder created at the root of the project
String ligne;
try
{
PrintWriter pw = new PrintWriter (new BufferedWriter (new FileWriter (f, true)));
if (numberOfTries==1){
pw.println (numberOfTries + " try by " + str ) ;
}
else if (numberOfTries!=1){
pw.println (numberOfTries + " tries by " + str ) ;
}
// pw.println (numberOfTries) ;
pw.close ();
// this line MUST be written.
}
catch (IOException exception) {
System.out.println ("Error while writing data:" + exception.getMessage());
}
BufferedReader ficTexte;
// to read from a folder text.
try {
ficTexte = new BufferedReader (new FileReader(f));
do {
ligne= ficTexte.readLine();
if (ligne !=null)
// if the line is not empty.
System.out.println(ligne);
} while (ligne !=null);
ficTexte.close();
System.out.println("\n");
}
// Show message in case of errors.
catch (FileNotFoundException e) {
System.out.println (e.getMessage());
}
catch (IOException e) {
System.out.println (e.getMessage());
}
}
Suppose I have
3 tries by Vibe
2 tries by NoNo
10 tries by Caroline
7 tries by Mata
10 tries by Lionel
and I want it to be arranged as follows :
2 tries by NoNo
3 tries by Vibe
7 tries by Mata
10 tries by Caroline
10 tries by Lionel
How could it be done?
Basic solution:
Write code to read all rows in the file and store them in a List of your choosing (ArrayList seems reasonable). Check out Scanner
Write a custom comparator to perform your sort. Check out Comparator. As in the fge answer, compare two strings. Unlike in that answer, don't use matcher, which feels like overkill to me. Instead just call String.split() and refer to the first element in the returned array (index zero). Convert this to a number perform the comparison.
Collections.sort(rows, yourComparator) (just like in the fge answer).
Write the rows to a file of your choosing.
Try this:
private static final Comparator<String> CMP = new Comparator<String>()
{
#Override
public int compare(final String a, final String b)
{
final int inta = Integer.parseInt(a.split("\\s+")[0]);
final int intb = Integer.parseInt(b.split("\\s+")[0]);
return Integer.compare(inta, intb);
}
}
Then, later in code:
final Path file = Paths.get("scores.txt");
final List<String> lines = Files.readAllLines(file, StandardCharsets.UTF_8);
Collections.sort(lines, CMP);
for (final String line: lines)
System.out.println(line);
(similarly you should use Files.newBufferedWriter() to get a Writer to your file)

Java reading a vector of objects from a file only reads the first object in the vector

I have several objects which are assigned attributes based on user input. I then store those objects in a vector, and then write that vector to a file but on deserializing the stored vector, only the first object is read. Here's the code that i have so far:
public Vector<Cases> registerCase() {
Vector<Cases> casesVector = new Vector<Cases>(10, 2);
Scanner myCase = new Scanner(System.in);
Scanner userChoice = new Scanner(System.in);
System.out.println("HOW MANY CASES DO YOU WANT TO REGISTER?");
int count = userChoice.nextInt();
for (int i = 0; i < count; i++) {
Cases newCase = new Cases();
System.out.println("Enter the case name: ");
newCase.caseName = myCase.nextLine();
System.out.println("Enter the client's name: ");
newCase.client = myCase.nextLine();
System.out.println("Enter the case type: ");
newCase.caseType = myCase.nextLine();
if((newCase.caseType.equals("Major")) || newCase.caseType.equals("major")){
newCase.closedCaseRevenue = majorCasePrice;
}else {
newCase.closedCaseRevenue = (int) (0.75 * majorCasePrice);
}
casesVector.add(newCase);
}
try{
// Open a file to write to, named SavedCases.sav.
FileOutputStream saveFile = new FileOutputStream("SavedCases.sav", true);
ObjectOutputStream save = new ObjectOutputStream(saveFile);
save.writeObject(casesVector);
save.close();
}
catch(Exception exc){
exc.printStackTrace();
}
Vector<Cases> comVector = new Vector<Cases>();
try{
FileInputStream saveFile = new FileInputStream("SavedCases.sav");
ObjectInputStream save = new ObjectInputStream(saveFile);
comVector = (Vector<Cases>) save.readObject();
System.out.println("The size of the vector is: " + comVector.size());
save.close(); // This also closes saveFile.
}
catch(Exception exc){
exc.printStackTrace();
}
for (Cases law_case : comVector) {
System.out.println("Name: " + law_case.caseName);
System.out.println("Client: " + law_case.client);
System.out.println("Case Type: " + law_case.caseType);
System.out.println("Case State: " + law_case.caseState);
System.out.println("Case Revenue: " + law_case.closedCaseRevenue);
System.out.println();
}
return casesVector;
}
EDIT: So to append to a vector if it already exists...
Check for an existing file using
File f = new File(FileName);
if(f.exists())
/* Read in the vector from the file using an object input stream on the file */
else
/* make a new vector */
Then read in your input and output it exactly as you have it there, however when you make the FileOutputStream do not include the true flag, this will cause you to add a new vector each time instead of just overwriting the current vector with the new, correct one.
ORIGINAL
The problem is with your implementation is that you are appending a new array each time you write to the save file. So whenever you try to read from the file, you are always getting that first array you ever made.
I am not sure whether you'd like to just overwrite the array with a new one each time, but you should either read in the current array before you add more cases or not set the append flag to true for the FileWriter constructor depending on your desired result.
Your code is running fine for me and is printing all the registered cases except that I am not appending to the already created file(that's what you want, right?). Couple of checks-
Is the class Cases implementing java.io.Serializable?
What is the visibility of the fields? default/private?
I see that you are not closing FileOutputStream and FileInputStream, is there a reason you are doing so?

Print data from file to array

I need to have this file print to an array, not to screen.And yes, I MUST use an array - School Project - I'm very new to java so any help is appreciated. Any ideas? thanks
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class HangmanProject
{
public static void main(String[] args) throws FileNotFoundException
{
String scoreKeeper; // to keep track of score
int guessesLeft; // to keep track of guesses remaining
String wordList[]; // array to store words
Scanner keyboard = new Scanner(System.in); // to read user's input
System.out.println("Welcome to Hangman Project!");
// Create a scanner to read the secret words file
Scanner wordScan = null;
try {
wordScan = new Scanner(new BufferedReader(new FileReader("words.txt")));
while (wordScan.hasNext()) {
System.out.println(wordScan.next());
}
} finally {
if (wordScan != null) {
wordScan.close();
}
}
}
}
Nick, you just gave us the final piece of the puzzle. If you know the number of lines you will be reading, you can simply define an array of that length before you read the file
Something like...
String[] wordArray = new String[10];
int index = 0;
String word = null; // word to be read from file...
// Use buffered reader to read each line...
wordArray[index] = word;
index++;
Now that example's not going to mean much to be honest, so I did these two examples
The first one uses the concept suggested by Alex, which allows you to read an unknown number of lines from the file.
The only trip up is if the lines are separated by more the one line feed (ie there is a extra line between words)
public static void readUnknownWords() {
// Reference to the words file
File words = new File("Words.txt");
// Use a StringBuilder to buffer the content as it's read from the file
StringBuilder sb = new StringBuilder(128);
BufferedReader reader = null;
try {
// Create the reader. A File reader would be just as fine in this
// example, but hay ;)
reader = new BufferedReader(new FileReader(words));
// The read buffer to use to read data into
char[] buffer = new char[1024];
int bytesRead = -1;
// Read the file to we get to the end
while ((bytesRead = reader.read(buffer)) != -1) {
// Append the results to the string builder
sb.append(buffer, 0, bytesRead);
}
// Split the string builder into individal words by the line break
String[] wordArray = sb.toString().split("\n");
System.out.println("Read " + wordArray.length + " words");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (Exception e) {
}
}
}
The second demonstrates how to read the words into an array of known length. This is probably closer to the what you actually want
public static void readKnownWords()
// This is just the same as the previous example, except we
// know in advance the number of lines we will be reading
File words = new File("Words.txt");
BufferedReader reader = null;
try {
// Create the word array of a known quantity
// The quantity value could be defined as a constant
// ie public static final int WORD_COUNT = 10;
String[] wordArray = new String[10];
reader = new BufferedReader(new FileReader(words));
// Instead of reading to a char buffer, we are
// going to take the easy route and read each line
// straight into a String
String text = null;
// The current array index
int index = 0;
// Read the file till we reach the end
// ps- my file had lots more words, so I put a limit
// in the loop to prevent index out of bounds exceptions
while ((text = reader.readLine()) != null && index < 10) {
wordArray[index] = text;
index++;
}
System.out.println("Read " + wordArray.length + " words");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (Exception e) {
}
}
}
If you find either of these useful, I would appropriate it you would give me a small up-vote and check Alex's answer as correct, as it's his idea that I've adapted.
Now, if you're really paranoid about which line break to use, you can find the values used by the system via the System.getProperties().getProperty("line.separator") value.
Do you need more help with the reading the file, or getting the String to a parsed array? If you can read the file into a String, simply do:
String[] words = readString.split("\n");
That will split the string at each line break, so assuming this is your text file:
Word1
Word2
Word3
words will be: {word1, word2, word3}
If the words you are reading are stored in each line of the file, you can use the hasNextLine() and nextLine() to read the text one line at a time. Using the next() will also work, since you just need to throw one word in the array, but nextLine() is usually always preferred.
As for only using an array, you have two options:
You either declare a large array, the size of whom you are sure will never be less than the total amount of words;
You go through the file twice, the first time you read the amount of elements, then you initialize the array depending on that value and then, go through it a second time while adding the string as you go by.
It is usually recommended to use a dynamic collection such as an ArrayList(). You can then use the toArray() method to turnt he list into an array.

Categories

Resources