Java中的ArrayList和输入

时间:2020-03-06 14:33:09  来源:igfitidea点击:

我已经习惯了python,所以这让我有些困惑。我试图逐行接受输入,直到用户输入特定数字为止。这些数字将存储在数组中,以对它们应用一些统计数学。目前,我有一个主类,一个stats类和一个" reading"类。

两个问题:

  • 我似乎无法解决输入循环问题,这样做的最佳实践是什么。
  • 如何防止数组中存储超过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;
}

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

解决方案

在循环条件中需要的是:

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

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

你也应该像这样声明ArrayList

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

这使得列表类型特定,并允许给出条件。否则会有额外的转换。

**

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

**

答案:

  1. 我似乎无法解决输入循环问题,这样做的最佳实践是什么。

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

当读取的数字不是结束信号并且计数低于限制时:执行。

  1. 读取方法的对象类型是什么?一个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代码样式中,变量名称应使用cammel格式,例如" endSignal"而不是" end_signal"

我认为我们起步不错,但这是我的建议。我将在代码下面突出显示重要的区别和要点:

软件包控制台;

导入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"

}

  • 在Java中,使用泛型是一件好事。这样,我们就可以为编译器和虚拟机提供有关要使用的类型的提示。在这种情况下,它是double值,并且通过声明结果List包含double值,则可以使用这些值而无需强制转换/类型转换:
if (!readRange.isEmpty()) {
    double last = readRange.get(readRange.size() - 1);
}
  • 使用Java集合时最好返回接口,因为有许多特定列表的实现(LinkedList,SynchronizedLists等)。因此,如果以后需要另一种类型的List,则可以轻松地更改方法内部的具体实现,而无需更改任何其他代码。
  • 我们可能想知道while控制语句为什么起作用,但是如我们所见,next = input.next()。trim()周围有方括号。这样,变量分配就在条件测试之前进行。修剪饰边也可以避免白间距问题
  • 我不在这里使用nextDouble(),因为每当用户输入不是double的内容时,我们都会得到一个异常。通过使用String,我可以解析用户提供的任何输入,还可以根据结束信号进行测试。
  • 可以肯定的是,用户确实输入了double,因此我使用了Double.valueOf()方法的JavaDoc中的正则表达式。如果此表达式匹配,则将转换该值,否则将打印错误消息。
  • 我们使用计数器是出于我在代码中看不到的原因。如果我们想知道已经成功输入了多少个值,只需调用readRange.size()。
  • 如果要处理数组,则构造函数的第二部分将说明如何进行转换。
  • 我希望我们不要被我混淆为double和Double,但是由于Java 1.5的自动装箱功能,这没问题。而且由于Scanner.next()永远不会返回null(afaik),所以这根本不是问题。
  • 如果要限制数组的大小,请使用

好的,我希望我们对我的解决方案和解释有所帮助,使用result.size()作为指标,使用关键字break留下while控制语句。

加的特Greetz