How to save user choice into new array list - java

I’m sure I wasn’t clear enough in the title, clarifying everything here. I have a passenger booking a flight, I want to make a list in which the flights booked by the passenger will be stored.
This is the part of the code where the passenger completes the reservation, how do I make a new list and add a booked flight in it
#Override
public void payingFirstClassWithoutPromoCode(ArrayList<Flight> flightsList) {
System.out.println("Confirm buying ticket: (yes or no)");
String confirmation = scanner.nextLine();
if (confirmation.equalsIgnoreCase("yes")) {
if (selectedPassenger.getBalance() >= selectedFlight.getPriceForFirstClass()) {
System.out.println("Successful reserved!");
selectedPassenger.setBalance(selectedPassenger.getBalance() - selectedFlight.getPriceForFirstClass());
System.out.println(selectedPassenger.getFirstName() + "'s new balance is: " + selectedPassenger.getBalance());
} else {
noFundsAvailable(flightsList);
}
} else if (confirmation.equalsIgnoreCase("no")) {
cancellation(flightsList);
} else {
System.out.println("Wrong input!");
}
}

I think you can add a Flight field in your Passenger class, then do
selectedPassenger.setFlight(selectedFlight)
Here's the passenger class
class Passenger{
//other fields
Flight flight;
public void setFlight(Flight f){
this.flight = f;
}
If a passenger can have multiple flight, then declare a List in your passenger class, then do
selectedPassenger.getFlights().add(selectedFlight);
class Passenger{
//other fields
List<Flight> flight;
public Passenger(){
//don't forget to initialize flight list
flight = new ArrayList();
}
public List<Flight> getFlights(){
return this.flight ;
}
instead of fetching the whole list and adding it manually, you can have a method in your passenger class like
public void addFlight(Flight f){
this.flight.add(f);
}
then you can do
selectedPassenger.addFlight(selectedFlight);

You could design your Passenger class like this:
public class Passenger {
private String name;
private List<Flight> flights;
//Getter and setter for name
public Passenger(String name) {
this.name = name;
this.flights = new ArrayList<>();
}
public void addFlight(Flight flight) {
flights.add(flight);
}
}
On a side note, it might be worth refactoring your code. I note that you named your method payingFirstClassWithoutPromoCode(ArrayList<Flight> flightsList). I imagine you will have many more options, which means you will have to write multiple methods with very similar code.
It can be a good idea to make one method that can handle many different scenarios.
For example, you can add the ticket type (first/business/economy class) as an parameter in your method: payingWithoutPromoCode(ArrayList<Flight> flightsList, String ticketType).
It means you have to rewrite your method a little bit. In my example, you probably need to rewrite the methods in your Flight class. Instead of selectedFlight.getPriceForFirstClass() you can do selectedFlight.getPrice(ticketType).

Related

Use an object in another class

I want to use the object person in the Librarian_Interface class, but this call the method login() in a loop. I think there is something I don't understand with java instance and I tried to get person with a constructor or methode but in vain. Thanks !
public class Login_Interface {
Person person;
public Login_Interface() {
db.initConnection();
person = login(db, in);
if (person != null)
{
Librarian_Interface a = new Librarian_Interface();
a.run();
}
}
public void run() {
}
public static Person login(DbConnection db, Scanner sc) {
Persons.setDbConnection(db);
Persons persons = Persons.getInstance();
System.out.print("\nEnter your Phone Number : ");
String phone = sc.nextLine();
System.out.print("\nEnter your Password : ");
String password = sc.nextLine();
return persons.login(phone, password);
}
}
public class Librarian_Interface {
public Librarian_Interface() {
// What I want
// System.out.print(person); or person.getAge(); ...
All you have to do is pass the person object to the Librarian_Interface constructor. then you can call methods getAge on it, etc.
public class Librarian implements Runnable {
private final Person person;
public Librarian(Person person) {
this.person = person;
}
#Override
public void run() {
int age = person.age();
// ... whatever else
}
}
By the way, the convention in Java is to use upper camel case for class names, with no underscores. So it would be better to name the class LibrarianInterface. Also, it's probably not the best idea to call it LibrarianInterface if it is in fact a class and not an interface.
Since Librarian has a public run method, it's a good idea to have it implement Runnable so that users of the class see how it is meant to be used.

Why can't I seem to find the error in my program when compiling. Help needed

The pet store program should start with the user being able to choose to adopt a pet or give a pet the to the shop. If the user wants to adopt a pet, they should be able to see either all available pets, unless they say they know what type of pet they want, then show only available pets of that type.
The 4 methods that will need to be created for this program should:
add new pets
get a pet adopted
show pets by type
show pets available for adoption
Object Class: Pets.java
import java.util.*;
public class Pets {
public static void main(String[] args){
private double age; // age of the animal (e.g. for 6 months the age would be .5)
private String petName; // name of the animal
private String aType; // the type of the pet (e.g. "bird", "dog", "cat", "fish", etc)
private int collarID; // id number for the pets
private boolean isAdopted = false; // truth of if the pet has been adopted or not
private String newOwner;
private Date adoptionDate;
public double getAge() {
return age;
}
public void setAge(double age) {
this.age = age;
}
public String getPetName() {
return petName;
}
public void setPetName(String petName) {
this.petName = petName;
}
public String getaType() {
return aType;
}
public void setaType(String aType) {
this.aType = aType;
}
public int getCollarId() {
return collarID;
}
public void setCollarId(int collarId) {
this.collarID = collarId;
}
public boolean isAdoptated() {
return isAdopted;
}
public void setAdoptated(boolean isAdoptated) {
this.isAdopted = isAdoptated;
}
public Date getAdoptionDate() {
return adoptionDate;
}
public void setAdoptionDate(Date adoptionDate) {
this.adoptionDate = adoptionDate;
}
#Override
public String toString() {
return "Pets [age=" + age + ", petName=" + petName + ", aType=" + aType + ", collarId=" + collarID
+ ", isAdoptated=" + isAdopted + ", adoptionDate=" + adoptionDate + "]";
}
}
}
You should define the data fields and methods inside the class, but not inside the main()-method. The main()-method is the entry point of your java application and could be used to create an instance of your Pets class.
e.g.:
public static void main(String[] args) {
Pets pet = new Pets();
}
This code is not compiling for 2 main reasons:
You are specifying access modifiers on variables inside a method (in this case main), which is forbidden;
You are writing methods (e.g. getAge) inside another method (main) and trying to return a variable (e.g. age) that is out of that scope, in fact the variable age is not known inside the getAge method, because it's declared in the main method.
You should move the variable declaration to class level, and then have all methods separated using those variables. I'll give you a sketch, not the complete solution:
import java.util.*;
public class Pets {
/* Insert all variable declarations here */
private double age;
/* Constructor if you need it */
public Pets(/* parameters you think you need */) {
// Set attributes when you declare a new Pets()
}
/* Insert all methods you need here */
public double getAge() {
return this.age;
}
The positioning of the main method - for what I've understoon from your description - should be placed outside this class, in another class where the whole application will start to run. The Pet class should serve only for anything concerning pets (the four methods you will need to implement and all getters/setters for retrieving private class variables).
You’ve happened to put about everything — private fields and public methods — inside you main method. That doesn’t make sense. Everything that is in your main, move it outside, right under the line public class Pets {. That should fix your compiler error.

Best way to store collection of objects in Java?

I am creating a dump Java app for student information system for learning and implementing OOPS Concepts like inheritance, abstraction, polymorphism and encapsulation.
What I am doing is, I have created Faculty Class, Student Class and a College Class. Now i want to add new faculty in College. So my approach is to create a method in College class i.e. addFaculty(Faculty f) and fireFaculty(Faculty f), now i want to add Faculties in College class.
Whats the best way to do it? How do i store list of Faculty Object in College Object. Because i can add more than one faculty and more than one student in college.
Whats the best approach to solve this problem in OOPS?
Here is College.java code which i have implemented, it works fine but is this the best way i can solve it?
public class College
{
String name;
String location;
String courses[];
HashMap<String,Faculty> faculties;
int noOfFaculties = 0;
int noOfStudents = 0;
public College(String name,String location,String courses[])
{
this.name = name;
this.location = location;
this.courses = courses;
faculties = new HashMap<>();
}
public void addFaculty(Faculty faculty)
{
faculties.put(faculty.getName(),faculty);
}
public void printFaculties()
{
Set<String> set = faculties.keySet();
if(set.size()>0)
{
for(String s:set)
{
System.out.println(faculties.get(s).getName());
}
}
else
{
System.out.println("No Faculties Currently Working");
}
}
public void fireFaculty(Faculty faculty)
{
faculties.remove(faculty.getName());
}
public String getName()
{
return name;
}
public String getLocation()
{
return location;
}
public String[] getCourses()
{
return courses;
}
}
If you cannot have duplicates use HashSet<Faculty> if you dont mind use a List<Faculty>.
Example:
class College {
private List<Faculty> listFactories = new ArrayList<>(); // dupes allowed
private Set<Faculty> setFactories = new HashSet<>(); // no dupes allowed
}
Check collections API.
There's a ton of ways you can do it. Probably the easiest way to handle storing a collection of objects is by using one of the Collections provided by Java. For beginners, probably the easiest one to understand is an ArrayList, which is basically an array that grows in size dynamically depending on the amount of objects in the collection.
So, as an axample, your code might be something like this:
public class College
{
private ArrayList<Faculty> faculty;
public College()
{
faculty = new ArrayList<Faculty>();
}
public void addFaculty(Faculty f)
{
faculty.add(f);
}
public void fireFaculty(Faculty f)
{
faculty.remove(f);
}
}
imho It depends what kind of services College college offers. If I were coding, I would start with:-
List<Faculy> faculties = new ArrayList<>();
....
public void addFaculty(Faculty f) {
faculties.add(f);
}
//... etc
And change to an altearnative later if needed.

Address book program in Java

I'm just doing a small program. It's an address book which has four options:
insert new contact
search contact by last name
delete contact by name
show all contacts
exit program
Just wondering how to get the insert contact part and how to store it. I've hardcoded one contact to test it.
Here is my code I have started
package addressbook;
import java.util.Scanner;
public class addressbooks
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
//create a table to hold information
String[][] addressbooks = new String[100][8];
addressbooks[0][0]="Mobile Number";
addressbooks[0][1]="First Name";
addressbooks[0][2]="Last Name";
addressbooks[0][3]="Address";
addressbooks[0][4]="City";
addressbooks[0][5]="County";
addressbooks[0][7]="Telephone Number";
//pre-populate address book for testing purposes and records
addressbooks[1][0]="1";
addressbooks[1][1]="David";
addressbooks[1][2]="Needham";
addressbooks[1][3]="Sraheens, Achill";
addressbooks[1][4]="Galway";
addressbooks[1][5]="Mayo";
addressbooks[1][6]="086-1581077";
addressbooks[1][7]="098-45368";
addressbooks[2][0]="2";
addressbooks[2][1]="Mc";
addressbooks[2][2]="lovin";
addressbooks[2][3]="Hawaii";
addressbooks[2][4]="Hawaii";
addressbooks[2][5]="Hawaii";
addressbooks[2][6]="12345";
addressbooks[2][7]="412-555-1234";
//menu options
System.out.print("Welcome to my Address book!");
System.out.print("\n");
System.out.print("\n1 - Insert a New Contact \n2 - Search Contact by Last Name \n3 - Delete Contact \n4 - Show All Contacts \n5 - Exit " );
System.out.print("\n");
System.out.print("\nChoose your option: ");
int option = input.nextInt();
if (option ==1)
{
System.out.print("\nPlease enter your First Name : ");
}
if (option ==2)
{
}
if (option ==3)
{
}
if (option ==4)
{
System.out.println(addressbooks[1][0]+
"\t"+addressbooks[1][2]+ ", "+addressbooks[1][1]+
"\n\t"+addressbooks[1][3]+
"\n\t"+addressbooks[1][4]+ ", "+addressbooks[1][5]+ " "+addressbooks[1][6]+
"\n\t"+addressbooks[1][7]);
}
if (option ==5)
{
}
}
}
I'd start like this:
package model;
public class Person {
private String firstName;
private String lastName;
// What else means something to your problem? Birthday?
// Constructors, getters (make them immutable), equals/hashCode
}
public class Address {
private String street;
private String city;
private String county;
private String postalCode;
// Constructors, getters (make them immutable), equals/hashCode
}
public class AddressBook {
private Map<Person, Address> contacts = new ConcurrentHashMap<Person, Address>();
public void addContact(Person p, Address a) {
this.contacts.put(p, a);
}
public void removeContact(Person p) {
this.contacts.remove(p);
}
public Collection<Person> findAllContacts() {
return new Collections.unmodifiableCollection(this.contacts.keySet());
}
public boolean hasContact(Person p) {
return this.contacts.contains(p);
}
// etc.
}
I would recommend separating all that stuff about text-based IO out away from the fundamentals of your problem. If you get it right, the next step is to write a web UI. Most of the code will be reusable if you do it correctly.
Think about layering your app:
view->services->persistence
Model classes might be used in all three layers.
The answer recommending JDBC isn't wrong. If you write your service and persistence classes as interfaces, you'll find it easy to swap out an in-memory Map of Contacts for a database version that uses JDBC:
package persistence;
public interface ContactDao {
Collection<Contact> find();
Contact find(Long id);
Collection<Contact> find(String lastName);
Collection<Contact> find(Address address);
Long save(Contact c);
void update(Contact c);
void delete(Contact c);
}
There are lots of ways to do things. I've already changed my mind: I've introduced a Contact class:
package model;
public class Contact {
private Person;
private Address;
}
The use of objects will greatly help you here:
class ADdressBook
{
List<Contact> contacts;
function addContact(Contact contact)
{
contacts.add(contact);
}
}
You will want to use the methods that are exposed as part of the List/Collection API to make this easier on you. Implementing the Contact class is an exercise for you.
I actually created a similar program, I would recommend simply constructing a database, this also allows you to save data in between uses of the program. Using JBDC is quite simple, here is the site i used: http://www.zentus.com/sqlitejdbc/

Any nice way to make two immutable objects refer to eachother?

Take these two Java classes:
class User {
final Inventory inventory;
User (Inventory inv) {
inventory = inv;
}
}
class Inventory {
final User owner;
Inventory (User own) {
owner = own;
}
}
Is there any way without using reflection* to pull this off? I don't actually expect it is, but it can't hurt to ask.
Update: Since in bytecode construction has two steps (1. allocate object, 2. call constructor**) could this be (ab)used to do this, with handwritten bytecode or a custom compiler? I'm talking about performing step 1 for both objects first, then step 2 for both, using references from step 1. Of course something like that would be rather cumbersome, and this part of the question is academic.
(* Because reflection may give trouble with a security manager)
(** Says my limited knowledge)
This can only work cleanly if one of the objects is created by the other. For example you can change your User class to something like this (while keeping the Inventory class unchanged):
class User {
private final Inventory inventory;
User () {
inventory = new Inventory(this);
}
}
You need to be careful about accessing the User object in the Inventory constructor, however: it's not fully initialized yet. For example, its inventory field will still be null!
Ad Update: I've now verified that the bytecode-manipulation approach does not work. I've tried it using Jasmin and it always failed to load with a VerifyError.
Delving deeper into the issue, I found§ 4.10.2.4 Instance Initialization Methods and Newly Created Objects. This section explains how the JVM ensures that only initialized object instances get passed around.
You can do it if you don't need to inject one of the objects.
class User {
private final Inventory inventory;
User () {
inventory = new Inventory(this);
}
}
class User {
private final Inventory inventory;
User (/*whatever additional args are needed to construct the inventory*/) {
//populate user fields
inventory = new Inventory(this);
}
}
class Inventory {
private final User owner;
Inventory (User own) {
owner = own;
}
}
That's the best I can think of. Maybe there's a better pattern.
Slightly pedantic, but it's not strictly speaking necessary to create one inside the other, if you don't mind a little indirection. They could both be inner classes.
public class BadlyNamedClass {
private final User owner;
private final Inventory inventory;
public BadlyNamedClass() {
this.owner = new User() {
... has access to BadlyNamedClass.this.inventory;
};
this.inventory = new Inventory() {
... has access to BadlyNamedClass.this.owner;
};
}
...
}
Or even:
public class BadlyNamedClass {
private final User owner;
private final Inventory inventory;
public BadlyNamedClass() {
this.owner = new User(this);
this.inventory = new Inventory(this);
}
public User getOwner() { return owner; }
public Inventory getInventory() { return inventory; }
...
}
This is one "solution", though the loss of one final is inconvenient.
class User {
Inventory inventory;
User () { }
// make sure this setter is only callable from where it should be,
// and is called only once at construction time
setInventory(inv) {
if (inventory != null) throw new IllegalStateException();
inventory = inv;
}
}
class Inventory {
final User owner;
Inventory (User own) {
owner = own;
}
}
If you are only interested in JVM bytecode and don't care about coding in Java specifically, perhaps using Scala or Clojure could help. You'll need some kind of letrec machinery.
B: "Inventory created by the User is our last hope".
Y: "No, there is another."
If you abstract the references to a third party, you can control the relationship therein.
For example.
public class User
{
private final String identifier; // uniquely identifies this User instance.
public User(final String myIdentifier)
{
identifier = myIdentifier;
InventoryReferencer.registerBlammoUser(identifier); // Register the user with the Inventory referencer.
}
public Inventory getInventory()
{
return InventoryReferencer.getInventoryForUser(identifier);
}
}
public interface Inventory // Bam!
{
... nothing special.
}
// Assuming that the Inventory only makes sence in the context of a User (i.e. User must own Inventory).
public class InventoryReferencer
{
private static final Map<String, Inventory> referenceMap = new HashMap<String, Inventory>();
private InventoryReferencer()
{
throw ... some exception - helps limit instantiation.
}
public static void registerBlammoUser(final String identifier)
{
InventoryBlammo blammo = new InventoryBlammo();
referenceMap.add(indentifier, blammo);
}
public static void registerKapowUser(final String identifier)
{
InventoryBlammo kapow = new InventoryKapow();
referenceMap.add(indentifier, kapow);
}
public static Inentory getInfentoryForUser(final String identifier)
{
return referenceMap.get(identifier);
}
}
// Maybe package access constructors.
public class InventoryBlammo implements Inventory
{
// a Blammo style inventory.
}
public class InventoryKapow implements Inventory
{
// a Kapow style inventory.
}

Categories