i am doing a self project to help me understand more about java.but i am stuck at this question.
I have a following txt file :
Name Hobby
Susy eat fish
Anna gardening
Billy bowling with friends
What is the best way to read all the line and put it in arraylist(name,hobby). but the tricky part is the
eat fish or bowling with friends
has white spaces and it must be put under one array and obviously i cannot hardcode it.
here is my current code
public void openFile(){
try{
x = new Scanner(new File("D://practice.txt"));
}catch (Exception e){
System.out.println("File could not be found");
}
}
public void readFile(){
while (x.hasNextLine()){
x.nextLine();
if (x.hasNext()){
listL.add(x.next());
} else {
listL.add("");
}
if (x.hasNext()){
listR.add(x.next());
} else {
listR.add("");
}
}
}
thanks in advance...
note = 1.hobby and name are separated by spaces
2.names will only have one word only
Instead of doing scanner.next(), you may want to do something like this:
Scanner scan = new Scanner(new File("D://practice.txt"));
ArrayList<String> names = new ArrayList<String>();
ArrayList<String> hobbies = new ArrayList<String>();
while(scan.hasNext()){
String curLine = scan.nextLine();
int indexOfHobby = curLine.indexOf(' ');
names.add(curLine.substring(0, indexOfHobby).trim());
hobbies.add(curLine.substring(indexOfHobby).trim());
}
One problem with this is that there is no relationship between the two ArrayLists, so you have to be sure to mind your indices as you iterate through. One way to fix this would be to add a Person class so that you can have name and hobby as attributes of Person, then have an ArrayList of Persons. That might look like this:
Class Person {
String name;
String hobby;
public Person(String name, String hobby){
this.name = name;
this.hobby= hobby;
}
// more methods here
}
Then, in your main class, you'd do this:
Scanner scan = new Scanner(new File("D://practice.txt"));
ArrayList<Person> people= new ArrayList<Person>();
while(scan.hasNext()){
String curLine = scan.nextLine();
int indexOfHobby = curLine.indexOf(' ');
people.add(new Person(curLine.substring(0, indexOfHobby).trim(), curLine.substring(indexOfHobby).trim() ));
}
Also consider using a Map<String,String> to store people with their hobby together instead of keeping two different structures:
Scanner scan = new Scanner(new File("D://practice.txt"));
Map<String,String> namesAndHobbies = new HashMap<String,String>();
while(scan.hasNext()){
String line = scan.nextLine();
int idx = line.indexOf(' ');
String name = line.substring(0, idx).trim();
String hobby = line.substring(idx).trim();
namesAndHobbies.put(name, hobby);
}
This will allow you to access people by name, so you can find out the hobby of a person by name.
Use namesAndHobbies.keySet() to get a collection of all names and namesAndHobbies.values() to get a collection of all hobbies.
Related
I have a CarModel class that has three fields: name, fuelEconomy, and gasTankSize.
class CarModel {
private String name;
private double fuelEconomy;
private double gasTankSize;
CarModel(String name, double fuelEconomy, double gasTankSize) {
this.name = name;
this.fuelEconomy = fuelEconomy;
this.gasTankSize = gasTankSize;
}
String getName() {
return name;
}
double getFuelEconomy() {
return fuelEconomy;
}
double getGasTankSize() {
return gasTankSize;
}
}
Given the input as a string of text separated by a new line:
MODEL Camry 6.5 58
MODEL Civic 7.5 52
FINISH
How can I create a new object every time the word MODEL is in the input, store the model in an array, use the following words as the data for those fields and end the program when FINISH is in the input?
Inside main method, try doing something like this (Using try with resources):
public static void main(String args[]){
String line;
List<CarModel> cars = new ArrayList<>();
try(Scanner sc = new Scanner(System.in)){
while(sc.hasNextLine()){
line = sc.nextLine();
String[] arr = line.split(" ");
if(arr[0].equalsIgnoreCase("Model")){
cars.add(new CarModel(arr[0], Double.parseDouble(arr[1]), Double.parseDouble(arr[2])));
}else if(arr[0].equalsIgnoreCase("Finish"){
break;
}
}
}catch(ArrayIndexOutOfBoundsException ex){
// do something here!
}catch(Exception ex){
// do something here as well!
}
}
I would use the String.split method. You pass a delimiter, in your case a space character, and then the method chops the string into pieces based on your provided delimeter. Getting the input into your program depends on where the input will be coming from, whether by file or terminal or some other source.
Once you've read a line of input, call String[] values = line.split(" ")
Again, how to read the input depends on where the input is coming from, which you haven't specified.
I have a program which reads some data under a file reader and then creates an instance of another class which models the data. Anyway that class works (has been tested with some hard coded values) but I now want to output the data of the instance of a Patient being read under the file reader but seem unable to.
Could anyone tell me where i'm going wrong.
You are not adding Patient instances to newPatient collection, that's why it's empty and you are not getting anything printed out. Add elements to queue:
while(scan.hasNextLine()){
String firstname = scan.nextLine();
String surname = scan.nextLine();
String illness = scan.nextLine();
int illnessSeverity = scan.nextInt();
String newLine = scan.nextLine();
newPatient.add(new Patient(firstname,surname,illness,illnessSeverity));
for (Patient newPatientData : newPatient) {
System.out.println(newPatientData);
}
You need to add data first to the Priority Queue. I think you missed that .
PriorityQueue<Patient> newPatient = new PriorityQueue<>();
File fileName = new File("patients.txt");
Scanner scan = null;
try {
scan = new Scanner(fileName);
while(scan.hasNextLine()){
String firstname = scan.nextLine();
String surname = scan.nextLine();
String illness = scan.nextLine();
int illnessSeverity = scan.nextInt();
String newLine = scan.nextLine();
Patient newP = new Patient(firstname,surname,illness,illnessSeverity);
newPatient.add(newP);
}
for (Patient newPatientData : newPatient) {
System.out.println(newPatientData);
}
} catch(Exception e) {
System.out.println("ERROR - file not found");
}
I want to get information from the user like last name, first name, and id number for example Smith, John 12345 and continue looping until the user enters "exit". Whenever I enter two inputs the first one gets wiped out and the second one is stored. Maybe I should be using a different approach then what I have...
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader input = new BufferedReader(reader);
String inputValues;
String person;
String lastname = "";
String firstname = "";
String id = "";
while(true){
inputValues = input.readLine();
person = inputValues.split("\\s+");
if(inputValues.equals("exit"){
break;
}
else {
lastname = person[0];
firstname = person[1];
id = person[2];
}
}
I know my program is wrong but this is what I have thus far. I do not know how to store multiple people to eventually print out their names and id at the end of this.
I hope I understand your problem correct: your problem is that you overwrite your old entries? To prevent that you have to use some kind of array or list.
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader input = new BufferedReader(reader);
String inputValues;
String[] person;
List<String> lastname = new ArrayList<String>();
List<String> firstname = new ArrayList<String>();
List<String> id = new ArrayList<String>();
while(true){
inputValues = input.readLine();
person = inputValues.split("\\s+");
if(inputValues.equals("exit")){
break;
}else{
lastname.add(person[0]);
firstname.add(person[1]);
id.add(person[2]);
}
}
for(int i=0; i<lastname.size(); i++)
System.out.println(firstname.get(i) +" "+ lastname.get(i) +" ("+ id.get(i) +")");
}
}
See here: https://ideone.com/l1TnF8
Just as kon has noted you need an array of strings for person, what is happening is that each time you input a new value the new one only replaces the old one since person is only a string occupying just one memory space.
what I have here is a set of three ArrayLists. An ArrayList of students which holds the name , surname , uid and degree scheme. Then I also have a list of modules and each module also holds an arraylist of student ID's for the students which are enrolled on that particular module.
What I'm trying to do is to link in the arraylist of students with the arraylist of the user ID's so the program would look at the ID's and compare them to the list which has all the student details and then write a combined report with the full student details and the modules which they are enrolled on.
I'm having my arraylists set up nicely, but I'm having difficulty accessing the inner arraylist with the ID's. It's quite tricky to explain but here is the code for my Application class that holds everything together, you can see how the ArrayLists are laid out.
import java.util.*;
import java.io.*;
public class Model {
private ArrayList<Student> students;
private ArrayList<Module> modules;
private Module moduleLink;
public Model(){
students = new ArrayList<Student>();
modules = new ArrayList<Module>();
}
public void runTests() throws FileNotFoundException{
System.out.println("Beginning program, the ArrayList of students will now be loaded");
loadStudents("studentlist.txt");
System.out.println("Load attempted, will now print off the list");
printStudents();
System.out.println("The module list will now be loaded and printed");
loadModules("moduleslist.txt");
printModules();
System.out.println("Modules printed, ArrayList assosciation will commence");
}
public void printStudents(){
for(Student s: students){
System.out.println(s.toString());
}
}
public void printModules(){
for(Module m: modules){
System.out.println(m.toString());
}
}
public void loadStudents(String fileName) throws FileNotFoundException{
Scanner infile =new Scanner(new InputStreamReader
(new FileInputStream(fileName)));
int num=infile.nextInt();infile.nextLine();
for (int i=0;i<num;i++) {
String u=infile.nextLine();
String s=infile.nextLine();
String n=infile.nextLine();
String c=infile.nextLine();
Student st = new Student(u,s,n,c);
students.add(st);
}
infile.close();
}
public void loadModules(String fileName) throws FileNotFoundException{
Scanner infile =new Scanner(new InputStreamReader
(new FileInputStream(fileName)));
int numModules = infile.nextInt();
infile.nextLine();
for (int i=0;i<numModules;i++){
String code = infile.nextLine();
int numStudents = infile.nextInt();
infile.nextLine();
ArrayList<Student> enrolledStudents = new ArrayList<Student>(numStudents);
for (int a=0;a<numStudents;a++){
String uid = infile.nextLine();
Student st = new Student(uid);
enrolledStudents.add(st);
}
Module m = new Module(code,enrolledStudents );
modules.add(m);
}
infile.close();
}
}
Any help would be very appreciated, thanks.
If you are looking for Student details, probably you should re-design your classes.
Student should be enrolled to a module. Hence, Student should have Module. And use a Map to retrieve students based on the id.
class Student {
String id;
List<Module> modules = new ArrayList<Module>();
}
loadStudents() would remain same except that you have to populate a Map of student id to Student objects you create in the loop.
loadModules() would then pick the student based on student id from the map and update the modules.
This would be the case where you need data based on Student.
I'm fairly new to programming and I recently wrote something to utilize a scanner class to fill an object array from a text file. Essentially, I can re-write this text file or add new info and won't have to change the code. I suppose my question is this: is there an easier/more preferred method to doing this? I'm trying to learn the coding nuances.
import java.io.*;
import java.util.*;
public class ImportTest {
public static void main(String[] args) throws IOException
{
Scanner s = null;
Scanner k = null;
ArrayList myList = new ArrayList<String>();
ArrayList myList2 = new ArrayList<String>();
ArrayList myList3 = new ArrayList<Student>();
try
{
s = new Scanner(new BufferedReader(new FileReader("testMe.txt")));
while (s.hasNext())
{
myList.add(s.nextLine());
}
}
finally
{
if (s != null)
{
s.close();
}
}
System.out.println("My List 1:");
for(int i=0; i<myList.size(); i++)
{
System.out.println(i+". "+myList.get(i));
}
for(int x=0; x<myList.size(); x++)
{
try
{
k = new Scanner(myList.get(x).toString());
while (k.hasNext())
{
myList2.add(k.next());
}
}
finally
{
if (k != null)
{
k.close();
}
}
String name;
int age;
double money;
name=myList2.get(0).toString();
age=Integer.parseInt(myList2.get(1).toString());
money=Double.parseDouble(myList2.get(2).toString());
Student myStudent=new Student(name, age, money);
myList3.add(myStudent);
myList2.clear();
}
System.out.println("Test of list object: ");
for(int i=0; i<myList3.size(); i++)
{
System.out.println(i+". "+myList3.get(i).toString());
}
}
}
I would read the file line by line and parse every line directly. This way you do not need 3 lists, 2 scanners and multiple iterations:
String line = "";
BufferedReader br = new BufferedReader(new FileReader("test.txt"));
ArrayList<Student> students = new ArrayList<Student>();
while( (line = br.readLine()) != null)
{
String[] tmp = line.split("\\s+"); //split line by spaces
//this needs bounds & error checking etc.
students.add(new Student(tmp[0], Integer.parseInt(tmp[1]), Double.parseDouble(tmp[2])));
}
In Java 7 you can use the new file functions to read all lines at once:
List<String> allLines = Files.readAllLines("test.txt", Charset.defaultCharset());
Do not forget to close the reader or use try-with-resources (since java 1.7)
Correct me if I am wrong, testMe.txt file contains Student information which are name, age, money, and you want read those values.
Best way to do it is you should serialize your Student objects into the the testMe.txt with the help of ObjectOutputStream. As well you can read those value using ObjectInputStream, so in this way you can able to get Student objects itself(no need to hnadle String).
In case you do want to serialize the data into file, you should store the data in some predefined format like as comma(,) or semi-colon(;) seperated.
For Example -
emp1, 24, 20000
emp emp2, 25, 24000
emp3, 26, 26000
In this case while reading the string you can split it with seperation character and get the actual information.
Code snippet:
List<Student> students = new ArrayList<Student>();
...
try(scanner = new Scanner(new BufferedReader(new FileReader("testMe.txt")))){
while (scanner.hasNext()){
String data[] = scanner.nextLine().split(",");
Student student = new Student(data[0],data[1],data[2]);
students.add(student);
}
}
Try-with-resource will automatically handle the resouce, you dont need to explicitly close it. This features available in java since 1.7.