2010-10-06 17 views
20

Powiel możliwe:
Why does “abcd”.StartsWith(“”) return true?Dlaczego łańcuchy zaczynają się od "" w Javie?

Podczas debugowania przez jakiś kod znalazłem konkretny kawałek mojego walidacji została przy użyciu metody .startsWith() na klasy String, by sprawdzić, czy String rozpoczął się pusty znak

Biorąc pod uwagę następujące elementy:

public static void main(String args[]) 
{ 

    String s = "Hello"; 
    if (s.startsWith("")) 
    { 
     System.out.println("It does"); 
    } 

} 

Wydrukuje się It does

Moje pytanie brzmi: dlaczego łańcuchy zaczynają się od pustej litery? Przypuszczam, że pod maską Strings są zasadniczo tablicami znaków, ale w tym przypadku pomyślałbym, że pierwsza postać będzie mogła być H

Czy ktoś może wyjaśnić?

+7

Co to jest "pusty" znak? –

+11

@PP - nie bądź wybredny. 1) Wiele osób z SO nie ma języka angielskiego jako pierwszego języka. 2) Blank jest akceptowalną alternatywą dla przestrzeni. 3) Wiesz, co on/oni mają na myśli ... naprawdę. –

+5

@Stephen C absolutnie nie. Tu nie chodzi o "angielski". Chodzi o powszechne nazwy postaci IT. Puste miejsce nie jest dobrze zdefiniowane. Spacja, tabulacja, powrót karetki, posuw w linii to dobrze zdefiniowane nazwy białych znaków. Blank - jest ogólnością. –

Odpowiedz

40

"" jest pustym łańcuchem bez znaków. Nie ma "pustej postaci", chyba że masz na myśli spację lub znak pusty, z których żaden nie jest pusty.

Możesz myśleć o łańcuchu jako rozpoczynającym się od nieskończonej liczby pustych łańcuchów, tak jak możesz myśleć o liczbie jako zaczynającej się od nieskończonej liczby wiodących zer bez żadnej zmiany znaczenia.

1 = ...00001 
"foo" = ... + "" + "" + "" + "foo" 

Struny również skończyć z nieskończonej liczby pustych strun (podobnie jak liczby dziesiętne z zerami):

1 = 001.000000... 
"foo" = "foo" + "" + "" + "" + ... 
+0

+1 miłe słowa .. –

+2

Aby linia była w pełni zgodna, powinieneś użyć 1.0, w ten sposób dodanie zera do końca również nie ma wpływu. :) – HostileFork

+0

@Hostile Fork: Dobry punkt, edycja. – Cameron

5

Że „” nie jest pusty to pusty ciąg. Domyślam się, że API zadaje pytanie, czy to jest podłańcuch tego. A pusty łańcuch o zerowej długości jest podłańcuchem wszystkiego.

11

Wygląda na to, że w Twoim kodzie jest nieporozumienie. Twoja instrukcja s.startsWith("") sprawdza, czy ciąg znaków zaczyna się od pustego ciągu znaków (i , a nie pusty znak). Może to być dziwny wybór implementacji, tak jak jest: wszystkie ciągi powiedzą, że zaczynają się od pustego łańcucha.

Należy również zauważyć, że pustą literą będzie ciąg " ", w przeciwieństwie do pustego ciągu "".

2

Puste jest (""), różni się od pustego ciągu (""). Puste miejsce to znak, pusty ciąg to brak jakiejkolwiek postaci.

+0

Zabawne, by usłyszeć, że ludzie z Java wywołują spacje "puste". Co to jest karta, czy mogę zapytać, czy to też jest "puste"? –

+0

@PP: Używałem twojej terminologii, prawdopodobnie bardziej precyzyjne jest odwoływanie się do spacji i tabulacji. –

4

Pusty ciąg ("") zasadniczo "spełnia" każdy ciąg znaków. W przykładzie java wzywa

s.startsWith(""); 

do

s.startsWith("", 0); 

który zasadniczo opiera się na zasadzie, że "pusty element (string) spełnia swoje ograniczenia (Twoje zdanie string).".

Z ciągu.java

/** 
    * Tests if the substring of this string beginning at the 
    * specified index starts with the specified prefix. 
    * 
    * @param prefix the prefix. 
    * @param toffset where to begin looking in this string. 
    * @return <code>true</code> if the character sequence represented by the 
    *   argument is a prefix of the substring of this object starting 
    *   at index <code>toffset</code>; <code>false</code> otherwise. 
    *   The result is <code>false</code> if <code>toffset</code> is 
    *   negative or greater than the length of this 
    *   <code>String</code> object; otherwise the result is the same 
    *   as the result of the expression 
    *   <pre> 
    *   this.substring(toffset).startsWith(prefix) 
    *   </pre> 
    */ 
    public boolean startsWith(String prefix, int toffset) { 
    char ta[] = value; 
    int to = offset + toffset; 
    char pa[] = prefix.value; 
    int po = prefix.offset; 
    int pc = prefix.count; 
    // Note: toffset might be near -1>>>1. 
    if ((toffset < 0) || (toffset > count - pc)) { 
     return false; 
    } 
    while (--pc >= 0) { 
     if (ta[to++] != pa[po++]) { 
      return false; 
     } 
    } 
    return true; 
    } 
+0

To jest moja ulubiona odpowiedź. +1. Zasadniczo mówi on, że łańcuchy "zaczynają" od pustych łańcuchów, ponieważ 'String.startsWith' jest kodowany w ten sposób. Żadna z powyższych filozoficznych odpowiedzi nie dowodzi, czy łańcuchy rozpoczynające się od pustych łańcuchów są świadomym wyborem projektu w Javie lub zwykłym przypadkowym opadem z implementacji 'String.startsWith'. Dopóki to nie zostanie ustalone, ta dyskusja może mieć wyłącznie charakter akademicki. –

7

„Hello” zaczyna się od „”, a także zaczyna się od „H” i to też zaczyna się „On”, a także sharts z „Hel” ... widzisz?

3

Dla ludzi, którzy wzięli teorii automatów, to sens, ponieważ ciąg pusty ε jest podłańcuchem dowolny ciąg, a także jest elementem tożsamości konkatenacji, czyli:

for all strings x, ε + x = x, and x + ε = x

Więc tak, każdy ciąg "startWith" pusty ciąg. Zauważ również (jak wielu innych to mówi) pusty łańcuch różni się od pustego lub pustego znaku.

0

Pusty ciąg nie jest pustym znakiem. Zakładając, że twoje pytanie jest puste, myślę, że postanowili zostawić to w ten sposób, ale wydaje się to dziwne. Mogli sprawdzić długość, ale tego nie zrobili.

Powiązane problemy