【问题标题】:Boolean value cant convert to string布尔值不能转换为字符串
【发布时间】:2021-05-07 06:28:12
【问题描述】:

我正在编写一个程序,根据速度限制计算超速罚单成本,但最重要的是,如果他们在学区,并且我在公共(罚单)作为我的布尔值时遇到麻烦

   if (schoolZone.equals("Y")) {
          schoolZone = true;
       } else {
          schoolZone = false;
       }
   }

不会工作。它似乎无法将其转换为字符串值,我正在寻求帮助,因为我对计算机科学还很陌生

      public class Ticket {
    
       /*
       * Instance variable for ticket
       */
       private String name, TDL, address, city, state, zip;
    
       private int postedSpeed, travelling, ticketAmount, day, month, year;
    
       private boolean schoolZone;
    
       // default constructor
       public Ticket() {
    
       }
    
       // parameterized constructor
       public Ticket(String name, String tDL, String address, String city, String state, String zip, int postedSpeed,
               int travelling, int ticketAmount, int day, int month, int year, String schoolZone) {
           name = name;
           TDL = tDL;
           address = address;
           city = city;
           state = state;
           zip = zip;
           postedSpeed = postedSpeed;
           travelling = travelling;
           ticketAmount = ticketAmount;
           day = day;
           month = month;
           year = year;
           if (schoolZone.equals("Y")) {    
               schoolZone = true;
           } else {
               schoolZone = false;
           }
       }
    
       // calculate ticket
       public void calTicket() {
    
           double fine = 0.0;
           if (travelling > (postedSpeed + 30) && schoolZone == true) {
    
               fine = 2 * (6 * (travelling - postedSpeed) + 160 + ticketAmount);
           } else if (travelling > postedSpeed && schoolZone == true) {
    
               fine = 2 * (6 * (travelling - postedSpeed) + ticketAmount);
           } else if (travelling > (postedSpeed + 30)) {
    
               fine = ticketAmount + 160 + 6 * (travelling - postedSpeed);
           } else if (travelling > postedSpeed) {
    
               fine = ticketAmount + 6 * (travelling - postedSpeed);
           } else if (travelling < postedSpeed) {
    
               fine = 0;
           }
           if (schoolZone == true) {
               System.out.println("Dear Citizen Knight,\n" + "You have received this citation for driving " + travelling
                       + " mph in an area with a posted speed limit of " + postedSpeed + ".\r\n" + "\r\n"
                       + "This violation occurred in a school zone.\r\n" + "\r\n" + "Your fine is $" + fine
                       + " and can be paid at the address below.\r\n" + "\r\n"
                       + "Please remember to buckle up and drive safely.");
           } else {
    
               System.out.println("Dear Citizen Knight,\n" + "You have received this citation for driving " + travelling
                       + " mph in an area with a posted speed limit of " + postedSpeed + ".\r\n" + "\r\n"
                       + "This violation didn't occurred in a school zone.\r\n" + "\r\n" + "Your fine is $" + fine
                       + " and can be paid at the address below.\r\n" + "\r\n"
                       + "Please remember to buckle up and drive safely.");
           }
       }
    
       // return last name
       public String lastName() {
    
           String[] names = name.split("\\s+");
           return names[names.length - 1];
       }
    
       // toString method to get details
       public String toString() {
    
           return month + "/" + day + "/" + year + "\n" + name + "(TDL: " + TDL + ")\n" + address + "\n" + city + ", "
                   + state + ", " + zip + "\n";
       }
    }
    
    
    
    //Runner
    import java.util.Scanner;
    
    public class TicketRunner {
    
       public static void main(String[] args) {
    
           //Scanner object
           Scanner keyboard = new Scanner(System.in);
    
           //printing programmer details
           System.out.println("The Speeding Ticket Program");
           System.out.println();
           System.out.println("By: John Smith");
    
           System.out.println("\n===================================\n");
    
           //input driver data
           System.out.print("Name of Driver? --> ");
           String name = keyboard.nextLine();
            
             System.out.print("TDL? -->");
           String tdl = keyboard.nextLine();
           
           System.out.print("Address? -->");
           String address = keyboard.nextLine();
          
           System.out.print("City? -->");
           String city = keyboard.nextLine();
           
           System.out.print("State? -->");
           String state = keyboard.nextLine();
          
           System.out.print("Zip? -->");
           String zip = keyboard.nextLine();
          
           System.out.print("Did the violation occur in a school zone? {Y/N} -->");
           String zone = keyboard.nextLine();
    
           System.out.println("Date of Violation:");
    
           System.out.print("Month (number)? --> ");
           int month = keyboard.nextInt();
           System.out.print("Day? -->");
           int day = keyboard.nextInt();
           System.out.print("Year? -->");
           int year = keyboard.nextInt();
           System.out.print("What is the posted speed limit? -->");
           int postedSpeed = keyboard.nextInt();
           System.out.print("How fast was the car travelling in mph? --> ");
           int travelling = keyboard.nextInt();
    
           //instantiate ticket
           Ticket ticket = new Ticket(name, tdl, address, city, state, zip, postedSpeed, travelling, 75, day, month, year,
                   zone);
    
           //print ticket details
           System.out.println(ticket.toString());
           ticket.calTicket();
           keyboard.close();//close scanner
       }
    }
    /********************output******************/

