课堂极限测试及错误原因分析

今天进行了as的课堂测试,需要创建一个Android项目,从前端选择起点站和终点站,实现地铁费用的计算;
这个项目其实并不难,只需要完成对应的逻辑计算即可,可是在完成过程中,因为对站点信息的判断错误,使我一直无法得到正确的答案;
最后我更改了这个逻辑错误,完成了任务:
Line:

package com.app.testdemo.model;

import java.util.List;

public class Line {
    private final int id;
    private final String name;
    private final List<Station> stations;

    public Line(int id, String name, List<Station> stations) {
        this.id = id;
        this.name = name;
        this.stations = stations;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public List<Station> getStations() {
        return stations;
    }
}

Station:

package com.app.testdemo.model;

import java.util.List;

public class Line {
    private final int id;
    private final String name;
    private final List<Station> stations;

    public Line(int id, String name, List<Station> stations) {
        this.id = id;
        this.name = name;
        this.stations = stations;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public List<Station> getStations() {
        return stations;
    }
}

MainActivity:

package com.app.testdemo;

import android.os.Bundle;
import android.view.View;
import android.widget.*;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.app.testdemo.model.Line;
import com.app.testdemo.model.Station;

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

public class MainActivity extends AppCompatActivity {

    private Spinner spinnerStart;
    private Spinner spinnerEnd;
    private EditText editTextTickets;
    private TextView textViewAmount;
    private Button buttonCalculate;
    private Button buttonBuy;

    private List<Line> allLines;
    private List<Station> allStations;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);

        initViews();
        setupSpinners();
        setupListeners();
    }

    private void initViews() {
        spinnerStart = findViewById(R.id.spinnerStart);
        spinnerEnd = findViewById(R.id.spinnerEnd);
        editTextTickets = findViewById(R.id.editTextTickets);
        textViewAmount = findViewById(R.id.textViewAmount);
        buttonCalculate = findViewById(R.id.buttonCalculate);
        buttonBuy = findViewById(R.id.buttonBuy);

        // Initialize lines and stations
        allLines = new ArrayList<>();
        allLines.add(createLine1());
        allLines.add(createLine2());
        allLines.add(createLine3());

        allStations = new ArrayList<>();
        for (Line line : allLines) {
            allStations.addAll(line.getStations());
        }
    }

    private Line createLine1() {
        List<Station> stations = new ArrayList<>();
        stations.add(new Station("西王", 0, 1));
        stations.add(new Station("时光街", 1, 1));
        stations.add(new Station("长城桥", 2, 1));
        stations.add(new Station("和平医院", 3, 1));
        stations.add(new Station("烈士陵园", 4, 1));
        stations.add(new Station("新百广场", 5, 1, new ArrayList<Integer>() {{ add(3); }}));
        stations.add(new Station("解放广场", 6, 1));
        stations.add(new Station("平安大街", 7, 1));
        stations.add(new Station("北国商城", 8, 1, new ArrayList<Integer>() {{ add(2); }}));
        stations.add(new Station("博物院", 9, 1));
        stations.add(new Station("体育场", 10, 1));
        stations.add(new Station("北宋", 11, 1));
        stations.add(new Station("谈固", 12, 1));
        stations.add(new Station("朝晖桥", 13, 1));
        stations.add(new Station("白佛", 14, 1));
        stations.add(new Station("留村", 15, 1));
        stations.add(new Station("火炬广场", 16, 1));
        stations.add(new Station("石家庄东站", 17, 1));
        stations.add(new Station("南村", 18, 1));
        stations.add(new Station("洨河大道", 19, 1));
        stations.add(new Station("西庄", 20, 1));
        stations.add(new Station("东庄", 21, 1));
        stations.add(new Station("会展中心", 22, 1));
        stations.add(new Station("商务中心", 23, 1));
        stations.add(new Station("园博园", 24, 1));
        stations.add(new Station("福泽", 25, 1));

        return new Line(1, "1号线", stations);
    }

