I need to create a Linked List from a text file that looks like this:
john, peter, maria, dan, george, sonja
fred, steve
ann, tom, maria
//etc...
I want to print the first name in each line (leader) and the remaining names in the line (associated with that name).
So for example:
Leader: John Friends: peter, maria, dan, george, sonja Friend Count: 5
Leader: Fred Friends: steve Friend Count: 1
//etc...
This is what I have so far:
import java.util.*;
import java.io.*;
import javax.swing.JFileChooser;
public class Test {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
LinkData ld1 = new LinkData();
JFileChooser chooser = new JFileChooser(".");
int returnVal = chooser.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("You chose to open this file: "
+ chooser.getSelectedFile().getName()
+ "Print some info"
// open and read file:
Scanner scanner = null;
try {
scanner = new Scanner(chooser.getSelectedFile());
} catch (IOException e) {
System.err.println(e);
error();
}
if (scanner == null)
error();
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
Scanner lineScan = new Scanner(line);
lineScan.useDelimiter(", ");
// System.err.println("The line that was scanned: " + line);
String leader = lineScan.next();
while (lineScan.hasNext()) {
list.add(lineScan.next());
}
System.out.println("Leaders include_" + leader + list.toString());
}
}
}
private static void error() {
System.err.println("An error has occurred: bad data");
System.exit(0);
}
}
Right now, the first name is printing fine, but then the linked list keeps growing and growing so the results don't print the way I want...
you should clear() the list between 2 line reads
while (scanner.hasNextLine()) {
list.clear();
//...
}
You are on the right track. You are processing each line into a leader and a list of friends. You will want to keep track of each of those entities in another object - I would recommend a Map. Something like:
Map<String, List<String>> leaderMap = new HashMap<String, List<String>>();
// ...
String leader = lineScan.next();
while (lineScan.hasNext()) {
list.add(lineScan.next());
}
leaderMap.put(leader, list);
Don't forget to reinitialize the list for each line you read from the file. At the end you can iterate the map, print the key (leader), and size of associated list (number of friends). Good luck!
Related
Reset may not be the right word here, but I am currently building a program that lets the user look up a name, and by scanning a txt file containing a list of names followed by numbers, the program then displays the numbers following said name. The way I am doing this is via .nextLine, but if the user inputs a name that's later in the list (say Samantha in the example) and then tries to look up a name at the top of the list (like Sally), the second name isn't found.
For reference, here is an example of that txt file:
Sally 0 0 0 0 0 0 0 0 0 0 886
Sam 58 69 99 131 168 236 278 380 467 408 466
Samantha 0 0 0 0 0 0 272 107 26 5 7
Samir 0 0 0 0 0 0 0 0 920 0 798
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
public class BabyNames {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Scanner input = new Scanner (new File("BabyNames.txt"));
Scanner keyboard = new Scanner (System.in);
System.out.println("This program allows you to search through the data from the "
+ "Social Security Administration to see how popular a particular name has "
+ "been since 1900.");
System.out.print("Name? ");
String name = keyboard.nextLine();
do {
while(input.hasNextLine()) {
String text = input.nextLine();
String[] words = text.split(" ");
if (text.contains(name)) {
System.out.println("Statistics on name \"" + name + "\"");
for (int i = 1; i < words.length; i++) {
System.out.println((1900 + (i-1)*10) + ": " + words[i]);
}
System.out.println("Enter another name or type quit to exit.");
name = keyboard.nextLine();
break;
}
else if (name.contains("quit") || name.contains("quit")){
System.exit(0);
}
else {
continue;
}
System.out.print("Error, name not found.");
}
} while (!name.contains("quit") || name.contains("quit"));
}
}
I looked up the .reset method but that hasn't seemed to work. Honestly, I'm stumped here.
Again, don't try to "reset" the Scanner or re-read the file. Your best bet is to read the file once and place all the data into a collection of some type, here a Map<String, SomeCustomClass> would work best. I'd first create a class to hold a row of information, perhaps called BabyName, one that holds a String field for name and an Integer List for the numbers listed after the name, something like:
import java.util.*;
public class BabyName {
String name;
List<Integer> numberList = new ArrayList<>();
public BabyName(String name, List<Integer> numberList) {
this.name = name;
this.numberList = numberList;
}
public String getName() {
return name;
}
public List<Integer> getNumberList() {
return numberList;
}
#Override
public String toString() {
return "BabyName [name=" + name + ", numberList=" + numberList + "]";
}
// consider adding hashCode and equals methods that are based on the name field alone
// ...
}
And then I'd recommend in your code a method that takes a line of text that has been extracted from the file, and converts it into a BabyName object:
private static BabyName createBabyName(String line) {
String[] tokens = line.split("\\s+");
String name = "";
List<Integer> numberList = new ArrayList<>();
// ... code to extract the data and that fills the numberList here
// ... left blank for you to fill in
BabyName babyName = new BabyName(name, numberList);
return babyName;
}
And then create a Map<String, BabyName> babyNameMap = new HashMap<>(); to hold BabyName objects using the name field as the map key, and when you read the file (just once mind you), you fill the map:
Scanner fileScanner = null;
try {
fileScanner = new Scanner(new File(FILE_PATH_NAME));
} catch (FileNotFoundException e) {
e.printStackTrace();
System.exit(-1);
}
// read file and fill the map
while (fileScanner.hasNextLine()) {
String line = fileScanner.nextLine();
BabyName babyName = createBabyName(line);
babyNameMap.put(babyName.getName(), babyName);
}
Then you can use this map to get the data from the user multiple times without having to re-read the file or reuse a Scanner.
e.g.,
String nameEnteredByUser = keyboard.nextLine();
BabyName selectedBabyName = babyNameMap.get(nameEnteredByUser);
// check for null here first
String name = nameEnteredByUser;
List<Integer> numberList = selectedBabyName.getNumberList();
Java Scanner, in general, doesn't know/control the pointer position in the file. It wraps over InputStream which in turn provides the input to the Scanner w.r.t every nextLine() call.
Scanner systemInput = new Scanner(System.in);
//new Scanner(new FileInputStream("file.t"));
InputStream has Mark/Reset feature which will help us to control the pointer position.
(Note: mark/ reset enables us to mark a checkpoint and you can jump back to the checkpoint later.)
Unfortunately, FileInputStream doesn't support it. But, BufferedInputStream came to the rescue.
Let's cook a solution for your problem,
Create a FileInputStream with your input file.
Wraps it with BufferedInputStream which provides mark() and reset() functions.
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream("BabyNames.txt"));
Provide it as input to the Scanner constructor.
Scanner input = new Scanner (inputStream);
Mark a checkpoint at the beginning of the file.
inputStream.mark(0);//saving a checkpoint
After the end of the inner while loop, reset the pointer to the marked position.
inputStream.reset();
Now, your code works fine.
Please take a look at my code.
import java.util.*;
import java.io.*;
public class LibraryDriver {
public static void main(String[] theArgs) {
String theAuthor = "";
String theTitle = "";
Scanner input = null;
PrintStream output = null;
try {
input = new Scanner(new File("LibraryIn1.txt"));
output = new PrintStream(new File("LibraryOut.txt"));
} catch (Exception e) {
System.out.println("Difficulties opening the file! " + e);
System.exit(1);
}
ArrayList < String > authors = new ArrayList < String > ();
ArrayList < Book > books = new ArrayList < Book > ();
while (input.hasNext()) {
// Read title
theTitle = input.nextLine();
// Read author(s)
theAuthor = input.nextLine();
authors = new ArrayList < String > (getAuthors(theAuthor));
// Insert title & author(s)into a book
// Add this book to the ArrayList<Book> of books
books.add(new Book(theTitle, authors));
authors.clear();
}
// Instantiate a Library object filled with the books read thus far
// and write the contents of the library to the output file
Library lib = new Library(books);
output.println("PRINTS INITIAL BOOK LIST:");
output.println(lib);
// Sort the current contents of the library
lib.sort();
// and write the contents of the sorted library to the output file
output.println("\nPRINTS SORTED BOOK LIST:");
output.println(lib);
// Close the first input file and open the second input file.
// Read the titles and authors from the second input file,
// add them to the library, and write the contents of the
// library to the output file.
input.close();
try {
input = new Scanner(new File("LibraryIn2.txt"));
output = new PrintStream(new File("LibraryOut.txt"));
} catch (Exception e) {
System.out.println("Difficulties opening the file! " + e);
System.exit(1);
}
while (input.hasNext()) {
theTitle = input.nextLine();
theAuthor = input.nextLine();
authors = (getAuthors(theAuthor));
Book b = new Book(theTitle, authors);
lib.add(b);
}
output.println("\nPRINT WITH NEW BOOK UNSORTED:");
output.println(lib);
// Sort the library and write it to the output file
lib.sort();
output.println("\nPRINT ALL SORTED BOOK LIST:");
output.println(lib);
// The following tests the findTitles method, i.e. test
// the findTitles method by passing “Acer Dumpling” and
// then “The Bluff”:
// Write only the "Acer Dumpling" books to the output file
output.println("\nPRINT ALL ACER DUMPLINGS:");
for (Book b: lib.findTitles("Acer Dumpling")) {
output.println(b);
}
// Write only the "The Bluff" books to the output file
output.println("\nPRINT ALL THE BLUFFS:");
for (Book b: lib.findTitles("The Bluff")) {
output.println(b);
}
// Close all open files and end main.
input.close();
output.close();
}
// Header for method that separates author names and
// returns an ArrayList<String> containing the author names
public static ArrayList < String > getAuthors(String theAuthors) {
String[] temp = theAuthors.split("\\*");
ArrayList < String > result = new ArrayList < String > (Arrays.asList(temp));
return result;
}
}
After running this program, the output file only loads like this:
PRINT WITH NEW BOOK UNSORTED:
(the list of books' title and authors)
PRINT ALL SORTED BOOK LIST:
(the list of books' title and authors)
PRINT ALL ACER DUMPLINGS:
(the list of title with acer dumpling)
PRINT ALL THE BLUFFS:
(the list of title with the bluff)
The first two parts "PRINT INITIAL BOOK LIST" and "PRINT SORTED BOOK LIST" are missing but I don't know how to figure that out.
Thanks!
You have asked don't know how to figure that out.
My answer is mentioned below:
Import your project in the eclipse.
Put the debug point in your code at multiple points.
Use the bug icon in eclipse to debug the class file.
Once it hits the debug pointer you have set, use F6 to debug it line by line or you can
use F5 to jump into the method.
You can also refer the link mentioned below:
https://www.eclipse.org/community/eclipse_newsletter/2017/june/article1.php
I am writing a method that will take in some command line arguments, validate them and if valid will edit an airport's code. The airport name and it's code are stored in a CSV file. An example is "Belfast,BHD". The command line arguments are entered as follows, java editAirport EA BEL Belfast, "EA" is the 2letter code that makes the project know that I want to Edit the code for an Airport, "BEL" is the new code, and Belfast is the name of the Airport.
When I have checked through the cla's and validated them I read through the file and store them in an ArrayList as, "Belfast,BEL". Then I want to update the text file by removing the lines from the text file and dumping in the arraylist, but I cannot figure out how to do it. Can someone show me a way using simple code (no advanced java stuff) how this is possible.
Here is my program
import javax.swing.*;
import java.io.*;
import java.util.*;
import java.text.*;
public class editAirport
{
public static void main(String [] args)throws IOException
{
String pattern = "[A-Z]{3}";
String line, line1, line2;
String[] parts;
String[] parts1;
boolean found1 = false, found2 = false;
File file = new File("Airports.txt"); // I created the file using the examples in the outline
Scanner in = new Scanner(file);
Scanner in1 = new Scanner(file);
Scanner in2 = new Scanner(file);
String x = args[0], y = args[1], z = args[2];
//-------------- Validation -------------------------------
if(args.length != 3) // if user enters more or less than 3 CLA's didplay message
JOptionPane.showMessageDialog(null, "Usage: java editAirport EA AirportCode(3 letters) AirportName");
else if(!(file.exists())) // if "Airports.txt" doesn't exist end program
JOptionPane.showMessageDialog(null, "Airports.txt does not exist");
else // if everything is hunky dory
{
if(!(x.equals("EA"))) //if user doesn't enter EA an message will be displayed
JOptionPane.showMessageDialog(null, "Usage: java editAirport EA AirportCode(3 letters) AirportName");
else if(!(y.matches(pattern))) // If the code doesn't match the pattern a message will be dislayed
JOptionPane.showMessageDialog(null, "Airport Code is invalid");
while(in.hasNext())
{
line = in.nextLine();
parts = line.split(",");
if(y.equalsIgnoreCase(parts[1]))
found1 = true; //checking if Airport code already is in use
if(z.equalsIgnoreCase(parts[0]))
found2 = true; // checking if Airport name is in the file
}
if(found1)
JOptionPane.showMessageDialog(null, "Airport Code already exists, Enter a different one.");
else if(found2 = false)
JOptionPane.showMessageDialog(null, "Airport Name not found, Enter it again.");
else
/*
Creating the ArrayList to store the name,code.
1st while adds the names and coses to arraylist,
checks if the name of the airport that is being edited is in the line,
then it adds the new code onto the name.
sorting the arraylist.
2nd for/while is printing the arraylist into the file
*/
ArrayList<String> airport = new ArrayList<String>();
while(in1.hasNext()) // 1st while
{
line1 = in1.nextLine();
if(line1.contains(z))
{
parts1 = line1.split(",");
parts1[1] = y;
airport.add(parts1[0] + "," + parts1[1]);
}
else
airport.add(line1);
}
Collections.sort(airport); // sorts arraylist
FileWriter aFileWriter = new FileWriter(file, true);
PrintWriter output = new PrintWriter(aFileWriter);
for(int i = 0; i < airport.size();)
{
while(in2.hasNext()) // 2nd while
{
line2 = in2.nextLine();
line2 = airport.get(i);
output.println(line2);
i++;
}
}
output.close();
aFileWriter.close();
}
}
}
}
The Airports.txt file is this
Aberdeen,ABZ
Belfast City,BHD
Dublin,DUB
New York,JFK
Shannon,SNN
Venice,VCE
I think your problem may lie in the two lines:
line2 = in2.nextLine();
line2 = airport.get(i);
this will overwrite the 'line2' in memory, but not in the file.
The program I am writing will sort a hospital record that comes in a text file. The format of the text file is lastname,firstname,age,roomnumber, it will look exactly like this :
Franklin,Benjamin,74,18
Hamilton,Alexander,25,6
Thatcher,Margaret,65,3
Nixon,Richard,45,7
and has to be printed with a certain format, but the user will specify how they are sorted. The format will look like this when sorted by last name:
Last First Age Room
Coolidge Calvin 24 27
Franklin Benjamin 74 8
Hamilton Alexander 50 123
Nixon Richard 45 7
I have been stuck on trying to find a way to store the lines and still be able to print out the lines together in order to keep the information together.
The Program has to be called through command-line and at the same time the program is called the user must specify the input file as the first argument (args[0]) and how to sort it as the second argument (args[1]).
I have tried a few different ways but I keep getting stuck in the same place, what would be the best way to approach this?
This is the current code btw. and the comment blocks is old code I have tried and keep it around, just in case.
import java.io.*;
import java.util.*;
public class PatientRecord {
public static void main(String args[])
{
System.out.println("Servando Hernandez");
System.out.println("Patient sorting Program.");
//
// Scanner scan = null;
// try
// {
// scan = new Scanner(new File(args[0]));
// }
// catch (FileNotFoundException e)
// {
// System.err.println("File path \"" + args[0] + "\" not found.");
// System.exit(0);
// }
//
// ArrayList<String> lines=new ArrayList<String>();
//
// while(scan.hasNextLine())
// lines.add(scan.nextLine());
//
// if(!(args.length == 0))
// {
// if(args[1] == lastname)
// {
// sortByLastName();
// }
// else if(args[1] == firstname)
// {
// sortByLastName();
// }
// else if(args[1] == age)
// {
// sortByAge();
// }
// else if(args[1] == roomnumber)
// {
// sortByRoomNumber();
// }
// }
//
List<Patient> patients = new ArrayList<>();
while(scan.hasNextLine())
{
String[] values= scan.nextLine().split(",");
patients.add(new Patient())
}
String sortType= args[1]
switch(sortType))
{
case "firsname":
break;
case "lastname":
break;
case "age":
break;
case "roomnumber":
break;
}
}
// static String sortByLastName()
// {
// Collections.sort(lines);
//
// for(String x : lines)
// System.out.println(x);
// }
class Patient
{
String firstName;
String lastName;
int age;
int roomNumber;
}
You should write a custom Comparator, let's call it PatientComparator. I will not implement the compare method completely, that's your job :-)
class PatientComparator implements Comparator<Patient> {
String sortType;
public PatientComparator(String sortType) {
this.sortType = sortType;
}
#Override
public int compare(Patient a, Patient b) {
// TODO: write your switch case here
return a.firstName.compareTo(b.firstName);
}
Then, you can sort the Patients using your own Comparator:
Collections.sort(patients, new PatientComparator(arg[1]));
Well I would start by dividing your exercise into two parts:
1- Calling the program through command-line with args[0]. Going through the file and showing the contents to the user (by respecting your format).
2- Add sorting to your script (this can be done in many ways; in general by overriding the compare method). Do step 1,sort with regarding to arg[1] and then the output.
To get you started I have done step 1 for you without doing any formatting on the output.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Test3 {
//You will store each line as an array of strings
//then you store the lines in a list of arrays of strings
public static ArrayList<String[]> mainList=new ArrayList<String[]>();
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new FileReader(args[0]));
try {
//reading each line from the input file
String line = br.readLine();
//spliting the line by comma (,) which will return
//an array of strings - our names and numbers in string format
while (line != null) {
String[] lineElements=line.split(",");
line = br.readLine();
mainList.add(lineElements);
}
} finally {
br.close();
}
//showing to the user
for (String[] line :mainList){
for (String x:line){
System.out.print(x+" ");
}
System.out.println("");
}
}
}
You simply compile with: javac name.java
Then you simply specify the file's location when you actually run it: java name /path/to/your/file/
I have run it using your sample file and I get this in the console (you simply have to format the output):
Franklin Benjamin 74 18
Hamilton Alexander 25 6
Thatcher Margaret 65 3
Nixon Richard 45 7
There is much more to do but I think this is a great start!
Alright gents I am trying to make a program that reads information from a file and then writes information out to another file.
I am reading from 2 columns first column is an integer (Team#) second column is a string(name of member)
1 Sam
3 Bob
6 Jill
3 Mike
1 Terra
1 Juice
6 Tom
6 Lucy
3 Dude
And then I have to take the 3rd instance in and output the name of the individual so it will look like this
Team Member
1 Juice
3 Dude
6 Lucy
I am having issues with trying to read the text into the array in order to output it, I am trying to use Parse String
My Code
package team;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;
public class Team {
public static void main(String[] args) throws FileNotFoundException {
//Output Please wait
System.out.println("Team Leader Started. Please wait....");
//Add Read and Write File locations
File inFile = new File("C:\\Users\\Christ\\Documents\\NetBeansProjects\\Team\\src\\team\\read.txt");
File outFile = new File("C:\\Users\\Christ\\Documents\\NetBeansProjects\\Team\\src\\team\\outputfile.txt");
// Initialise Arrays
int[] team = new int[99];
String[] name = new String[99];
// Scanner
Scanner sc = new Scanner(inFile);
sc.nextLine(); // move to second line assuming file is not empty.
// While Loop
while(sc.hasNextLine()) {
String s = sc.nextLine().trim();
String[] splitStr = s.split(" ");
team[Integer.parseInt(splitStr[0])-1] += Integer.parseInt(splitStr[1]);
name[String.parseString(splitStr[0])-1]++;
}
PrintWriter outFileWriter = new PrintWriter(outFile);
outFileWriter.println("Team Name");
// For loop
for(int i=0;i<99;i++) {
// Team
int t=i+1;
// Member
String m = name[i];
// Output to File
outFileWriter.println(t + " "+" "+ " " + m);
}
outFileWriter.close();
//Output Completed file, reference output file for sucees
System.out.println("Team Leader Completed Successfully");
}
}
Can someone please tell me where im going wrong? I do not want the final result only the ability at the moment to output the Team number and then the Member name to my output file.
Please Help ^_^
I would use a Map<Integer, ArrayList<String>> to store your team members with their corresponding teams.
It allows you to store key/value pairs and to maintain a dynamic list of members for each team.
public static void main(String [] args) throws FileNotFoundException{
System.out.println("Team Leader Started. Please wait....");
Map<Integer, ArrayList<String>> map = new HashMap<Integer, ArrayList<String>>();
//Add Read and Write File locations
File inFile = new File("C:\\Users\\Christ\\Documents\\NetBeansProjects\\Team\\src\\team\\read.txt");
File outFile = new File("C:\\Users\\Christ\\Documents\\NetBeansProjects\\Team\\src\\team\\outputfile.txt");
// Scanner
Scanner sc = new Scanner(inFile);
// While Loop
while(sc.hasNextLine()) {
String s = sc.nextLine();
String[] splitStr = s.split(" ");
Integer id = Integer.parseInt(splitStr[0]);
String name = splitStr[1];
List<String> list = map.get(id);
if(list == null)
map.put(id, new ArrayList<>(Arrays.asList(name)));
else {
list.add(name);
}
}
PrintWriter outFileWriter = new PrintWriter(outFile);
outFileWriter.println("Team Name");
// For loop
for(Map.Entry<Integer, ArrayList<String>> entry : map.entrySet()){
outFileWriter.write(entry.getKey()+"\t"+entry.getValue().toString()+"\n");
}
outFileWriter.close();
//Output Completed file, reference output file for sucees
System.out.println("Team Leader Completed Successfully");
}
Output :
Team Name
1 [Sam, Terra, Juice]
3 [Bob, Mike, Dude]
6 [Jill, Tom, Lucy]
If you know the number of inputted people, then adding a row to the input file denoting the length would allow for array sizes to be the minimum required also this gets rid of 100+ people casing an issue
like:
#9
1 Sam
3 Bob
6 Jill
3 Mike
1 Terra
1 Juice
6 Tom
6 Lucy
3 Dude