Comparing Strings using Arraylist

Asked

Viewed 482 times

1

I need that in the repetition it identifies the same strings, I know that I need to use the . equals(), however, is giving error, as if the variable x is checking more value that exist in Arraylist, but has as a condition that x is smaller than "data.size()" (which is the size of my vector).

public static void main(String args[]) {
        ArrayList<String> dados= new ArrayList<String>();

        //OBS. Primeiramente inserir os dados, futuramente
        //ler arquivos txt
        dados.add("Dado 2");
        dados.add("Dado 1");
        dados.add("Dado 3");
        dados.add("Dado 3");
        dados.add("Dado 3");
        Collections.sort(dados);  
        //while(dados.contains(dados)){
          //  System.out.println("deu certo");
        //}       
        //for (String x : dados){
        //    System.out.println(x);
        //    if (x.contains(x))
       // }     
        int i;
        int contador = 0;
        int x = 0;
        int tamanho = dados.size();
        for (i = 0; i<tamanho; i++){        
            System.out.println(dados.get(i));
                if (x<dados.size() && dados.get(i).equals(dados.get(++x))){
                System.out.println("entrou no contador");
                contador++;
                }              
        } 
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new main().setVisible(true);
            }
        });
    }

Error generated from code:

Erro gerado do código

[ERRO]
run:
Dado 1
Dado 2
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 5, Size: 5
Dado 3
entrou no contador
Dado 3
entrou no contador
Dado 3
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.get(ArrayList.java:429)
    at projetoic.main.main(main.java:118)
C:\Users\lsilv\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
FALHA NA CONSTRUÇÃO (tempo total: 5 segundos)
  • 2

    By way of comment, it would be better if you put the code in the question instead of image to make it easier for those who help you ;)

  • 3

    If you need to be < tamanho and not <= tamanho.

  • Puts the code in text form, in image form hinders testing,.

  • I edited and added the project code, made the proper corrections sent here, but the error persists..

4 answers

3

You can use java streams to count this way:

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("b");
list.add("c");
list.add("a");
list.add("a");
list.add("a");

Map<String, Long> counted = list.stream()
   .collect(Collectors.groupingBy(e -> e, Collectors.counting()));

The above code streams and groups the same words e -> e and counting the occurrences Collectors.counting(). Thus the resulting map is < Word, Occurrences>

The result is as follows:

{a=4, b=2, c=2, d=1}

See on ideone

As for your code is as already spoken, pay attention to the condition of the loop. (It is i < size)

2

You are trying to access the index 5 of an array that goes up to 4 (0,1,2,3,4).

2

1 - The index i goes from 0 to size-1: data[0]=="Given 1"... data[4]="Given 3" (the last Given 3). Therefore the for condition has to be 'i < size'.

2 - The 'x<data.size()' condition is after trying to pick up the value with 'data.get(++x)' so it does not prevent trying to pick up a value already outside the limits of the array.

3 - What answer do you expect? Because arranging the above conditions the output would be 2.

4 - Reinforce the rLinhares comment, do not put a code/error image, but copy and paste the text itself, so that whoever helps you can enjoy the text. For this use the formatting icon for code: the '{}' icon that appears at the top of the box where you type your question/answer here in the stack. Stay like this:

ArrayList<String> dados = new ArrayList<String>();
dados.add("Dado 2");
dados.add("Dado 1");
  • I applied the corrections you suggested, but the error remains :/

  • Paste the code and error here to try to see what might be.

  • Code posted :)

  • Put the increment in the comparison, and make it the preincrement. Otherwise you are comparing that x is smaller than the list size, but when picking up the item you use index (x you compared)+1. Then it would be 'if ++x<data.size() && ... equals(data.get(x))

  • I can’t comment on Igor Venturelli’s reply: it can be that way too, with post-increment x equals, just remember that in this case x would have to start at 1.

  • One last tip, try simulating the program with pen and paper, putting the values i, x, data.get(i), data.get(x) into each loop. It’ll help a lot to understand what’s going on ;-)

  • Thank you Mari, I followed Igor’s comment and everything worked out already!!

Show 2 more comments

0


The problem is here:

dados.get(++x)

++x is different from x++:

  • Post Increment (x++): the post-increment happens after the current expression ends. For example: assuming that x = 1, if you do dados.get(x++) you will have the index item 1 and after this item has been returned (or rather, after the whole expression has been finalized), then the x takes an increment and takes the value 2. Briefly, in literal terms what happens is: dados.get(1)

  • Preincrement (++x): the preincrement happens before the expression ends. For example: assuming that x = 1, if you do dados.get(++x) first the variable x will receive an increment by changing its value to 2 and only after that the previous expression will continue, causing you to take the index 2 of the list, and not the 1. Briefly, in literal terms what happens is: dados.get(2).


That way, even if you do the validation on if, when using the operator as preincrement, you will try to find a non-existent position in your list.

Switch to dados.get(x++) and it will work.

  • 1

    Perfect, that was the mistake I was looking for, I changed the structure but kept the increment before the x, thank you very much!!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.