Domanda

Ho bisogno di una funzione che prenderà stringa e interi che indicano la posizione del doppio o del numero di restituzione non negativo o di restituzione o null. Se c'è '+' restituire null.

Esempi

2.1      , 0 -> 2.1
+2.1     , 0 -> null
-1       , 0 -> null
-1.2     , 1 -> 1.2
qwa56sdf , 3 -> 56

Qual è il modo più elegante per farlo? Grazie.

UPD ho bisogno di codice come questo, ma meglio)

    Number parse(String str, int pos){
        Matcher m = Pattern.compile("^(\\d+(?:\\.\\d+)?)").matcher(str);
        m.region(pos, str.length());
        if(m.find()){
            return Double.parseDouble(m.group());
        } else {
            return null;
        }
    }
È stato utile?

Soluzione

public static Double parseDouble(String input, int fromIndex) {
    Matcher matcher = Pattern.compile("\\d*\\.?\\d+")
        .matcher(input.substring(fromIndex));
    return matcher.lookingAt() ? Double.parseDouble(matcher.group()) : null;
}

Altri suggerimenti

Potresti provare:

public static void main(String[] args) {
  System.out.println(parse("2.1", 0));
  System.out.println(parse("+2.1", 0));
  System.out.println(parse("-1", 0));
  System.out.println(parse("-1.2", 1));
  System.out.println(parse("qwa56sdf", 3));
}

private static Double parse(String string, int index) {
  if (string.charAt(index) == '-' || string.charAt(index) == '+') {
    return null;
  }
  try {
    return Double.parseDouble(string.substring(index).replaceAll("[^\\d.]", ""));
  }
  catch (NumberFormatException e) {
    return null;
  }
}

Ho dovuto spogliare i caratteri finali non di non cifre con sostituti tutti perché hanno causato un NumberFormatexception e avrebbero restituito NULL per input come quello nel tuo ultimo esempio.

EDIT: L'altra opzione per lavorare per casi come quello nel commento potrebbe essere quello di controllare ogni personaggio

private static Double parse(String string, int index) {
    String finalString = "";
    boolean foundSeparator = false;
    for (char c : string.substring(index).toCharArray()) {
        if (c == '.') {
            if (foundSeparator) {
                break;
            }
            else {
                foundSeparator = true;
            }
        }
        else if (!Character.isDigit(c)) {
            break;
        }
        finalString += c;
    }
    if (finalString == "") {
        return null;
    }
    return Double.parseDouble(finalString);
}

Dovrai utilizzare una combinazione del String.substring() metodo per iniziare dalla posizione indicata nella stringa e nel NumberFormat classe per analizzare il numero.

Se questo è funzionalmente corretto, mi sembra abbastanza elegante. Potresti voler rendere il modello un membro della classe finale poiché devi compilarlo solo una volta. E la regione probabilmente non è necessaria:

Matcher m = pattern.matcher(str.substring(pos));

Un'altra opzione è iniziare con una sottostringa di lunghezza 1 e farla crescere fino a quando non analizzerà più:

if ( str.charAt(pos) == '+' || str.charAt(pos) == '-' ) {
    //special cases
    return null;
}
Double val = null;
for ( int i = pos+1; i <= str.length(); i++ ) {
    try {
       val = Double.parseDouble(str.substring(pos, i)) {
    }  catch (NumberFormatException e) {
       break;
    }
}
return val;

È un po 'più semplice ma anche ingenuo per le prestazioni. Una soluzione meno leggibile ma più performa sarebbe quella di trovare la fine del doppio prima di passare per analizzare solo guardando i personaggi uno alla volta.

C'è anche il Scanner classe. Che ha specificamente metodi per leggere nei primitivi, ad esempio scanner.hasNextDouble() e scanner.nextDouble(). Dovrai comunque fare il controllo per + o -, perché ciò passerebbe comunque l'assegno.

Penso che la seguente implementazione sarebbe più elegante per il tuo insieme di requisiti. Sto usando la classe java.text.numberformat per l'analisi.

    private static Number parse(String text, int position){
        Number value=null;
        NumberFormat nf = NumberFormat.getInstance();
        try {
            value = nf.parse(text,new ParsePosition(position));
            if (value.intValue() < 0)
                value = null;
        } catch (Exception e) {
            value = null;
        }
        return value;
   }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top