Which data structure should I use in Java? - java

I'm doing Car Rental app in Java.
I have class Car with Strings RegNo, producer, model and boolean isCarRented.
List of cars I'm keeping in:
Collection<Car> carList = new HashSet<Car>();
Everything works fine.
Now what I need to do is history/statistic module for whole rental company:
history of all car rentals
rental history for each car separately
My idea is to:
Create class CarHistory with:
private static List<String> rentalDates = new ArrayList<String>();
Keeping there dates which I'm gonna add every time the car is rented.
Create data structure to remember each car rental history like this:
static Map<Car, CarHistory> rentalList = new HashMap<Car, CarHistory>();
Is it a good way? I do have troubles with constructor for single CarHistory in this solution. Not really sure what it should return. Should I create it after first rental? And should create empty List rentalDates for each car to create HashMap?

What you are trying to do is to implement a one-to-one relationship, because a Car has only one CarHistory and one CarHistory concerns only one Car. That is why, the correct way of doing it would be to add field CarHistory carHistory to the class of Car.
In the beginning, the list of CarHistory would be empty. With each reservation, you would simply add one record to the list. The car history would be easily accessible, and the model would match the reality in the most accurate way.

Related

Referencing an Object Inside an Object

I am creating a game in Java and need to create a list of all of the rooms in it.
I have a 'Rooms' class that has the code for the room, i.e. room name, items in the room etc.
In the Room class I want to have a static ArrayList that has all of the room objects in the whole game in there. This is needed for a method I am working on.
I have created an ArrayList field:
private static ArrayList<Rooms> listOfRooms = new ArrayList<Rooms>();
In the initialisation of each instance of Rooms, I wish to add that instance to the listOfRooms ArrayList.
I assume you start with listOfRooms.add(), but what would you actually put in the parameter to add the current object to the list of Rooms objects?
You'd add this to the list; this being a reference to the current object (a Room in this case) being worked on:
listOfRooms.add(this);
Note though, having listOfRooms as a static member of the class is a bad idea. With this setup, you can only ever have one list, and anyone can alter the list however they want since it's public.
It would likely be much better to create something like a Hotel class and make it a member of that:
class Hotel {
ArrayList<Rooms> listOfRooms = new ArrayList<Rooms>();
}
Now you can at least have multiple hotels if necessary with separate lists of rooms, and to modify the rooms, code would at least require a reference to the hotel.
Adding to what Carcigenicate said, it's always better to have more abstraction in object oriented programming.
For example, Hotel object has a Floor ArrayList in it. Each Floor object contains ArrayList of Room and so on.

How would I allow the user to add, edit, delete groups of Lists? Such as a classroom, cabin, etc

I was hoping someone could tell me if I'm even going about this the right way, or if what I'm doing is even possible.
My end goal is to create a program where you can create cabins, create campers, and assign them to a cabin.
What I thought of was allowing the user to create a new ArrayList by having a method called that does such. I would create a Camper class where it has the variables such as name, age, gender, etc...
Then I would write a method that looked something like this....
public static void userCreatesList(){
ArrayList<Camper> cabin = new ArrayList<Camper>();
}
The problem is, the method works when I add items to the list and have it print out as each time it prints a different list when calling the method, however, what I cannot figure out how to do is to call a previous list again as every list here will have the same variable or object name.
So, if I created say three cabin lists all together by calling this method three times, how would I assign a person to a particular cabin if they all end up having the same variable name?
It has to be a program where the user can create the list and I didn't have to declare a number of lists with a different variable name, because each camp may have a different number of cabins, and they have to be able to make their own list?
If what I'm doing is not possible and I need to be using another type of object besides a list to do this, please just tell me and I'll research how to use that object.
I've searched all over how to create a new group, a new set, etc.. and I cannot find anything relevant to what I'm trying to do that can explain this.
I want them to be able to give that group a name, such as "Red Cabin", "Blue Cabin", "Cabin 1", "Cabin 12", etc....
For this I would recommend to use Map, with group name as a key and ArrayList as value.
private static Map<String, ArrayList<Camper>> cabinMap = new HashMap<String, ArrayList<Camper>>();
public static void userCreatesList(String groupName){
ArrayList<Camper> cabin = new ArrayList<Camper>();
cabinMap.put(groupName, cabin);
}
Later you can access to the certain group from this map by name and add members to it.

Should an object know what other objects have it?

