java Java中的ArrayList和输入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/116276/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ArrayList in Java and inputting
提问by Octaflop
I'm used to python, so this is a bit confusing to me. I'm trying to take in input, line-by-line, until a user inputs a certain number. The numbers will be stored in an array to apply some statistical maths to them. Currently, I have a main class, the stats classes, and an "reading" class.
我习惯了python,所以这对我来说有点混乱。我正在尝试逐行输入,直到用户输入某个数字。这些数字将存储在一个数组中,以对它们应用一些统计数学。目前,我有一个主课、统计课和一个“阅读”课。
Two Questions:
两个问题:
I can't seem to get the input loop to work out, what's the best practice for doing so.
What is the object-type going to be for the reading method? A double[], or an ArrayList?
How do I declare method-type to be an arraylist?
How do I prevent the array from having more than 1000 values stored within it?
我似乎无法解决输入循环,这样做的最佳做法是什么。
读取方法的对象类型是什么?double[] 还是 ArrayList?
如何将方法类型声明为数组列表?
如何防止数组中存储超过 1000 个值?
Let me show what I have so far:
让我展示我到目前为止所拥有的:
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;
}
Any help would be appreciated, pardon my newbieness...
任何帮助将不胜感激,请原谅我的新手...
采纳答案by OscarRyz
Answers:
答案:
>1. I can't seem to get the input loop to work out, what's the best practice for doing so.
>1. 我似乎无法解决输入循环,这样做的最佳做法是什么。
I would rather have a simple while loop instead of a do{}while... and place the condition in the while... In my example it read:
我宁愿有一个简单的 while 循环而不是 do{}while... 并将条件放在 while... 在我的示例中它显示为:
while the read number is not end signal and count is lower than limit: do.
而读取的数量不是结束信号并且计数低于限制:做。
>2. What is the object-type going to be for the reading method? A double[], or an ArrayList?
>2. 读取方法的对象类型是什么?double[] 还是 ArrayList?
An ArrayList, however I would strongly recommend you to use List ( java.util.List ) interface instead. It is a good OO practice to program to the interface rather to the implementation.
一个 ArrayList,但是我强烈建议您改用 List ( java.util.List ) 接口。编程接口而不是实现是一个很好的 OO 实践。
>2.1How do I declare method-type to be an arraylist?
>2.1如何将method-type声明为arraylist?
See code below.
请参阅下面的代码。
>2.2. How do I prevent the array from having more than 1000 values stored within it?
>2.2. 如何防止数组中存储超过 1000 个值?
By adding this restriction in the while condition.
通过在 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;
}
}
Final remarks:
最后说明:
It is preferred to have "instance methods" than class methods. This way if needed the "readRange" could be handled by a subclass without having to change the signature, thus In the sample I've removed the "static" keyword an create an instance of "InputTest" class
“实例方法”比类方法更受欢迎。这样,如果需要,“readRange”可以由子类处理而无需更改签名,因此在示例中我删除了“static”关键字并创建了“InputTest”类的实例
In java code style the variable names should go in cammel case like in "endSignal" rather than "end_signal"
在 Java 代码风格中,变量名应该像“endSignal”而不是“end_signal”一样使用驼峰式大小写
回答by Jason Cohen
What you need in your loop condition is:
您在循环条件中需要的是:
while ( input.get( input.size()-1 ) != end_signal );
What you're doing is decrementing the counter variable.
您正在做的是递减计数器变量。
Also you should declare the ArrayListlike so:
你也应该这样声明ArrayList:
ArrayList<Double> list = new ArrayList<Double>();
This makes the list type-specific and allows the condition as given. Otherwise there's extra casting.
这使得列表类型特定并允许给定的条件。否则有额外的铸造。
回答by GHad
I think you started out not bad, but here is my suggestion. I'll highlight the important differences and points below the code:
我认为你一开始还不错,但这是我的建议。我将强调代码下方的重要差异和要点:
package console;
包控制台;
import java.util.; import java.util.regex.;
导入 java.util。; 导入 java.util.regex。;
public class ArrayListInput {
公共类 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"
}
}
In Java it's a good thing to use generics. This way you give the compiler and virtual machine a hint about the types you are about to use. In this case its double and by declaring the resulting List to contain double values, you are able to use the values without casting/type conversion:
if (!readRange.isEmpty()) { double last = readRange.get(readRange.size() - 1); }It's better to return Interfaces when working with Java collections, as there are many implementations of specific lists (LinkedList, SynchronizedLists, ...). So if you need another type of List later on, you can easy change the concrete implementation inside the method and you don't need to change any further code.
You may wonder why the while control statement works, but as you see, there are brackets around next = input.next().trim(). This way the variable assignment takes place right before the conditional testing. Also a trim takes playe to avoid whitespacing issues
I'm not using nextDouble()here because whenever a user would input something that's not a double, well, you will get an exception. By using String I'm able to parse whatever input a user gives but also to test against the end signal.
To be sure, a user really inputed a double, I used a regular expression from the JavaDoc of the Double.valueOf()method. If this expression matches, the value is converted, if not an error message will be printed.
You used a counter for reasons I don't see in your code. If you want to know how many values have been inputed successfully, just call readRange.size().
If you want to work on with an array, the second part of the constructor shows out how to convert it.
I hope you're not confused by me mixin up double and Double, but thanks to Java 1.5 feature Auto-Boxing this is no problem. And as Scanner.next()will never return null (afaik), this should't be a problem at all.
If you want to limit the size of the Array, use
在 Java 中,使用泛型是一件好事。通过这种方式,您可以向编译器和虚拟机提示您将要使用的类型。在这种情况下,它是 double 并且通过声明结果 List 包含 double 值,您可以使用这些值而无需强制转换/类型转换:
if (!readRange.isEmpty()) { double last = readRange.get(readRange.size() - 1); }使用 Java 集合时最好返回接口,因为有许多特定列表(LinkedList、SynchronizedLists 等)的实现。因此,如果您稍后需要另一种类型的 List,您可以轻松更改方法内部的具体实现,而无需更改任何进一步的代码。
您可能想知道 while 控制语句为何有效,但正如您所见,next = input.next().trim()周围有括号。这样,变量赋值就在条件测试之前发生。还需要进行修剪以避免空格问题
我在这里没有使用nextDouble(),因为每当用户输入不是双精度数的内容时,您就会得到一个异常。通过使用 String,我可以解析用户提供的任何输入,还可以针对结束信号进行测试。
可以肯定的是,用户确实输入了双精度值,我使用了Double.valueOf()方法的 JavaDoc 中的正则表达式。如果此表达式匹配,则转换该值,否则将打印错误消息。
由于我在您的代码中没有看到的原因,您使用了计数器。如果您想知道成功输入了多少个值,只需调用readRange.size()。
如果你想处理一个数组,构造函数的第二部分展示了如何转换它。
我希望你不会被我把 double 和 Double 搞混了,但多亏了 Java 1.5 的 Auto-Boxing 特性,这没问题。由于Scanner.next()永远不会返回 null (afaik),这根本不应该是一个问题。
如果要限制数组的大小,请使用
Okay, I hope you're finding my solution and explanations usefull, use result.size()as indicator and the keyword breakto leave the while control statement.
好的,我希望你发现我的解决方案和解释有用,使用result.size()作为指标和关键字break离开 while 控制语句。
Greetz, GHad
格雷茨,GHa
回答by user9103082
public static ArrayList<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;
}
回答by l_39217_l
**
**
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;
}
**
**

