6

我习惯了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;
}

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

4

5 回答 5

5

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

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

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

你也应该ArrayList这样声明:

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

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

于 2008-09-22T17:34:12.547 回答
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”一样采用驼峰式大小写

于 2008-09-22T18:15:37.533 回答
0

**

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;
}

**

于 2008-09-22T17:36:20.420 回答
0

我认为您开始时还不错,但这是我的建议。我将强调代码下方的重要区别和要点:

包控制台;

导入 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. 如果要限制数组的大小,请使用

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

格瑞兹,GHad

于 2008-09-22T18:16:48.607 回答
0
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;
}
于 2019-06-11T03:33:56.063 回答