1. Introdução à string, métodos comuns Análise de código -fonte
2. Análise constante de pool constante
Métodos comuns
igual a
aparar
substituir
Concat
dividir
StartSwith e EndSwith
Substring
toupppercase () e tolowerCase ()
compareto
Introdução à string
A classe String é modificada por final, o que significa que o objeto String é um imutável e os programas simultâneos preferem imutáveis. A classe String implementa as interfaces serializáveis, comparáveis e charsequence.
Comece com um pedaço de código:
public void stringTest () {string a = "a"+"b" +1; String b = "ab1"; System.out.println (a == b);}Adivinha qual é o resultado? Se sua conclusão for verdadeira. Ok, vamos ter outro código:
public void stringTest () {string a = new String ("AB1"); String b = "ab1"; System.out.println (a == b);}Qual é o resultado? A resposta correta é falsa.
Vamos ver como o código compilado pelo compilador
// o primeiro código public void stringTest () {string a = "ab1"; String b = "ab1"; System.out.println (a == b);} // o segundo código public void stringTest () {string a1 = new String ("AB1"); String b = "ab1"; System.out.println (a1 == b);}Em outras palavras, a primeira parte do código foi otimizada durante o período de compilação porque o compilador descobriu que os efeitos de "A"+"B" +1 e "AB1" são os mesmos e ambos são compostos por imutáveis. Mas por que a memória deles é o mesmo? Se você ainda estiver interessado nisso, vamos dar uma olhada em alguns códigos de origem importantes da classe String.
Código -fonte
1. Atributos da string
A classe String contém uma matriz de char imutável para armazenar strings, e um hash variável int é usado para armazenar o valor de hash calculado.
/** O valor é usado para armazenamento de caracteres. */Valor de char final privado [];/** cache o código de hash para a string*/private int hash; // Padrão para 0/** Use serialversionUid de JDK 1.0.2 para interoperabilidade*/estático privado final serialversionuid = -6849794470754667710L;
2. Construtor de cordas
// construtores sem parâmetros geralmente são inúteis, porque o valor é um public string imutável () {this.value = new char [0];} // o parâmetro é string tipo public string (string original) {this.value = original.value; this.hash = original.hash;} // O parâmetro é uma matriz de char, use a classe Matriz no pacote java.utils para copiar public string (char value []) {this.value = Arrays.copyof (value, alpination. bytes [], Int Offset, Int Length, String charsetName) lança UnsupportEdEncodingException {if (charsetName == null) lança novo NullPointerException ("CharSetName"); Verificação de bytes (bytes, deslocamento, comprimento); this.value = StringCoding.decode(charsetName, bytes, offset, length);}//Call the public String(byte bytes[], int offset, int length, String charsetName) constructor public String(byte bytes[], String charsetName) throws UnsupportedEncodingException { this(bytes, 0, bytes.length, charsetName);}3. Métodos comuns de string
1. Igual a
boolean é igual (objeto anobject) public boolean é igual a (objeto anobject) {// se a referência for o mesmo objeto, retorne true se (this == anObject) {return true; } // Se os dados da string do tipo não forem string, retorne false if (anobject instanceof string) {string anotherstring = (string) anobject; int n = value.length; // Se o comprimento da matriz de char não for igual, retorne false se (n == anototherstring.value.length) {char v1 [] = value; char v2 [] = anototherstring.value; int i = 0; // julga do caractere único de volta à frente, se houver alguma desigualdade, retorne false while (n--! = 0) {if (v1 [i]! = V2 [i]) retorna false; i ++; } // Cada caractere é igual, retorne a verdadeira retorno true; }} retornar false;}String e1 = "bom"; string e2 = "bom todos os dias"; e1.equals (e2); // retorna false
1 Primeiro, determine se o mesmo objeto é referenciado ==, ou seja, determine se os endereços de memória das duas referências são iguais. Se o mesmo, ele retornará diretamente true.
2 determinará se os tipos são iguais e se são o mesmo tipo de dados
3 Se o mesmo tipo for usado, o comprimento da matriz de caracteres convertido é o mesmo.
4 Compare se cada personagem é o mesmo da parte de trás para a frente
Ordem de julgamento =》 1. Endereço de memória 2. Dados Tipo 3. Comprimento da matriz 4. Comparação de caractere único
2. Compareto
int compareto (string anotherstring) public int compareto (string anotherstring) {// o comprimento da string do próprio objeto len1 int len1 = value.length; // o comprimento da sequência do objeto comparado len2 = anototherstring.value.length; // o valor mínimo do comprimento de duas seqüências limit int lim = math.min (len1, len2); char v1 [] = value; char v2 [] = anototherstring.value; int k = 0; // Do primeiro caractere do valor para o comprimento mínimo lim, se os caracteres não forem iguais, retorne em si (caracteres onde os objetos não são iguais - os caracteres que são comparados) enquanto (k <lim) {char c1 = v1 [k]; char c2 = v2 [k]; if (c1! = c2) {return c1 - c2; } k ++; } // Se as frentes forem todas iguais, retorne (comprimento próprio - comprimento do objeto que está sendo comparado) Retorno Len1 - Len2;}String co1 = "hello"; string co2 = "hello"; string co3 = "hello you"; System.out.println (CO1.comPARETO (CO2)); // 0system.out.println (CO1.compareto (CO3)); // -4
Este método é escrito engenhosamente e você pode julgar o tamanho do personagem de 0 primeiro.
Se a comparação entre os dois objetos puder comparar os caracteres ainda for igual, o comprimento do objeto que está sendo comparado será retornado diretamente. Se o comprimento das duas cordas for igual, o retorno será 0, o que julga inteligentemente as três situações.
3.HashCode
int hashcode () public int hashCode () {int h = hash; // Se o hash não foi calculado e a string não estiver vazia, o cálculo do código de hash é realizado se (h == 0 && value.length> 0) {char val [] = value; // Processo de computação // s [0]*31^(n-1) + s [1]*31^(n-2) + ... + s [n-1] para (int i = 0; i <value.length; i ++) {h = 31*h + val [i]; } // hash de atribuição hash = h; } retornar h;}String a = "Toyou"; char val [] = a.toCharArray (); char c1 = 't'; char c2 = 'a'; int f = c1; int e = c2; System.out.println (e); // 97 asystem.out.println (f); // 116 tSystem.out.println (31*val [0]); // 3596system.out.println (31*c1); // 3596 // Cálculo do código de hash porque os caracteres de char podem ser automaticamente convertidos na modelagem int correspondente
A classe String substitui o método HashCode e o método HashCode no objeto é uma chamada nativa.
O hash da classe String é calculado usando polinômios. Podemos obter completamente o mesmo hash através de cordas diferentes. Portanto, o código de hash de dois objetos de string é o mesmo, o que não significa que as duas cordas sejam iguais.
O código de hash do mesmo objeto de string deve ser o mesmo, mas o código de hash é o mesmo, não necessariamente o mesmo objeto
4.startswith
Boolean StartSwith (prefixo da string, int toffset) public boolean startSwith (prefixo da string, int toffset) {char ta [] = value; int para = toffset; char pa [] = prefix.value; int po = 0; int pc = prefix.value.length; // Nota: Toffset pode estar perto de -1 >>> 1. // Se o endereço de partida for menor que 0 ou (endereço inicial + comprimento do objeto comparado) for maior que o comprimento do próprio objeto, retorne false se ((Toffset <0) || (Toffset> value.length - pc)) {return false; } // Compare a partir do final do objeto que está sendo comparado enquanto (--PC> = 0) {if (ta [to ++]! = Pa [po ++]) {return false; }} retornar true;} public boolean startSwith (string prefix) {return startSwith (prefixo, 0);} public boolean endswith (string sufix) {return startSwith (sufixo, value.length - suffix.value.length);} String d = "www.58fxp.com"; System.out.println (d.startswith ("www")); // true system.out.println (d.endswith ("com")); // verdadeiroA comparação inicial e final são métodos comuns. Por exemplo, ao julgar se uma string é do protocolo HTTP ou julgando inicialmente se um arquivo é um arquivo MP3, você pode usar esse método para comparar.
5.CONCAT
String concat (string str) public string concat (string str) {int otherlen = str.Length (); // Se a string adicionada estiver vazia, retorne o próprio objeto se (otherlen == 0) {return this; } int len = value.length; char buf [] = Arrays.copyof (valor, len + outros len); str.getchars (buf, len); Retorne nova string (BUF, true);} String cat = "muito"; String newcat = cat.concat ("sim"); // muito simO método Concat também é um dos métodos comumente usados. Primeiro, ele determina se a string adicionada está vazia para decidir se deve criar um novo objeto.
1 Se o comprimento do caractere emendado for 0, retorne diretamente ao objeto de caractere original
2 Os caracteres emendados não estão vazios e retornam um novo objeto de personagem
Determine o comprimento do personagem para gerar um novo objeto
6.Reguplicar
String substituir (char Oldchar, char newchar) String public String (char Oldchar, char newchar) {// Compare os valores antigos e novos primeiro se (OldChar! = Newchar) {int len = value.length; int i = -1; char [] val = valor; / * Evite getfield opcode */ // Encontre a posição em que o valor antigo aparece pela primeira vez enquanto (++ i <len) {if (val [i] == Oldchar) {break; }} // dessa posição, até o final, substitua o valor antigo que aparece com o novo valor se (i <len) {char buf [] = new char [len]; for (int j = 0; j <i; j ++) {buf [j] = val [j]; } while (i <len) {char c = val [i]; BUF [i] = (c == OldChar)? Newchar: c; i ++; } retornar nova string (BUF, true); }} Retorne isso;} String r1 = "Como você faz"; String r2 = r1.replace ("do", "is"); system.out.println (r2); // como você estáEsse método também tem alguma inteligência, como descobrir onde o valor antigo aparece no início, o que economiza algum tempo de comparação.
O método Substituir (String Oldstr, String Newstr) é julgado por expressões regulares.
7.Trim
String Trim () public String Trim () {int len = value.length; int st = 0; char [] val = valor; / * Evite getfield opcode */ // Encontre a posição sem espaços na frente da string while ((st <len) && (val [st] <= '')) {st ++; } // Encontre a posição sem espaços no final da string while ((st <len) && (val [len-1] <= '')) {len--; } // Se não houver espaços na frente e depois, retorne a própria string ((st> 0) || (len <value.length))? substring (st, len): this;} String t1 = "public void"; // Um espaço na frente e depois do sistema.out.println ("t1:"+t1.length ()); // 13 com comprimento de espaço String t2 = t1.trim (); System.out.println ("T2:"+T2.Length ()); // 11 remova o sistema espacial.out.println (t2);8. INTERN
String intern () public nativo string intern ();
String dd = new String ("BB"). Intern ();O método NTERN é uma chamada nativa e sua função é encontrar objetos de igual valor através do método igual no pool constante na área do método.
Se não for encontrado, abra um espaço no pool constante para armazenar a string e retornar a referência à sequência correspondente. Caso contrário, retorne diretamente a referência ao objeto String já existe no pool constante.
Você também pode forçar o objeto de caracteres criado para o novo método para ver se o pool constante já existe.
Coloque o segundo código na introdução
// string a = new string ("ab1"); // altere para string a = new string ("ab1"). Intern ();O resultado é verdadeiro, porque o endereço apontado por A vem do pool constante, e a string constante apontada por B chamará esse método por padrão, então A e B ambos apontam para o mesmo espaço de endereço.
int hash32 () private transitório int hash32 = 0; int hash32 () {int h = hash32; if (0 == h) {// RACE de dados inofensivos no hash32 aqui. h = Sun.misc.hinging.murmur3_32 (hashing_seed, valor, 0, value.length); // garantir que o resultado não seja zero para evitar a recilação H = (0! = H)? h: 1; hash32 = h; } retornar h;}No JDK1.7, quando a classe String é usada como chave, a classe de coleta relacionada a hash não usa mais o método HashCode para discretar dados, mas usa o método Hash32.
Este método usa o tempo atual, o endereço da classe de string, o endereço da classe do sistema etc. como fatores para calcular a semente de hash. Através da semente de hash, um valor int de 32 bits é obtido através da semente de hash.
public int length () {return value.length;} public string tostring () {return this;} public boolean isEmpty () {return value.length == 0;} public charat (int index) {if (index <0) || (index> = value.length)) {throw new stringxoutSexception; } Valor de retorno [index];}Os acima são alguns métodos comuns simples.
Resumir
Objetos de string são tipos imutáveis. Métodos da String com Retorno Tipo String Retorna cada vez que um novo objeto String for retornado, exceto por determinadas condições específicas de alguns métodos para retornar.
Três maneiras de comparar objetos de string:
== Comparação de memória: compare diretamente os valores de memória apontados pelas duas referências, que são precisas, concisas e diretas.
é igual a comparação do valor da string: compare se os valores literais dos dois objetos referenciados são iguais.
Comparação da numericalização da string hashcode: numericalização de strings. Os dois códigos de hash referenciados são os mesmos, e a memória não é garantida como a mesma, e os valores literais não são garantidos como os mesmos.
Ideia de design de string constante piscina
1. Intenção original do design constante do pool constante
Cada string é um objeto de sequência e as seqüências de caracteres serão frequentemente usadas no desenvolvimento do sistema. Se criado e destruído como outros objetos, afetará bastante o desempenho do programa.
Para melhorar o desempenho e reduzir a sobrecarga da memória, a JVM otimiza ao instanciar seqüências instantinas.
Um pool constante de cordas é aberto para cordas, semelhante a uma área de cache
Ao criar uma string constante, primeiro determine se o pool constante de string existe.
A string retorna uma instância referenciada, não existe, instanciam a string e a coloca no pool.
Perceba o básico
A base para implementar essa otimização é que cada constante de string é uma constante final modificada; portanto, não há necessidade de se preocupar com os conflitos de dados no pool constante.
Há uma tabela no pool constante de string global criado pela instância de tempo de execução, que sempre mantém uma referência para cada objeto de string exclusivo no pool, o que significa que eles sempre se referem a objetos no pool constante de string, para que essas seqüências no pool constante não sejam coletadas pelo coletor de lixo.
Pilha, pilha, área de método
Compreendendo piscinas constantes de string, primeiro olhe para a área do método de pilha
pilha
O que é armazenado é um objeto, cada objeto contém uma classe correspondente
A JVM possui apenas uma área de heap e é compartilhada por todos os threads. Não há tipos básicos e referências de objetos na pilha, mas apenas o próprio objeto
Os objetos são coletados pelo coletor de lixo, portanto o tamanho e o ciclo de vida não precisam ser determinados
Pilha
Cada encadeamento contém uma área de pilha, que armazena apenas objetos básicos de tipo de dados e referências de objetos personalizados.
Os dados (tipo primitivo e referência de objeto) em cada pilha são privados
A pilha é dividida em três partes: a área variável do tipo básico, o contexto do ambiente de execução e a área de instrução de operação (armazenando instruções de operação)
O tamanho dos dados e o ciclo de vida são certos e, quando nenhuma referência aponta para esses dados, os dados desaparecerão.
Área de método
Zonas estáticas, como pilhas, são compartilhadas por todos os threads
A área do método contém elementos que são sempre únicos em todo o programa, como variáveis de classe e estática;
String Constant Pool
Existe um pool constante de string na área do método
Código: Método de pilha armazena Strings
String str1 = "abc"; string str2 = "abc"; string str3 = "abc"; string str4 = new string ("abc"); string str5 = new string ("abc");Perguntas da entrevista
String str4 = new String ("ABC") Quantos objetos são criados?
Divisão: str4 =, new String (), "ABC"
Você pode criar um novo objeto através do novo método. O novo método cria um objeto instanciado e não vai para o pool constante para descobrir se ele já existe. Enquanto novo, um novo objeto será instanciado.
"ABC" Cada string é um objeto String. Se não houver no pool constante, um novo objeto será criado e colocado no pool constante. Caso contrário, a referência do objeto será retornada.
Atribua o endereço do objeto ao STR4 e crie uma referência
Portanto, se não houver literal "ABC" no pool constante, crie dois objetos, caso contrário, crie um objeto e crie uma referência
String str1 = new string ("a"+"b"); Quantos objetos serão criados? String str2 = new String ("ABC") + "ABC"; Quantos objetos serão criados?
A análise abrangente acima do código -fonte da String Java e do String Constant Pool é todo o conteúdo que compartilho com você. Espero que você possa lhe dar uma referência e espero que você possa apoiar mais o wulin.com.