【问题讨论】:

    标签: java string boolean output


    【解决方案1】:

    在构造函数上设置字段时,您应该包含 this 关键字。要解决您的问题,请使用以下代码:

    if (schoolZone.equals("Y")) {
        this.schoolZone = true;
    } else {
        this.schoolZone = false;
    }
    

    请注意,参数中的 schoolZone 位于 String 中,而您的类中的 schoolZone 位于 boolean 中。在您的构造函数中发生的情况是 String 类型中的参数 schoolZone 被设置为布尔值,这显然是行不通的。

    【讨论】:

    • 还有更好的:this.schoolZone = schoolZone.equals("Y");
    【解决方案2】:

    您的基本问题称为名称阴影。 在java中你基本上可以有三种不同类型的变量:

    1. 成员变量(静态或非静态)
    2. 参数变量
    3. 方法变量(方法内部) 因为它们都与相同的物质有关,所以它们也恰好具有相同的确切名称是很常见的。因此您会遇到名称冲突和阴影。

    我个人的解决方案是:

    • 对编译器使用严格的警告
    • 为我的变量添加前缀,如下所示

    我的班级布局和变量前缀

    • 静态最终“变量”,例如常量
    • 静态内部类、接口等静态结构
    • 静态变量,以's'为前缀
    • 静态方法
    • 非静态内部类等
    • 图形/UI 的最终成员变量,前缀为 g 或 c,用于一般图形和控件
    • 图形/UI 的非最终成员变量,前缀为 g 或 c,用于一般图形和控件
    • 逻辑的最终成员变量(即普通成员变量),以 m 为前缀
    • 逻辑的非最终成员变量(即普通成员变量),以 m 为前缀
    • 构造函数
    • 初始化方法
    • 覆盖 toString()、hashCode()、equals() 等方法
    • 简单的 getter 和 setter(C#:属性方法)
    • 核心逻辑方法

    另外,我在方法参数前面加上

    • p 代表参数(= @NonNull, @NotNull)
    • o 表示可选 (@Nullable)
    • r 用于返回/输出值(C#,或要写入的状态对象,如累加器列表等)

    注意:我的代码中关于静态/非静态的最大区别。 通常我将该代码分成两个文件/类,除非它只有 1 个变量和 1 个方法,或者绝对有必要在以对象为中心的类中包含静态代码。 对于初学者来说,静态陷阱通常是最邪恶问题的根源。

    我做的前缀对我很有帮助。 我的 IDE 中有非常严格的警告规则,其中之一是 NAME SHADOWING。 我还设置了 Eclipse 自动生成前缀。

    但其他人可能会发现这种风格有阻碍或只是丑陋。 了解您的团队使用什么,适应。如果您自己编写代码,请考虑一下,尝试一下,也许您会找到自己喜欢的东西。

    以下是按照我的风格重新编写的代码,以及一些提示:

    package stackoverflow;
    
    import java.text.DecimalFormat;
    import java.util.Objects;
    
    public class Ticket {
    
        static public String toLastName(final String pFullName) {
            if (pFullName == null) return null; // fail fast, fail early: we could also throw an exception here
    
            final String[] names = pFullName.split("\\s+");
            return names[names.length - 1];
        }
    
    
    
    
        /*
        * Instance variable for ticket
        */
        // if member variables are truly immutable, and you can have them final, then you can make em public final, so you dont need getters
        // BUT: if you're planning on using advanced Java features, with bytecode manipulation, reflection, like Java EE or aspect-oriented libraries,
        // you better stick to the getter/setters at all times
        public final String     mTDL;
        public final String     mAddress;
        public final String     mCity;
        public final String     mState;
        public final String     mZipCode;
        public final int        mPostedSpeedMph;
        public final int        mTravellingSpeedMph;
        public final int        mTicketAmount;
        public final int        mDay;
        public final int        mMonth;
        public final int        mYear;
        public final boolean    mSchoolZone;
    
        private String mName; // name can be changed du to marriage
    
        // default constructor
        // public Ticket() {} // this will not create a valid state, so we leave it out unless it's essential
        // if it's truly essential to your code, use a flag and a getter to see if you're interacting with valid objects
    
        // parameterized constructor
        public Ticket(final String pName, final String pTDL, final String pAddress, final String pCity, final String pState, final String pZipCode,
                final int pPostedSpeedMph, final int pTravellingSpeedMph, final int pTicketAmount,
                final int pDay, final int pMonth, final int pYear, final String pSchoolZone) {
            mName = pName;
            mTDL = pTDL;
            mAddress = pAddress;
            mCity = pCity;
            mState = pState;
            mZipCode = pZipCode;
            mPostedSpeedMph = pPostedSpeedMph; // it's better to explicitly name the unit. keeps you and others out of trouble
            mTravellingSpeedMph = pTravellingSpeedMph; // especially interesting in time units: is this parameter in seconds or milliseconds?
            mTicketAmount = pTicketAmount;
            mDay = pDay;
            mMonth = pMonth;
            mYear = pYear;
            mSchoolZone = "Y".equals(pSchoolZone); // use one-line assignments and conditionals when possible
            // also when trying to match two strings, beware of the NullPointerException. Having constants as first operand dodges that problem
        }
    
    
    
        public String getName() { // simple getter, for the only non-final member variable
            return mName;
        }
    
    
    
        // calculate ticket
        public void calcTicket() {
            final double fine = calcFine();
            final DecimalFormat df = new DecimalFormat("#.##"); // kicking a raw float to the string might get ugly results at times.
            // use dedicated formatting to prevent that
    
            final String schoolZoneText = mSchoolZone ? "This violation occurred in a school zone." : "This violation did not occurr in a school zone.";
            final String output = "Dear Citizen Knight " + getName() + ",\n\n"
                    + "You have received this citation for driving " + mTravellingSpeedMph
                    + " mph in an area with a posted speed limit of " + mPostedSpeedMph + ".\r\n"
                    + "\r\n"
                    + schoolZoneText + "\r\n"
                    + "\r\n" + "Your fine is $" + df.format(fine) + " and can be paid at the address below.\r\n"
                    + "\r\n"
                    + "Please remember to buckle up and drive safely.";
            /* HINT: do NOT mix \n and \r\n and \n\r and \r newlines! Stick to one. Java tries to works with \n alone.
             * Unless it's too much of a hassle, try to convert to \n, then work with \n internally and only re-convert at output,
             * if you need specific newline control.
             * Also, its is easier if you have the text somewhat outlined like the output is supposed to be displayed
             */
    
            System.out.println(output);
    
            // I left a remnant of your old code to tell you sth else:
            //if (mSchoolZone) { // if(true==true) is a bit overkill, if(true) usually suffices
        }
    
        public int calcFine() { // have this as its own method, to it is more focused and can be used from other places too, f conventient
            // early return approach: jump back as soon as solution is done. this way it is easier for the compiler to see problems and warn you.
            // here are also lots of magic numbers, that in other cases should be replaced by constants
            if (mTravellingSpeedMph > (mPostedSpeedMph + 30) && mSchoolZone == true) return 2 * (6 * (mTravellingSpeedMph - mPostedSpeedMph) + 160 + mTicketAmount);
            else if (mTravellingSpeedMph > mPostedSpeedMph && mSchoolZone == true) return 2 * (6 * (mTravellingSpeedMph - mPostedSpeedMph) + mTicketAmount);
            else if (mTravellingSpeedMph > (mPostedSpeedMph + 30)) return mTicketAmount + 160 + 6 * (mTravellingSpeedMph - mPostedSpeedMph);
            else if (mTravellingSpeedMph > mPostedSpeedMph) return mTicketAmount + 6 * (mTravellingSpeedMph - mPostedSpeedMph);
            // else if (mTravelling < mPostedSpeed) return 0; we actually do not even need this line
            return 0; // my compiler told me we need this, so then I realized the line above was redundant
        }
    
        // return last name
        public String getLastName() { // we call them GETTERS and SETTERS
            return toLastName(mName);
        }
    
        // toString method to get details
        @Override public String toString() { // do not forget annotations like @Override etc, they may hint at possible problems
            return mMonth + "/" + mDay + "/" + mYear + "\n" + mName + "(TDL: " + mTDL + ")\n" + mAddress + "\n" + mCity + ", "
                    + mState + ", " + mZipCode + "\n";
        }
    
        /*
         * Here a fine little method that shows where my prefixing really helps.
         * Of course, I bent the naming to showcase this.
         */
        public String takeLastName(final String pName) { // in case of marriage
            final String name = toLastName(pName);
            final String[] myNameParts = mName.split("\\s+");
            myNameParts[myNameParts.length - 1] = name;
            mName = String.join(" ", myNameParts);
            return mName;
        }
        public boolean hasSameLastNameAs(final String pOtherName) {
            final String otherLastName = toLastName(pOtherName);
            final String myLastName = toLastName(mName);
            return Objects.equals(otherLastName, myLastName);
        }
    
    
    
        public static void main(final String[] args) {
            final Ticket t = new Ticket("Peter Lustig", null, null, null, null, null, 30, 60, 2, 14, 1, 2021, "Y");
            t.calcTicket();
            t.takeLastName("Hans Dampf");
            System.out.println("\n\n\nAfter his marriage, he is now called " + t.getName());
    
        }
    
    }
    

    【讨论】:

    • 我喜欢你的风格
    【解决方案3】:

    完全同意 Donato,必须在左侧的构造函数中使用“this”来访问类变量并正确设置这些变量,否则传递的参数会将其设置为自身。

    【讨论】:

      【解决方案4】:

      当通过构造函数引用实例变量时,(有时也通过方法)你应该使用this关键字。它向编译器暗示您指的是实例变量而不是局部变量。

      在您的情况下,局部变量 schoolZone 的类型为 String,而实例变量 schoolZone 的类型为 boolean。所以你的代码必须如下所示。

      if (schoolZone.equalsIgnoreCase("Y")) {
          this.schoolZone = true;          
      } else {       
          this.schoolZone = false;
      }
      

      附: : 我的意见是使用equalsIgnoreCase() 而不是equals(),因为用户也可以输入小写的“Y”或“N”。

      因此,您的整个constructor 必须按以下方式进行编辑。

      // parameterized constructor
         public Ticket(String name, String tDL, String address, String city, String state, 
                       String zip, int postedSpeed, int travelling, int ticketAmount, int day, 
                       int month, int year, String schoolZone) {
             this.name = name;
             this.TDL = tDL;
             this.address = address;
             this.city = city;
             this.state = state;
             this.zip = zip;
             this.postedSpeed = postedSpeed;
             this.travelling = travelling;
             this.ticketAmount = ticketAmount;
             this.day = day;
             this.month = month;
             this.year = year;
      
             if (schoolZone.equalsIgnoreCase("Y")) {
                this.schoolZone = true;
             } else {
                 this.schoolZone = false;
             }
         }
      

      【讨论】:

        猜你喜欢
        • 2016-06-16
        • 2018-09-07
        • 1970-01-01
        • 2013-01-24
        • 2012-03-10
        • 2012-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多