È questo comportamento previsto per String.containsOnly ()?
Ecco del codice per illustrare il problema.
String str1 = '';
System.debug(str1.containsOnly('W'));
Mi sarei aspettato falsecome risultato ma sorprendentemente il risultato è stato true. Non capisco perché questo sia il caso considerando che una stringa vuota non contiene un 'W'carattere. È questo comportamento previsto o un bug?
Modifica : dopo le risposte che ho ricevuto finora, penso di dover riformulare la mia domanda e renderla più fondamentale. In questo modo, verrà data risposta alla domanda originale.
Un presupposto di fondo che sto facendo è che la documentazione del metodo ha preceduto ed è stata la base dell'implementazione del metodo e non viceversa. Se ritieni che questa ipotesi sia sbagliata, fammelo sapere.
Tralasciando così come containsOnly()è attualmente implementato, come va intesa la documentazione del metodo? È più una questione di significato o semantica che tecnica. Questa è la descrizione fornita.
contieneOnly (inputString) Restituisce true se la stringa corrente contiene solo caratteri della sequenza di caratteri specificata e non altri caratteri; in caso contrario, restituisce false.
Ecco le possibili interpretazioni fino ad ora:
La stringa corrente non contiene caratteri al di fuori dei caratteri nella stringa di input. (@PhilW)
La stringa corrente contiene uno qualsiasi dei caratteri nella stringa di input (
containsAny(inputString)) && interpretazione 1. (La mia comprensione).
Per favore fatemi sapere come avete capito la documentazione o la frase contiene solo e se avete altre interpretazioni plausibili, le aggiungerò all'elenco. Penso che sia necessario un consenso su questo prima di entrare nell'attuazione effettiva del metodo.
Risposte
Logicamente, sì, perché la stringa vuota non contiene caratteri non consentiti.
I caratteri non consentiti sono caratteri non esplicitamente elencati nella specifica "solo". Quindi in questo caso è qualsiasi lettera diversa dalla "W".
Se stessi implementando questo metodo da solo, farei qualcosa del tipo:
public Boolean containsOnly(String allowed) {
// "chars" is the internal array of characters in the string
for (Integer i = 0; i < chars.size(); i++) {
if (allowed.indexOfChar(chars[i]) < 0) {
return false;
}
}
return true;
}
Il punto è che è un'iterazione compatta alla ricerca di caratteri non consentiti con uscita anticipata come richiesto e se non trovi caratteri non consentiti restituisci semplicemente vero.
Non credo che questo comportamento possa essere considerato un bug; è un risultato naturale del controllo in modo compatto ed efficiente. Puoi anche visualizzare una stringa vuota come zero istanze del carattere "W". String.containsOnlyrestituirà true per:
- zero caratteri 'W' (la stringa vuota)
- un carattere "W" (la stringa "W")
- due caratteri "W" (la stringa "WW")
- eccetera.
Se vuoi verificare di avere una stringa non vuota e contiene solo i caratteri specificati, adatta il tuo codice per fare:
if (str1.isNotEmpty() && str1.containsOnly('W')) {
...
}
Sono propenso a pensare che questo non sia un bug ed è un comportamento standard, ma la documentazione è al massimo ambigua e non fornisce indicazioni su come dovrebbe funzionare una stringa vuota . Ulteriori chiarimenti sono giustificati dato che containse containsOnlyrestituiscono risultati diversi in questi scenari:
''.contains('W'); //false
''.containsOnly('W'); //true
Addendum : alcuni esempi aggiuntivi che mostrano come questa funzione sia più simile a un set rispetto a quella containsche cerca una sottostringa in una determinata stringa:
'abab'.containsOnly('ab'); //true
'ab'.containsOnly('abab'); //true
'abab'.containsOnly('abcd'); //true
'abab'.contains('ab'); //true
'ab'.contains('abab'); //false
'abab'.contains('abc'); //false
L' containsOnlyoperazione dovrebbe essere definita in termini matematici e ho la sensazione che sia implementata in questo modo. Non esiste esattamente un'operazione come containsOnly( che io sappia - non sono un matematico ), ma puoi arrivarci in due modi con le operazioni sugli insiemi standard. Se prendi l'intersezione (∩) dei due insiemi e l'intersezione è la stessa del tuo primo operando true, significa che i due insiemi si sovrappongono completamente:
{A, B} ∩ {A, B} = {A, B}
{} ∩ {A, B} = {}
Ma le regole dell'algebra degli insiemi trattano un insieme vuoto in un modo unico in quanto tutte le seguenti sono equivalenti:
{} ∩ {A, B} ≡ {} ∩ {} ≡ {}
Questo spiegherebbe perché una stringa vuota, che è un "insieme" di caratteri vuoto, restituirebbe sempre true quando l'operazione viene eseguita su di essa. L'intersezione dell'insieme vuoto con qualsiasi altro insieme (incluso un altro insieme vuoto) è sempre l'insieme vuoto.
Questo era un modo per implementare una containsOnlyfunzione utilizzando le operazioni sugli insiemi. L'altro è usare la differenza (\). Se la differenza di due serie è la stessa dell'originale, potresti dire che la prima serie contiene solo la seconda. Anche in questo caso, l'insieme vuoto si comporta in modo simile all'utilizzo di un'intersezione.
{A, B} \ {A} = {B}
{A, B} \ {A, B} = {} ≡ {} \ {A, B} = {} ≡ {} \ {} = {}
La mia ipotesi è che containsOnlyvenga implementato utilizzando uno di questi metodi per il suo algoritmo e la documentazione per la Stringclasse deve essere aggiornata per riflettere la metodologia corrente del metodo (in modo che i futuri sviluppatori siano consapevoli delle sfumature). Oppure il metodo dovrebbe essere cambiato per essere reso coerente contains.