Domanda

Sono abituato a Python, quindi questo mi confonde un po '. Sto cercando di inserire input, riga per riga, fino a quando un utente immette un determinato numero. I numeri verranno memorizzati in un array per applicare ad essi alcuni calcoli statistici. Al momento, ho una classe principale, le classi delle statistiche e una "lettura" Classe.

Due domande:

  1. Non riesco a far funzionare il ciclo di input, qual è la migliore pratica per farlo.

  2. Quale sarà il tipo di oggetto per il metodo di lettura? Una doppia [] o una ArrayList?

    1. Come posso dichiarare che il metodo-tipo è un arraylist?

    2. Come posso evitare che l'array contenga più di 1000 valori al suo interno?

Lasciami mostrare quello che ho finora:

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

Qualsiasi aiuto sarebbe apprezzato, scusate la mia novità ...

È stato utile?

Soluzione

Le risposte:

> 1. Non riesco a far funzionare il ciclo di input, qual è la migliore pratica per farlo.

Preferirei avere un semplice ciclo while anziché un do {} while ... e posizionare la condizione nel frattempo ... Nel mio esempio si legge:

mentre il numero letto non è il segnale di fine e il conteggio è inferiore al limite: fare.

> 2. Quale sarà il tipo di oggetto per il metodo di lettura? Una doppia [] o una ArrayList?

Un ArrayList, tuttavia ti consiglio caldamente di usare invece l'interfaccia List (java.util.List). È buona norma OO programmare l'interfaccia piuttosto che l'implementazione.

> 2.1 Come posso dichiarare che il metodo-tipo è un arraylist?

Vedi il codice qui sotto.

> 2.2. Come posso evitare che l'array contenga più di 1000 valori al suo interno?

Aggiungendo questa restrizione nella condizione 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;
    }
}

Osservazioni finali:

Si preferisce avere "metodi di istanza" rispetto ai metodi di classe. In questo modo, se necessario, il campo "readRange" potrebbe essere gestito da una sottoclasse senza dover modificare la firma, quindi nel campione ho rimosso la "statica" parola chiave e creare un'istanza di " InputTest " classe

Nello stile del codice java i nomi delle variabili devono essere inseriti nel caso cammel come in "endSignal" anziché " end_signal "

Altri suggerimenti

Quello che ti serve nella condizione del tuo ciclo è:

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

Quello che stai facendo è decrementare la variabile contatore.

Inoltre dovresti dichiarare ArrayList in questo modo:

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

Questo rende specifico il tipo di elenco e consente la condizione fornita. Altrimenti c'è un casting extra.

Penso che tu abbia iniziato non male, ma ecco il mio suggerimento. Metterò in evidenza le differenze e i punti importanti sotto il codice:

console del pacchetto;

import java.util. ; import java.util.regex. ;

ArrayListInput di classe pubblica {

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. In Java è una buona cosa usare generici. In questo modo dai al compilatore e alla macchina virtuale un suggerimento sui tipi che stai per usare. In questo caso è doppio e dichiarando che l'elenco risultante contiene valori doppi, sei in grado di utilizzare i valori senza conversione di cast / type:

    if (!readRange.isEmpty()) {
        double last = readRange.get(readRange.size() - 1);
    }
    
  2. È meglio restituire le interfacce quando si lavora con raccolte Java, poiché esistono molte implementazioni di elenchi specifici (LinkedList, SynchronizedLists, ...). Quindi, se hai bisogno di un altro tipo di Elenco in un secondo momento, puoi facilmente cambiare l'implementazione concreta all'interno del metodo e non è necessario cambiare altro codice.

  3. Potresti chiederti perché la dichiarazione di controllo while funziona, ma come vedi ci sono parentesi attorno a next = input.next (). trim () . In questo modo l'assegnazione delle variabili avviene subito prima del test condizionale. Anche un assetto richiede attenzione per evitare problemi di spaziatura

  4. Non sto usando nextDouble () qui perché ogni volta che un utente inserisce qualcosa che non è un doppio, beh, otterrai un'eccezione. Utilizzando String sono in grado di analizzare qualsiasi input fornito da un utente, ma anche di testare il segnale finale.

  5. Per essere sicuro, un utente ha davvero inserito un doppio, ho usato un'espressione regolare da JavaDoc del metodo Double.valueOf () . Se questa espressione corrisponde, il valore viene convertito, in caso contrario verrà stampato un messaggio di errore.

  6. Hai usato un contatore per motivi che non vedo nel tuo codice. Se vuoi sapere quanti valori sono stati inseriti correttamente, chiama readRange.size().

  7. Se vuoi lavorare con un array, la seconda parte del costruttore mostra come convertirlo.

  8. Spero che tu non sia confuso da me mescolando doppio e doppio, ma grazie alla funzione Auto-Boxing di Java 1.5 questo non è un problema. E poiché Scanner.next () non restituirà mai null (afaik), questo non dovrebbe essere affatto un problema.

  9. Se si desidera limitare la dimensione dell'array, utilizzare

Ok, spero che tu stia trovando la mia soluzione e le mie spiegazioni utili, usa result.size () come indicatore e la parola chiave break per lasciare la dichiarazione di controllo while.

Greetz, GHad

**

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

**

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top