    private Line createLine2() {
        List<Station> stations = new ArrayList<>();
        stations.add(new Station("柳辛庄", 0, 2));
        stations.add(new Station("庄窠·铁道大学", 1, 2));
        stations.add(new Station("义堂", 2, 2));
        stations.add(new Station("建和桥", 3, 2));
        stations.add(new Station("长安公园", 4, 2));
        stations.add(new Station("北国商城", 5, 2, new ArrayList<Integer>() {{ add(1); }}));
        stations.add(new Station("裕华路", 6, 2));
        stations.add(new Station("槐中路", 7, 2));
        stations.add(new Station("欧韵公园", 8, 2));
        stations.add(new Station("元村", 9, 2));
        stations.add(new Station("石家庄", 10, 2, new ArrayList<Integer>() {{ add(3); }}));
        stations.add(new Station("塔坛", 11, 2));
        stations.add(new Station("仓丰路留村", 12, 2));
        stations.add(new Station("南位", 13, 2));
        stations.add(new Station("嘉华路", 14, 2));

        return new Line(2, "2号线", stations);
    }

    private Line createLine3() {
        List<Station> stations = new ArrayList<>();
        stations.add(new Station("西三庄", 0, 3));
        stations.add(new Station("高柱", 1, 3));
        stations.add(new Station("柏林庄", 2, 3));
        stations.add(new Station("市庄", 3, 3));
        stations.add(new Station("市二中", 4, 3));
        stations.add(new Station("新百广场", 5, 3, new ArrayList<Integer>() {{ add(1); }}));
        stations.add(new Station("东里", 6, 3));
        stations.add(new Station("槐安桥", 7, 3));
        stations.add(new Station("西三教", 8, 3));
        stations.add(new Station("石家庄", 9, 3, new ArrayList<Integer>() {{ add(2); }}));
        stations.add(new Station("汇通路", 10, 3));
        stations.add(new Station("孙村", 11, 3));
        stations.add(new Station("塔冢", 12, 3));
        stations.add(new Station("东王", 13, 3));
        stations.add(new Station("南王", 14, 3));
        stations.add(new Station("位同", 15, 3));
        stations.add(new Station("东二环南路", 16, 3));
        stations.add(new Station("西仰陵", 17, 3));
        stations.add(new Station("中仰陵", 18, 3));
        stations.add(new Station("南豆", 19, 3));
        stations.add(new Station("太行南大街", 20, 3));
        stations.add(new Station("乐乡", 21, 3));

        return new Line(3, "3号线", stations);
    }

    private void calculateFare() {
        Station startStation = allStations.get(spinnerStart.getSelectedItemPosition());
        Station endStation = allStations.get(spinnerEnd.getSelectedItemPosition());
        int ticketCount = 0;
        try {
            ticketCount = Integer.parseInt(editTextTickets.getText().toString());
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }

        if (startStation.getName().equals(endStation.getName())) {
            Toast.makeText(this, "起点站和终点站不能相同", Toast.LENGTH_SHORT).show();
            return;
        }

        int stationCount = calculateStationCount(startStation, endStation);
        int farePerTicket = (stationCount + 2) / 3;
        int totalFare = farePerTicket * ticketCount;

        textViewAmount.setText("总金额:" + totalFare + "元");
        buttonBuy.setEnabled(true);
    }

    private int calculateStationCount(Station start, Station end) {
        // 如果在同一条线路上
        if (start.getLineId() == end.getLineId()) {
            return Math.abs(start.getIndex() - end.getIndex());
        }

        // 需要换乘的情况
        int minStations = Integer.MAX_VALUE;

        // 遍历所有可能的换乘路径
        for (Station transfer1 : allStations) {
            if (transfer1.getTransferTo().size() > 0 && transfer1.getLineId() == start.getLineId()) {
                // 直接换乘到终点线路
                if (transfer1.getTransferTo().contains(end.getLineId())) {
                    Station transferEnd = findStationByNameAndLine(transfer1.getName(), end.getLineId());
                    if (transferEnd != null) {
                        int count = Math.abs(start.getIndex() - transfer1.getIndex()) +
                                Math.abs(end.getIndex() - transferEnd.getIndex());
                        minStations = Math.min(minStations, count);
                    }
                }

                // 需要二次换乘
                for (Station transfer2 : allStations) {
                    if (transfer2.getTransferTo().size() > 0 &&
                            transfer2.getLineId() == end.getLineId() &&
                            !transfer2.getName().equals(transfer1.getName())) {
                        // 找到中间线路的换乘站
                        Station midTransfer1 = findStationByNameAndLine(transfer1.getName(), transfer1.getTransferTo().get(0));
                        Station midTransfer2 = findStationByNameAndLine(transfer2.getName(), midTransfer1 != null ? midTransfer1.getLineId() : -1);

                        if (midTransfer1 != null && midTransfer2 != null) {
                            int count = Math.abs(start.getIndex() - transfer1.getIndex()) +
                                    Math.abs(midTransfer1.getIndex() - midTransfer2.getIndex()) +
                                    Math.abs(end.getIndex() - transfer2.getIndex());
                            minStations = Math.min(minStations, count);
                        }
                    }
                }
            }
        }

        return minStations == Integer.MAX_VALUE ? 0 : minStations;
    }

