【问题标题】:ArrayList in Java and inputtingJava中的ArrayList和输入
【发布时间】:2010-09-12 02:10:15
【问题描述】:

我习惯了 python,所以这让我有点困惑。我正在尝试逐行输入,直到用户输入某个数字。这些数字将存储在一个数组中,以便对其应用一些统计数学。目前,我有一个主类、统计类和一个“阅读”类。

两个问题:

  1. 我似乎无法让输入循环正常工作,这样做的最佳做法是什么。

  2. 读取方法的对象类型是什么? double[] 还是 ArrayList?

    1. 如何将方法类型声明为数组列表?

    2. 如何防止数组中存储超过 1000 个值?

让我展示一下我目前所拥有的:

public static java.util.ArrayList readRange(double end_signal){
    //read in the range and stop at end_signal

    ArrayList input = new ArrayList();
    Scanner kbd = new Scanner( System.in );
    int count = 0;
    do{
        input.add(kbd.nextDouble());
        System.out.println(input); //debugging
        ++count;
    } while(input(--count) != end_signal);
    return input;
}

任何帮助将不胜感激,请原谅我的新手......

【问题讨论】:

    标签: java arrays arraylist


    【解决方案1】:

    您在循环条件中需要的是:

    while ( input.get( input.size()-1 ) != end_signal );
    

    你正在做的是递减计数器变量。

    您还应该像这样声明ArrayList:

    ArrayList<Double> list = new ArrayList<Double>();
    

    这使得列表类型特定并允许给定条件。否则会有额外的演员表。

    【讨论】:

    • 您应该使用 List 接口而不是 ArrayList。 List list = new ArrayList();
    • 为什么?只要它最终返回一个 List 就没有关系。
    【解决方案2】:

    答案:

    >1.我似乎无法让输入循环正常工作,这样做的最佳做法是什么。

    我宁愿有一个简单的 while 循环而不是 do{}while... 并将条件放在 while... 在我的示例中它是:

    当读取数不是结束信号且计数低于限制时:做。

    >2.阅读方法的对象类型是什么? double[] 还是 ArrayList?

    一个 ArrayList,但是我强烈建议您改用 List (java.util.List) 接口。对接口进行编程而不是对实现进行编程是一种很好的 OO 实践。

    >2.1如何将method-type声明为arraylist?

    参见下面的代码。

    >2.2.如何防止数组中存储超过 1000 个值?

    通过在 while 条件中添加此限制。

    import java.util.Scanner;
    import java.util.List;
    import java.util.ArrayList;
    
    public class InputTest{
        
        private int INPUT_LIMIT = 10000;
    
        public static void main( String [] args ) {
            InputTest test = new InputTest();
            System.out.println("Start typing numbers...");
            List list = test.readRange( 2.0 );
            System.out.println("The input was " +  list );
        }
    
        /**
         * Read from the standar input until endSignal number is typed.
         * Also limits the amount of entered numbers to 10000;
         * @return a list with the numbers.
         */
        public List readRange( double endSignal ) {
            List<Double> input = new ArrayList<Double>();
            Scanner kdb = new Scanner( System.in );
            int count = 0;
            double number = 0;
            while( ( number = kdb.nextDouble() ) != endSignal && count < INPUT_LIMIT ){
                System.out.println( number );
                input.add( number );
            }
            return input;
        }
    }
    

    最后的评论:

    最好使用“实例方法”而不是类方法。这样,如果需要,“readRange”可以由子类处理而无需更改签名,因此在示例中我删除了“static”关键字并创建“InputTest”类的实例

    在 java 代码风格中,变量名应该像“endSignal”而不是“end_signal”一样采用驼峰式大小写

    【讨论】:

      【解决方案3】:

      我认为你开始的时候还不错,但这是我的建议。我将在代码下方突出显示重要的区别和要点:

      包控制台;

      导入 java.util.; 导入 java.util.regex.;

      公共类 ArrayListInput {

      public ArrayListInput() {
          // as list
          List<Double> readRange = readRange(1.5);
      
          System.out.println(readRange);
          // converted to an array
          Double[] asArray = readRange.toArray(new Double[] {});
          System.out.println(Arrays.toString(asArray));
      }
      
      public static List<Double> readRange(double endWith) {
          String endSignal = String.valueOf(endWith);
          List<Double> result = new ArrayList<Double>();
          Scanner input = new Scanner(System.in);
          String next;
          while (!(next = input.next().trim()).equals(endSignal)) {
              if (isDouble(next)) {
                  Double doubleValue = Double.valueOf(next);
                  result.add(doubleValue);
                  System.out.println("> Input valid: " + doubleValue);
              } else {
                  System.err.println("> Input invalid! Try again");
              }
          }
          // result.add(endWith); // uncomment, if last input should be in the result
          return result;
      }
      
      public static boolean isDouble(String in) {
          return Pattern.matches(fpRegex, in);
      }
      
      public static void main(String[] args) {
          new ArrayListInput();
      }
      
      private static final String Digits = "(\\p{Digit}+)";
      private static final String HexDigits = "(\\p{XDigit}+)";
      // an exponent is 'e' or 'E' followed by an optionally
      // signed decimal integer.
      private static final String Exp = "[eE][+-]?" + Digits;
      private static final String fpRegex = ("[\\x00-\\x20]*" + // Optional leading "whitespace"
              "[+-]?(" + // Optional sign character
              "NaN|" + // "NaN" string
              "Infinity|" + // "Infinity" string
      
              // A decimal floating-point string representing a finite positive
              // number without a leading sign has at most five basic pieces:
              // Digits . Digits ExponentPart FloatTypeSuffix
              // 
              // Since this method allows integer-only strings as input
              // in addition to strings of floating-point literals, the
              // two sub-patterns below are simplifications of the grammar
              // productions from the Java Language Specification, 2nd
              // edition, section 3.10.2.
      
              // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
              "(((" + Digits + "(\\.)?(" + Digits + "?)(" + Exp + ")?)|" +
      
              // . Digits ExponentPart_opt FloatTypeSuffix_opt
              "(\\.(" + Digits + ")(" + Exp + ")?)|" +
      
              // Hexadecimal strings
              "((" +
              // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
              "(0[xX]" + HexDigits + "(\\.)?)|" +
      
              // 0[xX] HexDigits_opt . HexDigits BinaryExponent
              // FloatTypeSuffix_opt
              "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" +
      
              ")[pP][+-]?" + Digits + "))" + "[fFdD]?))" + "[\\x00-\\x20]*");// Optional
                                                                              // trailing
                                                                              // "whitespace"
      

      }

      1. 在 Java 中,使用泛型是一件好事。这样,您就可以向编译器和虚拟机提示您将要使用的类型。在这种情况下,它的 double 并通过声明结果 List 包含 double 值, 您无需转换/类型转换即可使用这些值:

        if (!readRange.isEmpty()) {
            double last = readRange.get(readRange.size() - 1);
        }
        
      2. 在使用 Java 集合时最好返回接口,因为有许多特定列表的实现(LinkedList、SynchronizedLists、...)。因此,如果您稍后需要另一种类型的 List,您可以轻松更改方法内部的具体实现,而无需更改任何进一步的代码。

      3. 您可能想知道为什么 while 控制语句有效,但正如您所见,next = input.next().trim() 周围有括号。这样,变量赋值就发生在条件测试之前。还可以进行修剪以避免空白问题

      4. 我没有在此处使用 nextDouble(),因为每当用户输入非双精度的内容时,您都会遇到异常。通过使用字符串,我可以解析用户提供的任何输入,还可以针对结束信号进行测试。

      5. 可以肯定的是,用户确实输入了双精度,我使用了 Double.valueOf() 方法的 JavaDoc 中的正则表达式。如果此表达式匹配,则转换该值,否则将打印错误消息。

      6. 您使用计数器的原因我在您的代码中没有看到。如果您想知道成功输入了多少个值,只需调用 readRange.size()。

      7. 如果你想处理一个数组,构造函数的第二部分展示了如何转换它。

      8. 我希望你不会被我混淆 double 和 Double,但是感谢 Java 1.5 的 Auto-Boxing 特性,这没有问题。由于 Scanner.next() 永远不会返回 null (afaik),这应该不是问题。

      9. 如果要限制Array的大小,使用

      好的,我希望你发现我的解决方案和解释有用,使用 result.size() 作为指示符和关键字 break 离开 while 控制语句。

      Greetz,加德

      【讨论】:

        【解决方案4】:

        **

        public static java.util.ArrayList readRange(double end_signal) {
        
            //read in the range and stop at end_signal
        
            ArrayList input = new ArrayList();
        
            Scanner kbd = new Scanner(System. in );
            int count = 0;
        
            do {
                input.add(Double.valueOf(kbd.next()));
                System.out.println(input); //debugging
                ++count;
            } while (input(--count) != end_signal);
            return input;
        }
        

        **

        【讨论】:

          【解决方案5】:
          public static ArrayList&lt;Double> readRange(double end_signal) {
          
              ArrayList<Double> input = new ArrayList<Double>();
              Scanner kbd = new Scanner( System.in );
              int count = 0;
              do{
                  input.add(kbd.nextDouble());
                  ++count;
              } while(input(--count) != end_signal);
          return input;
          }
          

          【讨论】:

          • 详细说明它的工作原理和逻辑
          • 在ArrayList中的尖括号()我们可以定义数据类型,相应地我们可以存储值。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-31
          相关资源
          最近更新 更多