Percorrer várias Strings com o mesmo nome

40 respostas Resolvido
programaçãojava
A

E aí pessoal! Beleza?
Tenho essa string:

DebitosPendentes{" +
"Vencimento=2018-04-10; " +
"ValorAtualizado=29.92; " +
"Valor=29.92; Sequencia=9999; " +
"NroBanco=9999; " +
"BcoCobr=Banco; " +
"Cobranca=Boleto; " +
“Itens=[” +
“ListaItens{” +
"Descricao=Contrato; " +
"ValorItem=9.97; }, " +
“ListaItens{” +
"Descricao=Contrato; " +
“ValorItem=19.95; }]; },” +
“DebitosPendentes{” +
"Vencimento=2018-03-10; " +
"ValorAtualizado=29.92; " +
"Valor=29.92; " +
"Sequencia=9999; " +
"NroBanco=9999; " +
"BcoCobr=Banco; " +
"Cobranca=Boleto; " +
“Itens=[” +
“ListaItens{” +
"Descricao=Contrato; " +
"ValorItem=9.97; }, " +
“ListaItens{” +
"Descricao=Contrato;
ValorItem=19.95; }]; }, "

Como faço para percorrer cada item dessa string?
Obs: Eu tentei com indexOf, mas dá erro, por causa que tem mais itens com o mesmo nome na string.

40 Respostas

L

Me parece um JSON (eu sei que não é, ainda mais pelos diversos “=” dentro do código).
Mas, a estrutura é de JSON. Logo, eu faria um replaceAll("=", “:”) e outro replaceAll(";", “,”) e converteria em elementos JSON para ler com mais facilidade.
Ou quebraria em array de String com split(";") e daí leria item a item.

S

O indexOf é sobrecarregado, podendo passar o índice inicial da consulta.

Mas no seu caso, já que os campos são separados por ponto e vírgula, você pode fazer um split(";") da String.

A

Fiz a pergunta errada pessoal, eu já fiz o split. Aí fui tentar fazer o indexOf pra pegar o valor do item deu erro.
Fiz dessa forma:

for(int i = 0; i < debitos.length; i++){

int contador = debitos[i].toString().indexOf(ValorItem=);

int inicio = debitos[i].toString().indexOf(Descricao=)+10;

descricao1[i] = debitos[i].toString().substring(inicio, contador-2);

}

Mas ta dando erro, acredito que seja porque tem mais que um “ValorItem” e “Descrição”. Então, queria saber se tem como ir para o próximo indexOf, por exemplo
Obs: Nesse caso a variável “debitos” é um vetor objetos e a “descrição1” é um vetor de strings

A

Como converter pra JSON?

L

Existem bibliotecas para isso, como a Gson do google.
Neste caso, você precisaria de um POJO contendo os atributos que o teu JSON teria, pois faria a deserialização da String para objeto java (ou lista de objetos, enfim).

A

Não deu certo dessa forma Luis…
Gente só quero pegar o valor do item “ValorItem” :confused:
Tipo:
primeiro valor do item “ValorItem” = 9.97 (Guardo na primeira posição do vetor)
segundo valor do item “ValorItem” = 9.97 (Guardo na segunda posição do vetor)
E assim por diante…

L

Cara, lembra das aulas de MMC e MDC? Então, se uma sugestão não rolou, tenta encontrar a forma mais adequada de quebrar no menor pedaço possível para que você possa ler essas informações sem maiores problemas.

I

Cola a mensagem de erro pra gente aqui.

A

Não necessariamente da erro… O problema é que só pega o primeiro “ValorItem”, sendo que eu queria que pegasse todos “ValorItem” que tem no vetor de string :confused:

Seria um erro de lógica por minha parte…

I

vou te ajudar. peraê…

A

Beleza :slight_smile:

I

Este código não vai te servir completamente, mas da pra você ter uma ideia da minha lógica, e aplicar ao seu código, ao que você quer fazer exatamente com este valor.

for(int i = 0; i < debitos.length; i++){
		Integer aux = debitos[i].toString().indexOf("ValorItem=");
		while (aux != -1) {
			int contador = debitos[i].toString().indexOf("ValorItem=");
			int inicio = debitos[i].toString().indexOf("Descricao=")+10;
			descricao1[i] = debitos[i].toString().substring(inicio, contador-2);
		
            	debitos[i].toString().replaceFirst("ValorItem=", "");
			aux = debitos[i].toString().indexOf("ValorItem=");
		}
}

Em resumo: você faz um while, ate que o index seja -1 (que simboliza que n existe mais a ocorrencia daquela string.)

pega somente o primeiro item como de costume;

remove o primeiro item;

pega novamente o primeiro item (que agora será o segundo de antes e assim por diante.
A

Eu fiz aqui, mas continua pegando o primeiro item.
Olha o código:

for(int i = 0; i < debitos.length; i++){
    int aux = debitos[i].toString().indexOf("ValorItem=");// auxiliar recebe ValorItem na posição 23
    int aux2 = 0;
    while (aux != aux2) { // Enquanto auxiliar for diferente que aux2, faça
            int contador = debitos[i].toString().indexOf("ValorItem="); // contador recebe 23
            int inicio = debitos[i].toString().indexOf("Descricao=")+10; // inicio recebe 3
            descricao1[i] = debitos[i].toString().substring(inicio, contador-2); // descrição receberá a string
            // que estiver entre essas duas posições, que no caso é "Contrato de internet"
            aux2 = aux; // aux2 receberá 23
            debitos[i].toString().replace("ValorItem=", ""); // substitui o ValorItem na posição 23 por nada
            aux = debitos[i].toString().indexOf("ValorItem=");// auxiliar recebe o ValorItem na próxima posição, como por exemplo 50
            Log.i("descricao", "Descrição Débitos: " + descricao1[i]);
     }
 }
A

Eu tava lendo sobre o indexOf, parece que tem como começar de uma posição ou algo assim. Vi que tem uma propriedade dele assim “indexOf(int ch, int fromIndex)”. Você tem conhecimento sobre isso? Ou alguém poderia me explicar melhor? Porque não entendi muito bem

A

Eu tava pensando aqui… Se for seguindo essa lógica, eu também tenho que trocar a “Descrição”. Dessa forma, não corro perigo de ler mais informação do que preciso.

I

mas você não seguiu a lógica que sugeri…

algumas dicas:

1 - você precisa usar o replaceFirst para substituir somente a primeira aparição e não o resto todo;

2 - precisa usar o indice -1 como condição de parada, porque caso não exista mais ocorrência daquela string ele sai do seu while;

3 - esse somatório com 10 ai ta ficando estranho, você pode usar o indexOf("=") e pegar a posição logo após o sinal de =;

uma dúvida, se você quebrou sua string em um array de strings, e cada posição i contem uma string no formato “item=valor” e ta dando um for em i, não faz sentido ele pegar somente o primeiro item, seu problema é a lógica de implementação. posta mais do código ai pra tentar te ajudar…

A

Desculpa, achei que tinha seguido.

Eu troquei o “replace” para “replaceFirst”, e continua pegando o primeiro…

Se eu troco para -1 dá loop infinito.

Mas aí vai ter mais “=” na string e vou cair no mesmo caso

I

como está sua String?

pelo que entendi você fez um split dos ; dentro de um vetor chamado debitos, correto?

se você fez isso, não tem mais de um = por string não.

seu vetor ta assim

debitos[0] ="Vencimento=2018-04-10"
debitos[1] ="ValorAtualizado=29.92;"
debitos[2] ="Valor=29.92;"
debitos[3] =“Sequencia=9999;”

etc…

então quando você pega o valor de débitos i, você está pegando somente aquele valor equivalente ao indice i;
então se vc tiver mais de um ValorItem, ele vai pegar todos, porem cada um estará em sua devida posição no vetor descricao1[i];

uma pergunta, o que você deseja fazer com este código? pelo que vejo é possivel refatorá-lo para tornar mais eficiente. se me explicar o que quer, te ajudo.

A

Na verdade eu criei um vetor de objetos, onde por exemplo tem 9 posições e em cada posição contém dentro essas informações (Vencimento, valor atualizado, valor…). No caso estou fazendo um “for” para armazenar a informação de cada um deles. Segue o código abaixo.

for(int i = 0; i < debitos.length; i++){
    int contador = debitos[i].toString().indexOf("ValorAtualizado=");
    int inicio = debitos[i].toString().indexOf("Vencimento=")+11;
    vencimento1[i] = debitos[i].toString().substring(inicio, contador-2).replaceAll("-", "/");
}

for(int i = 0; i < debitos.length; i++){
    int contador = debitos[i].toString().indexOf("Valor=");
    int inicio = debitos[i].toString().indexOf("ValorAtualizado=")+16;
    valorAtualizado1[i] = debitos[i].toString().substring(inicio, contador-2).replaceAll(",","");
    nf = NumberFormat.getCurrencyInstance(new Locale("pt", "BR"));
    valorAtualizado2[i] = nf.format(Double.valueOf(valorAtualizado1[i]));
}

Está dessa forma:

Debitos[0] = [DebitosPendentes{Vencimento=2018-04-10; ValorAtualizado=29.92; Valor=29.92; Sequencia=9999; NroBanco=9999; BcoCobr=Banco; Cobranca=Boleto; Itens=[ListaItens{Descricao=Contrato; ValorItem=9.97; }, ListaItens{Descricao=Contrato; ValorItem=19.95; }];

Debitos[1] = [DebitosPendentes{Vencimento=2018-03-10; ValorAtualizado=29.92; Valor=29.92; Sequencia=9999; NroBanco=9999; BcoCobr=Banco; Cobranca=Boleto; Itens=[ListaItens{Descricao=Contrato; ValorItem=9.97; }, ListaItens{Descricao=Contrato; ValorItem=19.95; }];

A

O WebService me retorna esse vetor de objetos e eu tenho que salvar no banco Sqlite e mostrar uma lista com alguns itens e quando o usuário clica no item, aparece todo o detalhe dele.

I

E isto está funcionando para itens que tem apenas uma aparição, mas não funciona para itens como ValorItem e Descrição que se repetem, certo?

neste caso voltamos a primeira lógica do while…

uma pergunta: você quer estes valores, tipo valorItem somados, ou 2 valorItem separados dentro do seu vetor?

A

Por exemplo:

Tela da lista:
Item 1
Vencimento: 2018-04-10
ValorAtualizado: 29.92
Valor: 29.92

Item 2
Vencimento: 2018-03-10
ValorAtualizado: 29.92
Valor: 29.9

Aí o usuário clica no item 1
Tela detalhe
Item 1
Vencimento: 2018-04-10
ValorAtualizado:29.92
Valor:29.92
Sequencia:9999
NroBanco:9999
BcoCobr:Banco
Cobranca:Boleto
Itens:
Descricao:Contrato;
ValorItem:9.97
Descricao:Contrato
ValorItem:19.95

A

Eu tava pensando em concatenar todos os “ValorItem” separando por um espaço para armazenar no banco e depois dar split pra exibir

I

Dei uma adaptada naquela lógica do while, acho que o problema no loop infinito é porque o replaceFirst não tava funcionando. tenho minhas dúvidas, mas acho que é porque ele tava trabalhando com o vetor diretamente.

dei uma leve adaptada usando mais uma variavel… faz um teste ae

for(int i = 0; i < debitos.length; i++){
		String aux2 = debitos[i].toString();
		Integer aux = aux2.indexOf("ValorItem=");
		while (aux != -1) {
			int contador = aux2.indexOf("ValorItem=");
			int inicio = aux2.indexOf("Descricao=")+10;
			descricao1[i] = aux2.substring(inicio, contador-2);
		
			aux2.replaceFirst("ValorItem=", "");
			aux = aux2.indexOf("ValorItem=");
			Log.i("descricao", "Descrição Débitos: " + descricao1[i]);
		}
     }
A

Deu loop infinito de novo… E aparece essa mensagem quando você clica no “replaceFirst” no android studio.

I

É… como está dando errro no replaceFirst não sei como lhe ajudar.

A

Não é que está dando erro. Ele está sendo ignorado, por alguma razão que não sei…
Mas obrigado por tentar me ajudar :slight_smile:
Vou tentar fazer alguma coisa com indexOf haha

L

Vi, em uma das respostas, que a String é retornada por um WebService. Porém, um WebService vai devolver de acordo com o que for especificado como formato de saída.
É possível alterar este WS para que a saída seja mais amigável?

A

Amigável, como por exemplo?

L
Solucao aceita

Como um JSON ou um xml, em que há um padrão mais simples de se ler e no qual seja possível utilizar uma ferramenta já existente.
Senão você vai empreender um tempo e esforço muito grandes (está desde ontem aqui e envolveu diversos caras bons), com retorno quase nulo.
Se você tivesse isso em xml, por exemplo, teria algo parecido com isso
<debito-pendente> <debito> <vencimento>2018-04-10</vencimento> <valor-atualizado>29.92</valor-atualizado> <valor>29.92</valor> <sequencia>9999</sequencia> <nro-banco>9999</nro-banco> <bco-cobr>Banco</bco-cobr> <cobranca>Boleto</cobranca> <itens> <descricao>Contrato</descricao> <valor-item>19.95</valor-item> </itens> </debito> </debito-pendente>

I

com pouca adaptação, você retornaria isso em um JSON, usava uma biblioteca pronta pra destrinchar em objetos, e estaria pronto. não tinha me ligado que o WS era seu.

Segue a dica do @Luis_Augusto_Santos que é sucesso.

M

Concordo com o @Luis_Augusto_Santos.
Acha um jeito de botar essa string num formato de JSON e faz um parse pra uma classe representando a estrutura. Depois disso vai ficar muito mais fácil pra trabalhar e você perderá menos tempo dando manutenção nisso.

A

Pedi pra mudar o WebService, agora ele retorna dessa forma:

<status xsi:type="xsd:int">1</status>
         <erro_code xsi:type="xsd:int">0</erro_code>
         <erro_desc xsi:type="xsd:string"/>
         <result xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="tns:DebitosPendentes[26]">
            <item xsi:type="tns:DebitosPendentes">
               <Vencimento xsi:type="xsd:string">2018-04-10</Vencimento>
               <ValorAtualizado xsi:type="xsd:decimal">29.92</ValorAtualizado>
               <Valor xsi:type="xsd:decimal">29.92</Valor>
               <Sequencia xsi:type="xsd:string">9999</Sequencia>
               <NroBanco xsi:type="xsd:int">9999</NroBanco>
               <BcoCobr xsi:type="xsd:string">Banco</BcoCobr>
               <Cobranca xsi:type="xsd:string">Boleto</Cobranca>
               <Itens xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="tns:ListaItens[2]">
                  <item xsi:type="tns:ListaItens">
                     <Descricao xsi:type="xsd:string">Contrato</Descricao>
                     <ValorItem xsi:type="xsd:decimal">9.97</ValorItem>
                  </item>
                  <item xsi:type="tns:ListaItens">
                     <Descricao xsi:type="xsd:string">Contrato</Descricao>
                     <ValorItem xsi:type="xsd:decimal">19.95</ValorItem>
                  </item>
               </Itens>
            </item>
            <item xsi:type="tns:DebitosPendentes">
               <Vencimento xsi:type="xsd:string">2018-03-10</Vencimento>
               <ValorAtualizado xsi:type="xsd:decimal">29.92</ValorAtualizado>
               <Valor xsi:type="xsd:decimal">29.92</Valor>
               <Sequencia xsi:type="xsd:string">9999</Sequencia>
               <NroBanco xsi:type="xsd:int">9999</NroBanco>
               <BcoCobr xsi:type="xsd:string">Banco</BcoCobr>
               <Cobranca xsi:type="xsd:string">Boleto</Cobranca>
               <Itens xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="tns:ListaItens[2]">
                  <item xsi:type="tns:ListaItens">
                     <Descricao xsi:type="xsd:string">Contrato</Descricao>
                     <ValorItem xsi:type="xsd:decimal">9.97</ValorItem>
                  </item>
                  <item xsi:type="tns:ListaItens">
                     <Descricao xsi:type="xsd:string">Contrato</Descricao>
                     <ValorItem xsi:type="xsd:decimal">19.95</ValorItem>
                  </item>
               </Itens>
            </item>
A

Primeira vez que vou trabalhar com xml no android… Nem sei por onde começar. Alguma sugestão?

A

Praticamente dois meses de projeto indo embora :confused:

L

Cara, se tivesse dito que era no android nem teria sugerido XML. Pedisse direto json, que é mais natural a quem trabalha com android.
De qualquer forma, dá uma pesquisada sobre como ler XML em java, vai ajudar muito.

A

Valeu :+1:

A

Aqui o primeiro parâmetro da propriedade replaceFirst está esperando um regex, isso ajuda em algo? Está assim:
replaceFirst(String regex, string replacement)

Como você colocou:

debitos[i].toString().replaceFirst("ValorItem=", "");

Eu acho que é por isso que foi ignorado, porque você não está colocando um regex no primeiro parâmetro…

I

Não, não…

neste caso, regex também aceita a string a ser substituída.

veja este exemplo:

https://www.tutorialspoint.com/java/java_string_replacefirst.htm

import java.io.*;
public class Test {

   public static void main(String args[]) {
      String Str = new String("Welcome to Tutorialspoint.com");

      System.out.print("Return Value :" );
      System.out.println(Str.replaceFirst("(.*)Tutorials(.*)", "AMROOD"));

      System.out.print("Return Value :" );
      System.out.println(Str.replaceFirst("Tutorials", "AMROOD"));
   }
}

Saída:

Return Value :AMROOD
Return Value :Welcome to AMROODpoint.com
A

Entendi

Criado 20 de março de 2017
Ultima resposta 21 de mar. de 2017
Respostas 40
Participantes 5