For instance, I have two classes: Book and Customer. Customer has a List which contains all the Books it purchased. I can easily look up a Customer's purchase history with this design.
However, if I want to know how many Customers have bought a particular Book, usually I would look up all Customers purchase history and get those who bought this particular Book. This can be a time consuming looking up process. I wonder if it would be a better approach to add a List inside the Book class, and add all the Customers who bought this particular book to this List.
I wonder if my approach would be better/worse in terms of design. This is definitely making Book-Customer strongly coupled, but I am not sure if there is other ways to implement such method.
Ideally, to be pure, neither the book nor the customer should know about each other. I would instead create a third class, Purchase, containing references to the customer and the book, the date ordered, date shipped, price paid, etc.
Then I'd have a Map<Customer, List<Purchase>> and optionally a Map<Book, List<Purchase>>.
Even Customer class having reference to list of books is not that great.
Keep both Customer and Book classes unaware of each other. Instead maintain maps for your quick reference. e.g. -
Map<Customer, List<Book>> customerToBooks;
Map<Book, List<Customer>> bookToCustomers;
And manipulate these maps through assignBook(Customer c, Book b) and returnBook(Customer c, Book b) methods
One thing you can do is check the list inside of the customer's class checking the book purchase history like so:
Customer.java
public class Customer{
public Set<Book> purchases = new HashSet<Book>();
public void purchaseBook(Book b){
purchases.add(b);
}
}
Original class:
public Set<Customer> customers = new HashSet<Customer>();
public Set<Customer> getCustomersFromBook(Book b){
Set<Customer> ret = new HashSet<Customer>();
for(Customer c : customers){
if(c.purchases.contains(b)){
ret.add(c);
}
}
return ret;
}
Or you can do the same sort of thing, but with the customers inside of a Set in the Book class.

How to use indexOf() in an ArrayList on Android?

I have a problem and it's that I try to get the position of an item in an ArrayList called cars.
Car car = new Car(int idcar, String model, String brand); //Here it's an example
ArrayList<Car> cars = new ArrayList<Car>();
And suppose that I have 5 cars in the ArrayList and I want to get the information of the car number 3 so I tried to get the position with the function indexOf() but it always returns me the value -1.
I know that the value -1 it's when it didn't found any car in the arraylist that it's equals to the car that I use in the function. Could it be because idcar is null when I use the second constructor and try to find the object with indexOf()? I use the function like this:
int position = cars.indexOf(car);
I think it's because I have 2 constructors of the class Car. One with idcar, model and brand and another with just model and brand. I did that because if I don't know the id of the car, I can't use the car in the function so it's an infernal loop and I don't have any idea how to end it.
It's connected to a database that save all the cars that you insert into the arraylist and it's why I need the id, just because if I enter 7 cars one day, close the application and run it again, I won't know the id (that it's the position in the arraylist) of this car and I won't be able to delete one of them, for example.
Of course I have all get's and set's methods in the class Car to get or set all the information when I have inicialized the object Car.
I expect it could be understood clearly.
Thank you very much!
If you haven't implemented Car's equals() method, you have to be sure that you are passing exactly the same instance of Car to the indexOf() method as the instance that is contained by the list.
This is because indexOf() uses contained objects' equals() method and equals() default implementation is just a == comparison.
It'd make sense to implement Car's equals() method.

How to dynamically create Lists in java?

I'm programming in java for a class project.
In my project I have airplanes, airports and passengers.
The passenger destination airport is randomly created, but then I have to add it to a List with passengers for that destination.
As long as the airports are read from a file thus they can vary, how can I create Lists according to these airports?
What I want to do is something like:
List<Passenger> passengersToJFK = new ArrayList<Passenger>();
.
.
.
if(passenger.destination == "JFK"){
passengersToJFK.add(passenger);
}
The problem is that as I've said, the number and name of airports can vary, so how can I do a general expression that creates Lists according to the Airports File and then adds passengers to those Lists according to the passenger destination airport?
I can get the number of Airports read from the file and create the same number of Lists, but then how do I give different names to this Lists?
Thanks in advance
You can keep a registry of the associations between a destination or airport and a list of passengers with a Map, in a particular class that centers this passengers management.
Map<String,List<Passenger>> flights = new HashMap<String,List<Passenger>>();
Then, whenever you want to add a new destination you put a new empty list and
public void addDestination(String newDestination) {
flights.put(newDestination, new ArrayList<Passenger>());
}
When you want to add a passenger, you obtain the passenger list based on the destination represented by a String.
public void addPassengerToDestination(String destination, Passenger passenger) {
if(flights.containsKey(destination))
flights.get(destination).add(passenger);
}
I suggest you dig a little deeper into some particular multi-purpose Java classes, such as Lists, Maps and Sets.
I would probably create a Map of airports with airport name as the key and a List of passengers as the value.
e.g.
Map<String, List<String>> airports = new HashMap<String, List<String>>();
airports.put("JFK", passengersToJFK);
You sound like you're thinking too much in terms of primitives, Strings, and collections and not enough in terms of objects.
Java's an object-oriented language; start thinking about Objects and encapsulation.
You've got a good start with your Passenger class. Keep going with Airport.
Do you add Passengers to Airport? Nope, I think they belong to a Flight.
Do a little thinking about your problem before you write more code.
You shouldn't focus on giving the actual variables of list objects unique names, but instead, create a map from String (destination id) to List (passengers heading to that destination), and add lists on the fly to that map, linking each new list to its relevant destination. Update the lists in that map as needed.
The best way to do it is to create objects for all three.
You might have an Airport object that looks like this:
class Airport{
String name;
List Airplane airplanes;
}
then you would have an airplane that looked like this:
class Airplane{
String name; // ?? or bodyType? or whatever else you need
List Passenger passengers;
}
In this way you compose your objects from each other in a way that ends up being much easier to understand and deal with.
Note that I'm leaving off methods, like Airport probably has a method like "addAirplane" to add another airplane, and the airplane object has an addPassenger method...

Categories