Nick Kisbye Hansen
Nick Kisbye Hansen

Reputation: 101

List of 'unique' objects in Java

I'm making a school assignment with my class mate. We are making a taxi app, where you can start and stop the taxi, ask for current price and get a total price when the taxi is stopped. At the moment it works fine. But the problem occurs if we start Taxi 1 for example, and then start Taxi 2. The start and end time of Taxi 1 is overwritten by the new objects (Taxi 2) start and end time - even though we are getting an unique object from and arraylist based on the number the user i typing into the system.

The code in Main.java:

import java.text.DecimalFormat;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Taxi taxi = new Taxi();
        System.out.println("Hej og velkommen til Damn Fast Taxis.");
        boolean isEnd = false;
        DecimalFormat decimalFormat = new DecimalFormat("#.0");
        while(!isEnd) {

            Taxi chosenTaxi;

            System.out.println("1. Start en taxi.");
            System.out.println("2. Stop en taxi.");
            System.out.println("3. Pause en taxi.");
            System.out.println("4. Spørg efter pris.");
            System.out.println("5. Gratis tur.");
            System.out.println("6. Tilføj antal taxier.");

            Scanner sc = new Scanner(System.in);
            String choice = sc.nextLine();

            switch (choice) {
                case "1":
                    if (taxi.getTaxiListPrint().size()>=1) {

                        Scanner startTaxiNumber = new Scanner(System.in);
                        int numberChoice = startTaxiNumber.nextInt();
                        chosenTaxi = taxi.chooseTaxi(numberChoice);

                        chosenTaxi.setStartTime();
                        break;
                    } else {
                        System.out.println("Ingen taxier er oprettet i systemet.");
                        break;
                    }

                case "2":

                    if (taxi.getTaxiListPrint().size()>=1) {
                        Scanner endTaxiNumber = new Scanner(System.in);
                        int numberChoice = endTaxiNumber.nextInt();
                        chosenTaxi = taxi.chooseTaxi(numberChoice);

                        chosenTaxi.setEndTime();

                        if (!chosenTaxi.isStopped()) {
                            System.out.println("Turen varede " + decimalFormat.format(((chosenTaxi.getEndTime() - chosenTaxi.getStartTime()) / 100)*0.1) + " sekunder.");
                            Price price = new Price();
                            String finalPrice = price.calculatePrice(chosenTaxi.getStartTime(), chosenTaxi.getEndTime(), decimalFormat);
                            System.out.println("Pris: " + finalPrice + " dollars.");
                            chosenTaxi.setStopped(true);
                        } else {
                            System.out.println("Denne taxi er allerede blevet stoppet.");
                        }
                        break;
                    } else {
                        System.out.println("Ingen taxier er oprettet i systemet.");
                    }
                case "3":
                    break;
                case "4":

                    if (taxi.getTaxiList().size()>=1) {
                        Scanner currentPriceTaxiNumber = new Scanner(System.in);
                        int numberChoice = currentPriceTaxiNumber.nextInt();
                        Taxi currentChosenTaxi = taxi.chooseTaxi(numberChoice);

                        currentChosenTaxi.setEndTime();
                        if (!currentChosenTaxi.isStopped()) {
                            Price priceNow = new Price();
                            String currentPrice = priceNow.calculatePrice(currentChosenTaxi.getStartTime(), currentChosenTaxi.getEndTime(), decimalFormat);
                            System.out.println("Pris: " + currentPrice + " dollars.");
                        } else {
                            System.out.println("Denne taxi er allerede blevet stoppet.");
                        }
                        break;
                    } else {
                        System.out.println("Ingen taxier er oprettet i systemet.");
                        break;
                    }

                case "5":

                    break;
                case "6":
                    System.out.println("Hvor mange taxier vil du tilføje?");
                    Scanner taxaNumber = new Scanner(System.in);
                    int number = taxaNumber.nextInt();
                    for (int i = 0; i<number;i++) {
                        taxi.addTaxi(taxi);
                    }
                    System.out.println(number + " " + "Taxa'er tilføjet!");
                    break;
                default:
                    isEnd = true;

     break;

Taxi class:

import java.util.ArrayList;
import java.util.List;

public class Taxi {

    private long startTime;
    private long endTime;
    private boolean isStopped = false;
    private List<Taxi> taxiList = new ArrayList<>();

    public void addTaxi(Taxi taxi) {
        taxiList.add(taxi);
    }

    public Taxi chooseTaxi(int choice) {
        return taxiList.get(choice - 1);
    }

    public List<Taxi> getTaxiListPrint() {

        for(int i = 1; i<taxiList.size() + 1;i++) {
            System.out.println("Taxi: " + i);
        }
        return taxiList;
    }

    public List<Taxi> getTaxiList() {
        return taxiList;
    }

    public long getStartTime() {
        return startTime;
    }

    public long getEndTime() {
        return endTime;
    }

    public boolean isStopped() {
        return isStopped;
    }

    public void setStartTime() {
        this.startTime = System.currentTimeMillis();
    }

    public void setEndTime() {
        this.endTime = System.currentTimeMillis();
    }

    public void setStopped(boolean stopped) {
        isStopped = stopped;
    }
}

I'm sorry if my code is messy, I'm very new to the language. The short question is: how to I define the different objects, so that the program doesn't overwrite every time I make a new instance of taxi?

Thank you very much. /Nick

Upvotes: 0

Views: 157

Answers (2)

molamk
molamk

Reputation: 4116

Include only attributes that make up a Taxi in your class

As the comments said, having a taxiList in your Taxi class is not a good idea. Your Taxi class should have only the necessary attributes which make up a Taxi. A better structure will look like this

public class Taxi {
    private long startTime;
    private long endTime;
    private boolean isStopped = false;

    // Add the necessary getters & setters for the above attributes here
}

Manage your taxis, through a List or a TaxiManager class

To hold your taxiList you have 2 options

  1. In you Main class, define a List<Taxi> taxiList = new ArrayList<>()
  2. Create a separate class to hold the list and the logic to control its items. For example TaxiManager

The 1st option is a good way to go if have a small numbers of possible operations on a Taxi. The 2nd option is better if you want to abstract the taxi management logic from the Main class. It can look like this

public class TaxiManager {
    private List<Taxi> taxiList;
    public class TaxiManager() { taxiList = new ArrayList<>(); }

    // Here are some "management" methods you can use
    // DON'T FORGET TO HANDLE EXCEPTIONS (for example ArrayOutOfBounds, ...)

    public void addTaxi(Taxi newTaxi) { taxiList.add(newTaxi); }
    public Taxi getTaxiAtIndex(int index) { return taxiList.get(index); }
    public void stopTaxiAtIndex(int index) { taxiList.get(index).stop(); }

    // Add the necessary operations here
}

How to use this in your Main class

Create a new TaxiManager and call your methods according to the logic you choose (the switch case)

public class Main {
    public static void main(String[] args) {
        TaxiManager taxiManager = new TaxiManager();

        Scanner sc = new Scanner(System.in);
        String choice = sc.nextLine();

        switch (choice) {
            case "add": {
                taxiManager.addTaxi(new Taxi());
                break;
            }
            // Include other options
        }
    }
}

Answer to the question of "unique objects" => Use a Singleton

Ensure a class has only one instance, and provide a global point of access to it

This can be a good choice for your TaxiManager if you want to call it from different "classes" and still preserve the uniqueness of that manager. You can then rest assured that your taxis are not duplicated. If you want to go this way, your TaxiManager will look something like this

public class TaxiManager {
    private List<Taxi> taxiList;
    private TaxiManager() {}

    private static class SingletonHolder {
        private static final TaxiManager INSTANCE = new TaxiManager();
    }

    public static TaxiManager getInstance() {
        return SingletonHolder.INSTANCE;
    }

    // Add other methods here
}

And to call it from your Main class, use this

TaxiManager taxiManager = TaxiManager.getInstance();

Upvotes: 0

rockfarkas
rockfarkas

Reputation: 132

I think the simplest change you have to change these methods in Taxi class to static:

private static List<Taxi> taxiList = new ArrayList<>();

public static void addTaxi(Taxi taxi) {
    taxiList.add(taxi);
}

public static Taxi chooseTaxi(int choice) {
    return taxiList.get(choice - 1);
}

public static List<Taxi> getTaxiListPrint() {

    for (int i = 1; i < taxiList.size() + 1; i++) {
        System.out.println("Taxi: " + i);
    }
    return taxiList;
}

public static List<Taxi> getTaxiList() {
    return taxiList;
}

Change these methods to static form, for example:

Taxi currentChosenTaxi = taxi.chooseTaxi(numberChoice);

change to

Taxi currentChosenTaxi = Taxi.chooseTaxi(numberChoice);

Then add different taxis to the manager:

            case "6":
                System.out.println("Hvor mange taxier vil du tilføje?");
                Scanner taxaNumber = new Scanner(System.in);
                int number = taxaNumber.nextInt();
                for (int i = 0; i < number; i++) {
                    Taxi.addTaxi(new Taxi());
                }
                System.out.println(number + " " + "Taxa'er tilføjet!");
                break;

Note: you do not need make new Scanner(System.in) every time, you can use one if you put outside of the loop.

Upvotes: 1

Related Questions