简体   繁体   中英

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

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.

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM