Я привык к питону, поэтому меня это немного сбивает с толку. Я пытаюсь вводить данные построчно, пока пользователь не введет определенное число. Числа будут храниться в массиве для применения к ним некоторых статистических вычислений. В настоящее время у меня есть основной класс, классы статистики и класс чтения.
Два вопроса:
Кажется, я не могу заставить работать цикл ввода, как лучше всего это сделать.
Каким будет тип объекта для метода чтения? Двойной [] или ArrayList?
Как объявить тип-метод Arraylist?
Как сделать так, чтобы в массиве не сохранялось более 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 ... В моем примере это читалось так:
в то время как число чтения не является сигналом окончания, а количество меньше предела: do.
> 2. Каким будет тип объекта для метода чтения? Двойной [] или ArrayList?
ArrayList, однако я настоятельно рекомендую вам использовать вместо него интерфейс List (java.util.List). Хорошей практикой объектно-ориентированного программирования является программирование интерфейса, а не реализации.
> 2.1 Как мне объявить тип-метод arrayylist?
См. Код ниже.
> 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"
Думаю, вы начали неплохо, но вот мое предложение. Я выделю важные отличия и моменты под кодом:
пакетная консоль;
import 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 хорошо использовать дженерики. Таким образом вы дадите компилятору и виртуальной машине подсказку о типах, которые собираетесь использовать. В этом случае это двойное значение, и, объявив результирующий список, содержащий двойные значения, вы можете использовать значения без преобразования типов / типов:
if (!readRange.isEmpty()) {
double last = readRange.get(readRange.size() - 1);
}
При работе с коллекциями Java лучше возвращать интерфейсы, так как существует множество реализаций конкретных списков (LinkedList, SynchronizedLists, ...). Поэтому, если позже вам понадобится другой тип списка, вы можете легко изменить конкретную реализацию внутри метода, и вам не нужно менять какой-либо дополнительный код.
Вы можете задаться вопросом, почему оператор управления while работает, но, как вы видите, next = input.next (). trim () заключен в скобки. Таким образом, присвоение переменной происходит прямо перед условным тестированием. Также обрезка требует игры, чтобы избежать проблем с белым интервалом
Я не использую здесь nextDouble (), потому что всякий раз, когда пользователь вводит что-то, кроме двойного, вы получаете исключение. Используя String, я могу анализировать любой ввод, который вводит пользователь, а также проверять сигнал окончания.
Чтобы быть уверенным, что пользователь действительно ввел двойник, я использовал регулярное выражение из JavaDoc метода Double.valueOf (). Если это выражение совпадает, значение преобразуется, в противном случае будет напечатано сообщение об ошибке.
Вы использовали счетчик по причинам, которых я не вижу в вашем коде. Если вы хотите узнать, сколько значений было успешно введено, просто вызовите readRange.size ().
Если вы хотите работать с массивом, вторая часть конструктора показывает, как его преобразовать.
Надеюсь, вас не смущает то, что я смешиваю double и Double, но благодаря функции Auto-Boxing в Java 1.5 это не проблема. И поскольку Scanner.next () никогда не вернет null (afaik), это вообще не должно быть проблемой.
Если вы хотите ограничить размер массива, используйте
Хорошо, я надеюсь, что вы найдете мое решение и пояснения полезными, используйте result.size () в качестве индикатора и ключевое слово перемена, чтобы оставить оператор управления while.
Greetz, GHad
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;
}
Расскажите подробнее о том, как это работает и какова логика.
В ArrayList внутри угловой скобки (<>) мы можем определить тип данных и, соответственно, мы можем сохранить значение.
Вы должны использовать интерфейс List вместо ArrayList. Список <Double> list = новый ArrayList <Double> ();