For Each Loaded Line (From a File with Mixed Strings and Integers), Create a Person Type Object - java

I'm working on a program that reads data (of type string and int) from a file. Then, it creates an object named Person and puts it into an ArrayList.
For this task I am using the Scanner.
With methods like next(), nextLine(), I'm able to read/parse the data and create Person; however, I don't really know how to handle the situation when the input will have mixed persons.
My task says that there could be 2 options (input can include):
name, yearOfBirth
or, name,yearOfBirth,carName and Color (r,g,b)
Option 1: With next(), nextLine(), I know (more or less) how to do it:
John 1980 Mercedes 255 255 102
In the ArrayList, John should look like [John 1980 Mercedes 255 255 102]
but I do not know what to do when input will be for ex.:
Option 2:
John 1980 Mercedes 255 255 102
Mary 1997
Alice 1993 Skoda 0 127 153
In this situation, the program should recognize that the Mary do not have a car and in the ArrayList. Mary will look like [Mary 1997 null]
So, class Person has 2 constructors:
public Person(String name, int yearOfBirth, Car car)
and
public Person(String name, int yearOfBirth)
and Overrided toString() method.
Main:
public class Main {
public static void main(String[] args) {
ArrayList<Person> list = new ArrayList<Person>();
File file = new File("file.txt");
Scanner sc;
try {
sc = new Scanner(file);
while (sc.hasNext()) {
// here, i think, i should create an Person and add 'him/her' to ArrayList<Person>
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println(list);
System.out.println("End of Program.");
}
}
Person class:
public class Person {
String name;
int yearOfBirth;
Car car;
public Person(String name, int yearOfBirth, Car car) {
super();
this.name = name;
this.yearOfBirth = yearOfBirth;
this.car = car;
}
public Person(String name, int yearOfBirth) {
super();
this.name = name;
this.yearOfBirth = yearOfBirth;
}
#Override
public String toString() {
return name + " " + yearOfBirth + " " + car;
}
Car class:
public class Car {
String nameCar;
Color color;
int r, g, b;
public Car(String nameCar, int r, int g, int b) {
this.nameCar = nameCar;
this.color = new Color(r, g, b);
this.r = r;
this.g = g;
this.b = b;
}
#Override
public String toString() {
return nameCar + " " + r + " " + g + " " + b;
}
}
Input should includeArrayList of Persons

for this example you can read the whole line with your scanner, using sc.nextLine() (also use sc.hasNextLine() on the while loop). Then you can get the fields on a string array like this:
String line = sc.nextLine();
String[] fields = line.split(" ");
//separate all the "words" in the string by a space character
After doing this you can test if the length of the fields array is 6 =, meaning that the person has a car or only 2.

Related

Callling method from another class + sorting

I am working on a program where I have to call a method that prompts the user to enter data from another class. This program should print the name, age, address, and gender of customers. However, I am having problem to call a method for inputting each customer information.
Also, I have to create a method that sort the ages of customers in ascending order. So the program prints out all info based on the order of age from the (youngest customer) to the (oldest one). I am not sure how to create a method that will only sort the ages of customers without sorting the name, address, and gender. I would really appreciate any feedback or comments!
This is what I have so far.
import java.util.Scanner;
public class Customer1 {
public static void main(String [] args){
Scanner input = new Scanner(System.in);
int x;
System.out.print("Total number of customers: ");
x = input.nextInt();
Customer [] person = new Customer[x];
System.out.println("Name" + " " + "Age"+ " " + "Address" + " " + "Gender");
for(int i = 0; i < person.length; i++){
System.out.println(person.toString());
}
}
}
class Customer{
String name;
int age;
String address;
String gender;
public Customer(String newName, int newAge, String newAddress, String newGender){
name = newName;
age = newAge;
address = newAddress;
gender = newGender;
}
public void data(Customer [] person){
Scanner input = new Scanner(System.in);
for(int i = 0; i < person.length; i++){
System.out.print("Name: ");
name= input.toString();
System.out.print("Age: ");
age = input.nextInt();
System.out.print("Address: ");
address= input.toString();
System.out.print("Gender: ");
gender = input.toString();
}
}
/*This is the "uncompleted" method that I tried to create in order to sort the ages of customers.
But I don't know how to use it in order to sort only the ages*/
public void sort(Customer [] person){
double temp;
for(int a = 0; a < (person.length - 1); a++){
for( int b = (a + 1); b < person.length; b++){
if(person[a] > person[b]){
temp = person[a];
person[a] = person[b];
person[b] = temp;
}
}
}
}
public String toString(){
String result;
result = name + " " + age + " " + address + " " + gender;
return result;
}
}
Try out the below code which might solve this question .. I have included the methods suggested in the previous replies and created this program ..
import java.util.Scanner;
public class ReadSortCustomerData {
public static void main(String [] args) {
int numberOfCustomers;
Scanner input = new Scanner(System.in);
System.out.print("Enter the total number of customers: ");
numberOfCustomers = input.nextInt();
CustomerData [] customer = new CustomerData[numberOfCustomers];
for(int countCustomer=0 ; countCustomer < numberOfCustomers; countCustomer++) {
System.out.println("Enter the name of the"+(countCustomer+1)+"customer");
customer[countCustomer].setName(input.next());
System.out.println("Enter the age of the"+(countCustomer+1)+"customer");
customer[countCustomer].setAge(input.nextInt());
System.out.println("Enter the gender of the"+(countCustomer+1)+"customer");
customer[countCustomer].setGender(input.next());
System.out.println("Enter the address of the"+(countCustomer+1)+"customer");
customer[countCustomer].setGender(input.next());
}
}
public CustomerData[] sortCustomerData(CustomerData[] customers) {
for (int i=0;i<customers.length;i++) {
for(int j=i+1;j<customers.length;j++) {
if(ageCompare(customers[i], customers[j])==1) {
CustomerData tempCustomer = new CustomerData();
tempCustomer = customers[i];
customers[i] = customers[j];
customers[j] = tempCustomer;
}
}
}
return customers;
}
public int ageCompare(CustomerData a, CustomerData b)
{
return a.getAge() < b.getAge() ? -1 : a.getAge() == b.getAge() ? 0 : 1;
}
}
import java.util.Comparator;
import java.util.Scanner;
public class CustomerData {
private String name;
private int age;
private String address;
private String gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
This might need some tweaking during the run time but it should give you a good start.
I recommend you to rethink a little bit your code and take a look at the following tips
Using Comparator or Comparable interfaces
These interfaces helps you out with the sorting of your collections, lists and etc, i.e, the Comparator interface allows you to impose ordering to your collection with a hand from Collections.sort and Arrays.sort operations.
You must define the implementation of you Comparator, based on you target class(Person), then define the ordering by any field you want:
class PersonSort implements Comparator<Person>{
#Override
public int compare(Person p1, Person p2) {
return p1.getAge() - p2.getAge();
}}
Then you are allowed to force its ordering via Arrays.sort(T[], Comparator):
Arrays.sort(yourArray, new PersonSort());
I also recommend you to take a look at Oracle's Collection Framework Tutorial. You will find information over ordering, implementations and etc.
1. Getting the data that you require
Currently in your Customer1 class you're accepting an x amount of customers provided from user input. Following which you create an array for x Customer objects. You do not currently populate the array with any data.
Customer[] person = new Customer[x];
After this line you could then do a for loop with the following:
String name;
int age;
String address;
String gender;
for( int i = 0; i < person.length; i++ )
{
System.out.print("Name: ");
name = input.next();
System.out.print("Age: ");
age = input.nextInt();
System.out.print("Address: ");
address= input.next();
System.out.print("Gender: ");
gender = input.next();
person[i] = new Customer( name, age, address, gender );
}
A cavaet must be observed in your code, you've put input.toString(). This will give you a string representation of your scanner, not the input. input.next() will give you next input as a string.
2.Sorting
I would advise looking at the comparator documentation. Have a comparator object that implements comparator with Customer as the type parameter. Override the compare to check against each Customer object's age.
Example would be:
class CustomerComparator implements Comparator<Customer>
{
#Override
public int compare(Customer a, Customer b)
{
return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;
}
}
You should look into making the variables name, age, address gender private and using getX() methods (getters/setters).

Objects in Java is printing out junk

My program is a simple program that involves the use of objects. There are no errors the only problem is that my program is printing out junk. After it asked the user for it name, age , and gender.
Down below are two sets of programs. The first one is the object or the skeleton of the person. The second one is the print that asks for the user name age gender and prints it out.
public class Person
{
private String name;
private int age,personality,appearance;
private String gender;
//constructor method. only use it once
public Person(String nm, int ag,String gend) {
name=nm;
age=ag;
gend=gender;
personality=1+(int)(Math.random()*10);
appearance=1+(int)(Math.random()*10);
}
//accessor created
public String getName() {
return name;
}
public String getGend() {
return gender;
}
public int getInt() {
return age;
}
//mutator method. When using "void" NO RETURN TYPE
public void setName (String nm) {
name=nm;
}
public void setAge (int ag) {
age=ag;
}
public void setGender (String gend)
{
gender=gend;
}
//helper method (kind of like print but not really printing
public String toString () {
String orange ="";
orange ="Name "+name+"/n";
orange +="age"+age+"/n";
orange +="Gender: "+gender"/n";
orange +="Personality "+personality+"/n";
orange +="Apperance "+appearance+"/n";
return orange;
}
}
2)
import java .util.Scanner;
public class PersonTester {
public static void main (String []args){
// calling person
Person person;
String name="", gender ="";
int age =0;
Scanner input =new Scanner(System.in);
System.out.println ("What is your name");
name =input.nextLine();
System.out.println("What your age?");
age=input.nextInt();
input.nextLine();
System.out.println ("What is your gender");
gender =input.nextLine();
person=new Person (name,age,gender);
System.out.println(person);
}
We are learning bout basic objects for example we only learned about private variables,constructor, accessor, mutator, and helper methods.
In your toString() you have two errors. You need to use a + between gender"/n" and you need to use \n if you want a newline.
public String toString () {
return "Name " + name + "\n" +
"Age" + age + "\n" +
"Gender: " + gender + "\n" +
"Personality " + personality + "\n" +
"Appearance " + appearance + "\n";
}
If the problem is the gender is not printed out properly, the problem is in your constructor. You are passing in gend, but not saving it. Instead you overwrite the argument with the gender member variable:
public Person(String nm, int ag,String gend)
{
name=nm;
age=ag;
gend=gender;
You wanted:
gender = gend;

Trying to create a program that uses a Search Binary Tree to keep track of students- Java

I am creating a program that uses a Search Binary Tree to keep track of students that get added and deleted from a list. The program reads a text file that contains certain a command (add, delete, calculate average,etc) followed by the student name, age, and gender. For example, the first line of the text file would be: E Jake 14 M. E would stand for enroll(add).
I'm having issues both conceptually and coding wise.
I have a queue class, a queueLL class that implements the queue class, I have a camper class that returns name, age, and gender, and compares each student name, and lastly I have my search binary tree class.
The issue is in the main class:
import java.io.*;
import java.util.Scanner;
// delcaring some variables
public class CampPosanivee {
static String name;
static String age;
static String gender;
static Camper camper = null;
static double numkids;
QueueLL q = new QueueLL();
// creating a method to calculate averages
static double avgkids(Camper[] campers) {
double sum = 0;
for (int i = 0; i < campers.length; i++)
sum += campers[i].getNumKids();
if (campers.length == 0)
return 0;
return sum / campers.length;
}
public static void main(String[] args) throws IOException {
Camper c1 = new Camper("Kanga", "26", "F");
Camper c2 = new Camper("Tigger", "28", "M");
Camper c3 = new Camper("Pooh", "31", "M");
Camper c4 = new Camper("Rabbit", "30", "M");
Camper c5 = new Camper("Eeyore", "36", "M");
Scanner input = new Scanner(System.in);
System.out.print("Enter the name of File:");
String filename = input.next();
System.out.println();
FileReader inFile = new FileReader(filename);
Scanner sFile = new Scanner(inFile);
String lineOfData;
boolean q = true;
while (q && sFile.hasNext()) {
lineOfData = sFile.nextLine();
if (lineOfData.substring(0, 1).equalsIgnoreCase("h")) {
System.out.println("How to use this program:");
System.out.println("Type E to enroll a new camper");
System.out.println("Type W to withdraw a camper");
System.out.println("Type D to display age and gender of camper");
System.out.println("Type A to print average age of campers");
System.out.println("Type L to list all campers name in alphabetical order");
System.out.println("Type S to print the number of boys and girls camper");
System.out.println("Type P to list all camper names in preorder");
System.out.println("Type Q to quit program");
} else if (lineOfData.substring(0, 1).equalsIgnoreCase("e")) {
Scanner file = new Scanner(
new FileReader("data.txt"));
int n;
n = file.nextInt();
BST tree = new BST();
for (int i = 0; n < i; i++) {
Camper x = new Camper(file);
System.out.println(x);
tree.insert(x);
}
}
}
}
I don't think my implementation is correct and I am hitting a wall in terms of trying to finish the code. I get errors of trying pass the file argument in Camper
Camper x = new Camper(file);
The values define were 3 strings in my Camper Class file (name, age, gender). Any Help would be appreciated!
Edit Code for Camper:
public class Camper implements Comparable<Camper> {
private String name;
private String age;
private String gender;
private double numKids;
public Camper (String n, String a,String g){
name = n;
age = a;
gender = g;
}
public String getName()
{
return name;
}
public String getAge()
{
return age;
}
public String getGender()
{
return gender;
}
public double getnumKids()
{
return numKids;
}
public int compareTo(Camper other)
{
if (getName().compareTo(other.getName()) > 0)
{
return 1;
}
else if (getName().compareTo(other.getName()) < 0 )
{
return -1;
}
else
return 0;
}
}
Sorry for the late reply.
First off, they're called Binary Search Trees, not Search Binary Trees. :P
As for the actual error, you only have one constructor in the Camper class, and it takes three Strings - you're trying to pass it a file. It's not going to be able to guess how to parse that file and get the right three strings - you either need to do that in the calling code, or write another constructor that can do file handling.

java user input for Array - split by space

All,
Below code is working fine with the ArrayList. could you please help me on how to get user input for name gender and amountSpent (array size [4]), then split it by spaces so that it will have String, String and double.
Also, How to display the result of only the customer who has higher amount Spent then the other Customers.
thank you in advance!
Regards,
Viku
import java.util.Comparator;
public class Customer implements Comparable <Customer>{
public String name,gender;
public double amountSpent;
public Customer(String name, String gender, double amountSpent) {
super();
this.name = name;
this.gender = gender;
this.amountSpent = amountSpent;
}
public String getCustomername() {
return name;
}
public void setCoustomername(String name) {
this.name = name;
}
public String getgender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public double getamountSpent() {
return amountSpent;
}
public void setamountSpent(double amountSpent) {
this.amountSpent = amountSpent;
}
public static Comparator <Customer> CustomerNameComparator = new Comparator<Customer>() {
public int compare(Customer c1, Customer c2) {
String custName1 = c1.getCustomername().toUpperCase();
String custName2 = c2.getCustomername().toUpperCase();
//ascending order
//return custName1.compareTo(custName2);
//descending order
return custName2.compareTo(custName1);
}
};
public static Comparator <Customer> CustomerAmountSpentComparator = new Comparator<Customer>() {
public int compare(Customer aS1, Customer aS2) {
int custamtspent1 = (int) aS1.getamountSpent();
int custamtSpent2 = (int) aS2.getamountSpent();
//ascending order sort
// return custamtspent1 - custamtSpent2;
//descending order sort
return custamtSpent2 - custamtspent1;
}
};
#Override
public int compareTo(Customer o) {
return 0;
}
#Override
public String toString() {
return " Customer Name : " + name + ", Gender : " + gender + ", Amount Spent : " + amountSpent + "";
}
}
and Main Program:
import java.util.ArrayList;
import java.util.Collections;
public class MainProg {
public static void main(String args[]){
String nL = System.lineSeparator();
try {
ArrayList<Customer> arraylist = new ArrayList<Customer> ();
arraylist.add(new Customer ("Louis","Male", 4567.76));
arraylist.add(new Customer ("Daniela","Female", 7653.67));
arraylist.add(new Customer ("Jenny","Female", 3476.98));
arraylist.add(new Customer ("Arijit","Male", 9876.44));
System.out.println("Customer Name Decending Sort: " + nL);
Collections.sort(arraylist, Customer.CustomerNameComparator);
for (Customer str: arraylist) {
System.out.println(str);
}
System.out.println(nL + "Custmer Amount Spent [Hight to Low] Sorting: " + nL);
Collections.sort(arraylist, Customer.CustomerAmountSpentComparator);
for (Customer str: arraylist){
System.out.println(str);
}
System.out.println(nL + "Highest Amount Spent Custmer Detail: " + nL);
}
catch (Exception e){
System.out.println("Error: " + e);
}
finally {
System.out.println(nL + "Report Completed!");
}
}
}
OPTION 1 (suggested):
If the user is to input the data, why do you need to split it up? Just do as follows:
System.out.println("Name:");
name = scn.nextLine();
System.out.println("Gender:");
gender = scn.nextLine():
System.out.println("Amt:");
amt = scn.nextDouble();
Customer c1 = new Customer (name,gender, amt);
OPTION 2:
Alternatively, if you want user to input everything in one single line (separated by spaces), just do this:
System.out.println("Input name, gender, amt:");
name = scn.next();
gender = scn.next():
amt = scn.next();
Customer c1 = new Customer (name,gender, amt);
PROGRAM OUTPUT: Input name, gender, amt: John Male 33.50
OPTION 3 (requested by you):
Lastly if you still insist of doing a split by space, and you want to accept the user input in one string separated by spaces:
System.out.println("Input name, gender, amt:");
input = scn.nextLine();
String[] token = input.split(" ");
String name = token[0];
String gender = token[1];
double amt = Double.parseDouble(token[2]);
Customer c1 = new Customer (name,gender, amt);
PROGRAM OUTPUT: Input name, gender, amt: John Male 33.50
For your first question (if I have understood right), you want to take a user input as string:
Dave Male 123.45
and then parse this into two Strings and a double. Scanner as you mentioned is a good way to start, then try
String[] parts = input.split(" ");
double value = Double.parseDouble(parts[2]);
This will split the input into a String array of size 3 and convert the third element to a double object, that will allow you to create Customers.
For your second question, you can use a simple approach by iterating over all Customers in the ArrayList, and store the current customer with the highest amount. Replacing the customer if you find a bigger spender.
Viku, try moving
arraylist.add(new Customer(name,gender,amountSpent));
to within the
do{
...
arraylist.add(new Customer(name,gender,amountSpent));
} while(choice.equalsIgnoreCase("Yes"));
As the code is now, the arrayList.add is only executed after the loop -> only last entry.

Storing details from an input and displaying all the details with each new input. (Java)

I have a problem with figuring out how to approach this code. I am trying to prompt the user for details of a person (such as name, age and telephone number) and then output all person information. Whenever another person's information is inputted, the information of the person before hand as well as the current one is outputted.
Should look like this:
My Input: Adam, 25, 12345678, France
Output: Adam, 25, 12345678, France
My Input Second time: Bob, 22, 12345678, Australia
Output second time:
Adam, 25, 12345678, France
Bob, 22, 12345678, Australia
And so forth say 10 times which would create the table the tenth time with all details.
Any ideas on how I can do the whole create the table each time with more details? I've tried this to store variables but maybe looping an array is better? I'm new to Java as I've only picked it up recently. Any examples would be much appreciated. Thanks a heap!
Scanner scan = new Scanner(System.in);
scan.useDelimiter(",");
String sName = scan.next();
System.out.println(header);
String sLast = scan.next();
double sData1 = scan.nextDouble();
double sData2 = scan.nextDouble();
double sData3 = scan.nextDouble();
int sData4 = scan.nextInt();
Will fully check back when I get back on my computer. Thanks for the quick responses.
I think one of the best ways to approach this is to possibly create a person class and just add each person into a list, printing the entire list after every entry. You'll find it easiest to creat a Person class and implement a toString() method for it:
public class TestCode {
public static void main (String args []) {
Scanner input = new Scanner(System.in);
List<Person> peopleList = new ArrayList<Person>();
for(int i = 0; i < 10; i++){
System.out.println("enter info: ");
String name = input.next();
String age = input.next();
String phone = input.next();
String location = input.next();
peopleList.add(new Person(name, Integer.parseInt(age), Integer.parseInt(phone), location));
for(Person p: peopleList)
System.out.println(p.toString());
}
}
}
class Person{
String name;
int age;
int phoneNumber;
String location;
Person(String n, int a, int p, String l){
this.name = n;
this.age = a;
this.phoneNumber = p;
this.location = l;
}
public String toString(){
return(name + " " + age + " " + phoneNumber + " " + location);
}
}
Something like this, although this example does not include removing the commas from your input. You should handle removing commas from the input before storing the values into the People class if you choose to take this route.
Step 1. Create a class to hold the data about a person, with final fields, a suitable constructor and a toString() method:
public class Person {
final String name, country;
final int age, phone;
public Person(String name, int age, int phone, String country) {
this.name = name;
this.age = age;
this.phone = phone;
this.country = country;
}
public String toString() {
return name + ", " + age + ", " + phone + ", " + country;
}
// getters omitted for brevity
}
Step 2: Create a List of these things:
List<Person> people = new ArrayList<Person>();
Step 3: Scan in the 4 individual values then create a person them then add it to the list:
String name = scanner.next(); // etc for the other values
Person person = new Person(name, age, phone, country);
people.add(person);
When you are ready to print:
for (Person person : people) {
System.out.println(person);
}
You can use scan.nextLine() to get each person's information, then use a List to store all the person information. At last, print all the person information that are stored in the List.
In this way, you can input one person's information at one time, such as, input Adam, 25, 12345678, France in console.
Below is an example:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
List<String> personInformation = new ArrayList<String>();
String line = null;
while (!"exit".equals(line = scan.nextLine())) {
personInformation.add(line);
printPersonInformation(personInformation);
}
}
private static void printPersonInformation(List<String> personInformation) {
System.out
.println("All the person information we have now is as follows:");
for (String personInfo : personInformation) {
System.out.println(personInfo);
}
}
You could use two scanners, one to separate the lines, and another to split by commas, then build the data you are scanning as a list of lists, and then iterate over it to print it out. something like this:
private static void processRecords() throws FileNotFoundException
{
List<List<Object>> recordList = new ArrayList<List<Object>>();
// scan data line by line
Scanner scanner = new Scanner(new File("/tmp/foo.txt"));
while(scanner.hasNextLine())
{
List<Object> record = new ArrayList<Object>();
String line = scanner.nextLine();
//remove all spaces, since nextDouble and nextInt
//will choke on them:
line = line.replaceAll(" ", "");
//create a scanner just for this line
Scanner recordScanner = new Scanner(line);
recordScanner.useDelimiter(",");
String sData1 = recordScanner.next();
double sData2 = recordScanner.nextDouble();
double sData3 = recordScanner.nextDouble();
String sData4 = recordScanner.next();
record.add(sData1);
record.add(sData2);
record.add(sData3);
record.add(sData4);
// add the record to the list.
recordList.add(record);
//print it out
printHeader(recordList);
}
}
private static void printHeader(List<List<Object>> recordList)
{
//print it out
for (List<Object> recordToPrint : recordList)
{
for (Object objToPrint : recordToPrint)
{
//print your records.
System.out.print(objToPrint);
System.out.print(",");
}
System.out.println();
}
}
Note: I have changed the code to match your data - the code sample you supply doesn't quite match the data you gave.

Resources