ArrayList в Java и ввод

Я привык к питону, поэтому меня это немного сбивает с толку. Я пытаюсь вводить данные построчно, пока пользователь не введет определенное число. Числа будут храниться в массиве для применения к ним некоторых статистических вычислений. В настоящее время у меня есть основной класс, классы статистики и класс чтения.

Два вопроса:

  1. Кажется, я не могу заставить работать цикл ввода, как лучше всего это сделать.

  2. Каким будет тип объекта для метода чтения? Двойной [] или ArrayList?

    1. Как объявить тип-метод Arraylist?

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

Любая помощь будет оценена по достоинству, простите за новичок ...

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
0
17 109
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Что вам нужно в вашем условии цикла:

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

Вы уменьшаете значение переменной счетчика.

Также вы должны объявить ArrayList так:

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

Это делает список зависящим от типа и позволяет заданное условие. Иначе будет лишний кастинг.

Вы должны использовать интерфейс List вместо ArrayList. Список <Double> list = новый ArrayList <Double> ();

Aaron 23.09.2008 00:00

Почему? Пока он возвращает список в конце, это не имеет значения.

Jason Cohen 23.09.2008 17:39

**

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"

}

  1. В Java хорошо использовать дженерики. Таким образом вы дадите компилятору и виртуальной машине подсказку о типах, которые собираетесь использовать. В этом случае это двойное значение, и, объявив результирующий список, содержащий двойные значения, вы можете использовать значения без преобразования типов / типов:

    if (!readRange.isEmpty()) {
        double last = readRange.get(readRange.size() - 1);
    }
    
  2. При работе с коллекциями Java лучше возвращать интерфейсы, так как существует множество реализаций конкретных списков (LinkedList, SynchronizedLists, ...). Поэтому, если позже вам понадобится другой тип списка, вы можете легко изменить конкретную реализацию внутри метода, и вам не нужно менять какой-либо дополнительный код.

  3. Вы можете задаться вопросом, почему оператор управления while работает, но, как вы видите, next = input.next (). trim () заключен в скобки. Таким образом, присвоение переменной происходит прямо перед условным тестированием. Также обрезка требует игры, чтобы избежать проблем с белым интервалом

  4. Я не использую здесь nextDouble (), потому что всякий раз, когда пользователь вводит что-то, кроме двойного, вы получаете исключение. Используя String, я могу анализировать любой ввод, который вводит пользователь, а также проверять сигнал окончания.

  5. Чтобы быть уверенным, что пользователь действительно ввел двойник, я использовал регулярное выражение из JavaDoc метода Double.valueOf (). Если это выражение совпадает, значение преобразуется, в противном случае будет напечатано сообщение об ошибке.

  6. Вы использовали счетчик по причинам, которых я не вижу в вашем коде. Если вы хотите узнать, сколько значений было успешно введено, просто вызовите readRange.size ().

  7. Если вы хотите работать с массивом, вторая часть конструктора показывает, как его преобразовать.

  8. Надеюсь, вас не смущает то, что я смешиваю double и Double, но благодаря функции Auto-Boxing в Java 1.5 это не проблема. И поскольку Scanner.next () никогда не вернет null (afaik), это вообще не должно быть проблемой.

  9. Если вы хотите ограничить размер массива, используйте

Хорошо, я надеюсь, что вы найдете мое решение и пояснения полезными, используйте result.size () в качестве индикатора и ключевое слово перемена, чтобы оставить оператор управления while.

Greetz, GHad

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

Расскажите подробнее о том, как это работает и какова логика.

Nasser Ali Karimi 11.06.2019 06:42

В ArrayList внутри угловой скобки (<>) мы можем определить тип данных и, соответственно, мы можем сохранить значение.

sagar_bhoi_188 11.06.2019 07:01

Другие вопросы по теме