    private Station findStationByNameAndLine(String name, int lineId) {
        for (Station station : allStations) {
            if (station.getName().equals(name) && station.getLineId() == lineId) {
                return station;
            }
        }
        return null;
    }

    private void setupSpinners() {
        List<String> stationNames = new ArrayList<>();
        for (Station station : allStations) {
            stationNames.add(station.getName() + "(" + allLines.get(station.getLineId() - 1).getName() + ")");
        }

        ArrayAdapter<String> adapter = new ArrayAdapter<>(
                this,
                android.R.layout.simple_spinner_item,
                stationNames
        );
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        spinnerStart.setAdapter(adapter);
        spinnerEnd.setAdapter(adapter);
    }

    private void setupListeners() {
        buttonCalculate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                calculateFare();
            }
        });

        buttonBuy.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "购票成功!", Toast.LENGTH_SHORT).show();
                resetForm();
            }
        });
    }

    private void resetForm() {
        spinnerStart.setSelection(0);
        spinnerEnd.setSelection(0);
        editTextTickets.setText("");
        textViewAmount.setText("");
        buttonBuy.setEnabled(false);
    }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="24dp"
    android:background="@color/white"
    tools:context=".MainActivity">

    <!-- 起点站选择 -->
    <TextView
        android:id="@+id/textViewStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="起点站"
        android:textSize="16sp"
        android:textColor="@color/black"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <Spinner
        android:id="@+id/spinnerStart"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:layout_marginTop="8dp"
        android:background="@drawable/spinner_background"
        android:paddingHorizontal="16dp"
        app:layout_constraintTop_toBottomOf="@id/textViewStart"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <!-- 终点站选择 -->
    <TextView
        android:id="@+id/textViewEnd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="终点站"
        android:textSize="16sp"
        android:textColor="@color/black"
        android:layout_marginTop="24dp"
        app:layout_constraintTop_toBottomOf="@id/spinnerStart"
        app:layout_constraintStart_toStartOf="parent" />

    <Spinner
        android:id="@+id/spinnerEnd"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:layout_marginTop="8dp"
        android:background="@drawable/spinner_background"
        android:paddingHorizontal="16dp"
        app:layout_constraintTop_toBottomOf="@id/textViewEnd"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <!-- 购票数量输入 -->
    <TextView
        android:id="@+id/textViewTickets"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="购票数量"
        android:textSize="16sp"
        android:textColor="@color/black"
        android:layout_marginTop="24dp"
        app:layout_constraintTop_toBottomOf="@id/spinnerEnd"
        app:layout_constraintStart_toStartOf="parent" />

    <EditText
        android:id="@+id/editTextTickets"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:layout_marginTop="8dp"
        android:hint="请输入购票数量"
        android:inputType="number"
        android:background="@drawable/edittext_background"
        android:paddingHorizontal="16dp"
        app:layout_constraintTop_toBottomOf="@id/textViewTickets"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <!-- 金额显示 -->
    <TextView
        android:id="@+id/textViewAmount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="单程费用:0元,总费用:0元"
        android:textSize="18sp"
        android:textColor="@color/black"
        android:layout_marginTop="24dp"
        app:layout_constraintTop_toBottomOf="@id/editTextTickets"
        app:layout_constraintStart_toStartOf="parent" />

    <!-- 计算金额按钮 -->
    <Button
        android:id="@+id/buttonCalculate"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:layout_marginTop="24dp"
        android:text="计算金额"
        android:textColor="@color/white"
        android:backgroundTint="@color/primary"
        android:textAllCaps="false"
        app:layout_constraintTop_toBottomOf="@id/textViewAmount"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <!-- 购买车票按钮 -->
    <Button
        android:id="@+id/buttonBuy"
        android:layout_width="0dp"
        android:layout_height="48dp"
        android:layout_marginTop="16dp"
        android:text="购买车票"
        android:textColor="@color/white"
        android:backgroundTint="@color/secondary"
        android:textAllCaps="false"
        android:enabled="false"
        app:layout_constraintTop_toBottomOf="@id/buttonCalculate"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

posted @ 2025-03-14 18:56  vivi_vimi  阅读(23)  评论(0)    收藏  举报