My code is supposed to read a sequence until the empty line. I am stuck at storing the object in array at numItem and then increase numItem.
public static int readInput(Scanner myScanner, String[] input) {
boolean streamEnded = false;
int numItem = 0;
while (!streamEnded && myScanner.hasNext()) {
String name = myScanner.nextLine();
String id = myScanner.nextLine();
if (name.length() == 0 && id.length() == 0) {
streamEnded = true;
} else {
input[numItem] = name;
input[numItem] = id;
numItem++;
}
Person personTest = new Person(name, id);
persons[numItem]
}
return numItem;
}
}
A few things:
Put the numItem increment outside of the if/else statement. It should go at the end of your while loop after persons[numItem].
Not sure what this: persons[numItem] is supposed to do. If you mean to store the personTest object at that index it should be persons[numItem] = personTest;.
Unless you know you are only going to have 10 people created in your array, I would use an ArrayList, that way you could add as many Person objects as you need.
I didn't go through it line by line, those are just my general observations. I'm pretty sure your code won't compile as it is, especially with this: persons[numItem]. Hope this helps a bit.
I think you are looking for something like this,
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
List<Person> persons = new ArrayList<Person>();
while (myScanner.hasNext()) {
String inp = myScanner.nextLine();
if (inp.length() <= 0) {
break;
}
String[] parts = inp.split(" ");
persons.add(new Person(parts[0], parts[1]));
}
while (myScanner.hasNext()) {
String inp = myScanner.nextLine();
if (inp.length() <= 0) {
break;
}
String[] parts = inp.split(" ");
Person person = findPerson(persons, parts[0]);
person.changeBalance(Double.parseDouble(parts[1]));
System.out.println(person);
}
}
private static Person findPerson(List<Person> persons, String id) {
for (Person person : persons) {
if (person.getId().equals(id)) {
return person;
}
}
return new Person("", "");
}
Here I have used a ArrayList instead of array to make things easier. I have printed the person every time the balance changes. But, you can move it outside of the loop to match your output.
Related
How could I remove an object inside a Linkedlist. I have a class account with studentId and studentName. I enter the objects inside the list, but when I try to remove I do not know how to do it. Because every time you remove an element from the middle of the list it gets organized, meaning the indexes change. So how can I get the studentId attribute and remove the object inside the linkedList.
Sample:
LinkedList: Account{studentId = 1, studentName = nome1} = index = 0 ,
LinkedList: Account{studentId = 2, studentName = nome2} = index = 1 ,
LinkedList: Account{studentId = 3, studentName = nome3} = index = 2.
what I would like was for the user to insert the studentId that he wants to delete and I can do a code that searches and deletes that object.
public Account{
private int studentID;
private String StudentName;
}
public static void main(String[] args){
int accountNumber;
LinkedList<Account> linkedAccount = new LinkedList<>();
Account obj1;
System.out.println("Type the acc number: ");
accountNumber = in.nextInt();
obj1 = linkedAccount.remove(accountNumber);
System.out.println("The " + obj1 + " has been deleted");
}
Every time I delete an object from the middle it changes the index of the linkedList. Rearranging. So i do not know how to do it can you help me?
If you don't need to keep a reference to the object you remove, you can just
linkedAccount.removeIf(acc -> acc.getStudentID() == accountNumber);
If you want to keep a reference to the element you remove you can
for (Account acc : linkedAccount) {
if (acc.getStudentID() == accountNumber) {
obj1 = acc;
linkedAccount.remove(acc);
break;
}
}
// OR
for (int i = 0; i < linkedAccount.size(); i++) {
if (linkedAccount.get(i).getStudentID() == accountNumber) {
obj1 = linkedAccount.remove(i);
break;
}
}
Notice that in most case and basiclly an ArrayList is sufficient When to use LinkedList over ArrayList in Java?
Currently, you're using accountNumber as the index which is incorrect, instead loop over the list and find the index of the object and then remove:
for (int i = 0; i < linkedAccount.size(); i++) {
if (linkedAccount.get(i).getStudentID() == accountNumber) {
obj1 = linkedAccount.remove(i);
break;
}
}
Further, why are you using a LinkedList instead of an ArrayList? the latter is almost always favourable.
I think the best option is to search the account in the list by the studentID and then remove it.
public Account{
private int studentID;
private String StudentName;
public int getStudentID() {
return this.studentID;
}
}
public static void main(String[] args){
int accountNumber;
LinkedList<Account> linkedAccount = new LinkedList<>();
Account obj1;
System.out.println("Type the acc number: ");
accountNumber = in.nextInt();
for (int i = 0; i < linkedAccount.size(); i++) {
if (accountNumber == linkedAccount.get(i).getStudentID()) {
System.out.println("The student " + linkedAccount.get(i).getStudentID() + " has been deleted");
linkedAccount.remove(i);
break; // This is to exit for loop, but if you want to delete every instance in the list with this ID you can skip this break
}
}
}
i'm new to programming and i'd like to ask that why is it that in my code i do not need to use a return function in the constructor and method?
Also why is it that after using the yearPasses function age is increased by 3 and not 1?
Apology for the lengthy code
public class Person
{
private int age;
public Person(int initialAge)
{
// Add some more code to run some checks on initialAge
if (initialAge<0)
{
System.out.println("Age is not valid, setting age to 0.");
initialAge = 0;
age = initialAge;
}
else
{
age = initialAge;
}
}
public void amIOld()
{
if (age<13)
{
System.out.println("You are young.");
}
else if (age>=13 && age<18)
{
System.out.println("You are a teenager.");
}
else
{
System.out.println("You are old.");
}
}
public void yearPasses()
{
age = age + 1;
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
for (int i = 0; i < T; i++)
{
int age = sc.nextInt();
Person p = new Person(age);
p.amIOld();
for (int j = 0; j < 3; j++)
{
p.yearPasses();
}
p.amIOld();
System.out.println();
}
sc.close();
}
}
You don't need a return in the constructor because a constructor's job is to create an object. The new operator returns that object for you, so it doesn't need to be in the constructor itself.
Your other methods are declared with a return type of void, which means they don't return anything, so you don't need return statements in those either.
You're calling yearPasses in a loop that executes three times.
Constructors create the object, the new keyword is where the object is returned.
All your other methods are labelled as void, meaning they do not return anything.
You could add a return to your yearPasses method, that will return the new age if you want, however it depends on what you need it to do. (This is just an example of using the return)
I'm working on a project where I will tally a Student's choices and add them to a count array (still working on this part). For now, I'm trying to retrieve the choices that have been sent and added to a Student ArrayList in my Student class.
Student class:
public class Students {
private String name;
private ArrayList<Integer> choices = new ArrayList<Integer>();
public Students(){
name = " ";
}
public Students(String Name){
name = Name;
}
public void setName(String Name){
name = Name;
}
public String getName(){
return name;
}
public void addChoices(int Choices){
choices.add(Choices);
}
public ArrayList<Integer> getChoices(){
return choices;
}
Here is my main driver class:
public class P1Driver {
public static void main(String[] args) throws IOException{
ArrayList<Students> students = new ArrayList<Students>();
String[] choices = new String[100];
int[] count;
Scanner scan1 = new Scanner(new File("Choices.txt"));
Scanner scan2 = new Scanner(new File("EitherOr.csv"));
// Scan the first file.
int choicesIndex = 0;
while(scan1.hasNextLine()){
String line = scan1.nextLine();
choices[choicesIndex] = line;
choicesIndex++;
}
scan1.close();
// Scan the second file.
int studentIndex = 0;
while(scan2.hasNextLine()){
String line = scan2.nextLine();
String [] splits = line.split(",");
students.add(new Students(splits[0]));
for(int i = 1; i < splits.length; i++){
students.get(studentIndex).addChoices(Integer.parseInt(splits[i]));
}
studentIndex++;
}
scan2.close();
// Instantiate and add to the count array.
int countIndex = 0;
for(int i = 0; i < students.size(); i++){
if(students.get(i).getChoices(i) == -1){
}
}
The last part is where I am now. It's nowhere near done obviously (I'm right in the middle of it) but during my construction of a for loop to get the choices from the students, I'm getting an error that says, "The method getChoices() in the type Students is not applicable for the arguments (int)." Can someone explain what this means, where me error is, and possibly how to fix it? Thanks all.
getChoices(int i) is not a method you've defined.
if(students.get(i).getChoices(i) == -1){
}
getChoices() returns a list, so you can just use the get method on the list:
if(students.get(i).getChoices().get(i) == -1){
}
Alternatively, make a getChoice method:
public Integer getChoice(int i){
return choices.get(i);
}
Have you tried getChoices()[i] instead of getChoices(i)
I want to create a program which displays current staff in the ArrayList before asking the user for input of a payroll number they'd like to remove. User then should input the payroll number of one of the three staff members and press enter. Upon pressing enter, the program should remove that particular staff member from the array list and display the entire list again (missing out the staff member they've deleted obviously). If the user no longer wishes to remove any payroll numbers, the payroll number entry should be 0 and should then display the contents of the list again.
The problem I'm having is with the remove part.
I've been recommended of two ways of achieving this:
This 'search' method should return either the position within the ArrayList (so that remove(<index>) may be used) or a reference to the object (so that remove(<objectRef>) may be used). If the staff member is not found, then the search method should return -1 (if remove(<index>) is being used) or null (if remove(<objectRef>) is being used).
However I am not sure how to implement this in Java.
Here is my file structure:
ArrayListTest.java
import java.util.*;
import personnelPackage.Personnel;
public class ArrayListTest
{
static Scanner keyboard = new Scanner(System.in);
public static void main(String[] args)
{
long searchQuery;
ArrayList<Personnel> staffList = new ArrayList<Personnel>();
Personnel[] staff =
{new Personnel(123456,"Smith","John"),
new Personnel(234567,"Jones","Sally Ann"),
new Personnel(999999,"Black","James Paul")};
for (Personnel person:staff)
staffList.add(person);
do
{
showDisplay(staffList);
System.out.print("\nPlease enter a payroll number to search: ");
searchQuery = keyboard.nextLong();
searchForPayrollNumber(staffList, searchQuery);
}while(!(searchQuery == 0));
}
private static void showDisplay(ArrayList<Personnel> staffList)
{
System.out.print("\n------------- CURRENT STAFF LIST -------------\n");
for (Personnel person : staffList)
{
System.out.println("Payroll number: " + person.getPayNum());
System.out.println("Surname: " + person.getSurname());
System.out.println("First name(s): " + person.getFirstNames() + "\n");
}
}
public static void searchForPayrollNumber(ArrayList<Personnel> staffList, long searchQuery)
{
long index = staffList.indexOf(searchQuery);;
for (Personnel person: staffList)
{
if (person.getPayNum() == searchQuery)
{
System.out.print("\n------------- Staff member found and removed! -------------");
System.out.println("\n\nFirst Name(s): " + person.getFirstNames());
System.out.println("\nSurname: " + person.getSurname());
System.out.print("\n-----------------------------------------------");
staffList.remove(index);
return;
}
}
System.out.print("\n------------- No staff members found. Program terminated -------------");
return;
}
}
Personnel.java (in its own package named personnelPackage)
package personnelPackage;
public class Personnel
{
private long payrollNum;
private String surname;
private String firstNames;
public Personnel(long payrollNum, String surname, String firstNames)
{
this.payrollNum = payrollNum;
this.surname = surname;
this.firstNames = firstNames;
}
public long getPayNum()
{
return payrollNum;
}
public String getSurname()
{
return surname;
}
public String getFirstNames()
{
return firstNames;
}
public void setSurname(String newName)
{
surname = newName;
}
}
Consider using Iterator for search and removal:
Iterator<Personnel> i = staffList.iterator();
while (i.hasNext()) {
Personnel p = i.next();
if (p.getPayNum() == searchQuery) {
// print message
i.remove();
return p;
}
}
return null;
If using List#remove() is strictly required, return found personnel p and call if (p != null) staffList.remove(p):
public static Personnel searchByPayNum(List<Personnel> ps, long num) {
for (Personnel p : ps) {
if (p.getPayNum() == num)
return p;
}
return null;
}
And in caller code:
Personnel p = searchByPayNum(staffList, query);
if (p != null) {
// log
staffList.remove(p);
}
public static long searchForPayrollNumber(ArrayList<Personnel> staffList, long searchQuery) {
//long index = staffList.indexOf(searchQuery);
for(int i = 0; i < staffList.size(); i++) {
if (staffList.get(i).getPayNum() == searchQuery) {
System.out.print("\n------------- Staff member found and removed! -------------");
System.out.println("\n\nFirst Name(s): " + staffList.get(i).getFirstNames());
System.out.println("\nSurname: " + staffList.get(i).getSurname());
System.out.print("\n-----------------------------------------------");
//staffList.remove(i);
return i;
}
}
System.out.print("\n------------- No staff members found. Program terminated -------------");
return -1;
}
Your search method shouldn't return void. It should return int or long instead,
public static long searchForPayrollNumber(ArrayList<Personnel> staffList, long searchQuery)
{
int index = -1;
for (int i = 0; i < staffList.size(); i++){
if(staffList.get(i).getPayNum() == searchQuery){
index = i;
System.out.print("\n------------- Found Staff member at position " + index + " in the list");
break;
}
}
if (index != -1){
staffList.remove(index);
System.out.print("\n------------- Removed the staff member");
}
return index;
}
Last approach returned the index. Now when you want to return the object:
public static long searchForPayrollNumber(ArrayList<Personnel> staffList, long searchQuery)
{
Personnel p = null;
for (int i = 0; i < staffList.size(); i++){
if(staffList.get(i).getPayNum() == searchQuery){
p = staffList.get(i);
break;
}
}
staffList.remove(p);
return p;
}
You must know that after removing it from the list, It will shift any subsequent elements to the left (subtracts one from their indices).
Also, just a suggestion:
Instead of
Personnel[] staff =
{new Personnel(123456,"Smith","John"),
new Personnel(234567,"Jones","Sally Ann"),
new Personnel(999999,"Black","James Paul")};
Why not
staffList.add(new Personnel(123456,"Smith","John"));
staffList.add(new Personnel(234567,"Jones","Sally Ann"));
staffList.add(new Personnel(999999,"Black","James Paul"));
This is just an advice. Since searching and removing are your primary goals, ArrayList is not the right collection to use.
Create a Hashmap with ID as key and Personnel object as value. This will help in identifying the Personnel in O(1) time and removal as well.
ArrayList should be used only when you know the index to read value. It then does that in O(1). If not, it is O(n) and not as efficient as HashMap.
The code I've currently created stores the first line of the text file, creates a new Vehicle object and puts it in the array at the first position of null, and stores the same line in every null value in the array. I need it to be able to:
Store the contents of the first line, then store a new Vehicle object in the first place in the array that is null. Then repeat until there are no more lines.
I believe it is a problem with my for loop.
Note - I am required to use Array instead of ArrayList
public void addVehicle(Vehicle[] Honda) throws FileNotFoundException
{
if(canAddVehicle() == true)
{
for(int i = 0; i < vehicles.length; i++)
{
if(vehicles[i] == null)
{
Scanner reader = new Scanner(file);
Honda[i] = new Vehicle();
Honda[i].readRecord(reader);
vehicles[i] = Honda[i];
reader.close();
}
}
System.out.println("Vehicle Added!");
}
else
{
System.out.println("You can not add more than 4 vehicles.");
}
}
Vehicle class:
public void readRecord(Scanner reader)
{
setMake(reader.next());
setModel(reader.next());
setYear(reader.nextInt());
setvin(reader.next());
setValue(reader.nextDouble());
setMilesDriven(reader.nextInt());
setLastOilChange(reader.nextInt());
}
Data file:
Hyundai Sonata 2010 ABC236347NM2N2NW2 18455.34 8765 7567
Chevy Blazer 1998 1234H32343LMN3423 29556.65 38559 38559
//EDIT\
Constraits: I cannot create any new public methods or constructors, and I cannot have any additional class level data
You're looping within the readRecord method, even though that's meant to only store one object, isn't it?
It's possible that you can just remove the while loop - although that then relies on the addVehicle caller knowing how many entries are in the file.
It seems more likely that you should have a method to read everything from a file, populating a List<Vehicle> and returning it. For example:
public List<Vehicle> readVehicles(String file)
{
Scanner reader = new Scanner(file);
List<Vehicle> vehicles = new ArrayList<Vehicle>();
try
{
while (reader.hasNextLine())
{
vehicles.add(Vehicle.readFromScanner(reader));
}
}
finally
{
reader.close();
}
return vehicles;
}
// In vehicle
public static Vehicle readFromScanner(Scanner scanner)
{
String make = reader.next();
String model = reader.next();
int year = reader.nextInt();
String vin = reader.next();
// Don't use double for currency values
BigDecimal value = reader.nextBigDecimal();
int milesDriven = reader.nextInt();
// Shouldn't this be some sort of date type?
int lastOilChange = reader.nextInt();
// I'll assume you have a constructor like this
return new Vehicle(make, model, year, vin, value, milesDriven,
lastOilChange);
}
Found my solution!
public boolean addVehicle(Vehicle[] Honda) throws FileNotFoundException
{
boolean found = false;
int position = 0;
if(canAddVehicle() == true)
{
for(int i = 0; i < vehicles.length && !found; i++)
{
if(vehicles[i] == null)
{
position = i;
found = true;
}
}
Scanner reader = new Scanner(file);
while(reader.hasNext())
{
Honda[position] = new Vehicle();
Honda[position].readRecord(reader);
vehicles[position] = Honda[position];
position++;
}
reader.close();
return true;
}
return false;
}