How to access an attribute in a Java Arraylist?

Asked

Viewed 172 times

0

I created an application that receives some data and gathers in a ArrayList of a class that is in another package. How do I recover an attribute that is private by getter that is in the other class that is not the application?

package pkgpendrive;

import java.util.Scanner;

public class PenDrive {
    private String marca, modelo;
    private int capacidade;
    private double preco;

    public void setCapacidade(String capacidade){
        this.capacidade = capacidade;
    }
    public String getCapacidade(){
        return capacidade;
    }

    public void setPreco(double preco){
        this.preco = preco;
    }
    public double getPreco(){
        return preco;
    }
   .
   .
   .
    public void relatorio(){
        System.out.printf("%-5s %-6s %-10d %-5.2f\n", getMarca, getModelo, getCapacidade, getPreco);
    }

    public PenDrive(){

    }
}

In the application the iteration is created and the report is shown:

import pkgpendrive.PenDrive;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;

public class AppPenDrive_2 {
    public static void main(String[] args) {
        boolean continua = true;
        int escolha = 0, i, totCapacidade = 0, digito;
        double totPreco = 0;
        Scanner kb = new Scanner(System.in);

        ArrayList<PenDrive> penDrive = new ArrayList<PenDrive>();        

        while (continua) {
            PenDrive aux = new PenDrive();

            System.out.println("Pen Drive -- Adicionar [1] Excluir [2]\nParar Aplicaçao [3]");            
            escolha = Integer.parseInt(kb.nextLine());
            if(escolha == 1){
                aux.entradaDados();
                penDrive.add(aux);
            } else {
                if(escolha == 2){
                    i=0;
                    Iterator<PenDrive> iterar = penDrive.iterator();
                    while(iterar.hasNext()){
                        System.out.print("[" +i + "] = " );
                        iterar.next().relatorio();
                        i++;
                    }
                    System.out.print("Excluir [#]: ");
                    digito = Integer.parseInt(kb.nextLine());
                    penDrive.remove(digito);
                } else {
                    continua = false;
                }
            }
        }

        Iterator<PenDrive> iterar = penDrive.iterator();
        System.out.println("\n");
        System.out.println("Marca Modelo Capacidade Preço");
        System.out.println("----- ------ ---------- ------");
        while (iterar.hasNext()) {
            iterar.next().relatorio();
        }
        System.out.println("----- ------ ---------- ------");

        while(iterar.hasNext()){
            totCapacidade += iterar.next().getPreco();
            totPreco += iterar.next().getCapacidade();            
        }

        System.out.println("Capacidade Total: " + totCapacidade);
        System.out.printf("Preço Total: R$%.2f\n", totPreco);
        System.out.println("Quantidade: " + penDrive.size());
    }
}

Output:

Marca Modelo Capacidade Preço
----- ------ ---------- ------
ACME  AC32X  32         220,00
XPTO  ARM32  32         260,00
BEAR  BR16A  16         120,00
----- ------ ---------- ------
Capacidade Total: 0
Preço Total: R$0,00
Quantidade: 3

The idea was to go out like this, as in another application I did, but in this case it was a vector of objects:

Marca Modelo Capacidade Preço
----- ------ ---------- ------
ACME  AC32X  32         220,00
XPTO  ARM32  32         260,00
BEAR  BR16A  16         120,00
----- ------ ---------- ------
Capacidade Total: 80
Preço Total: R$600,00
Quantidade: 3

Just reiterating the question: how do I take the values of a private attribute of another class and sum with another in the application class?

2 answers

1


Your problem is not "access a private attribute of another class". You’re accessing them via getters correctly. The problem is that you are not entering the second while, so the totals are zeroed.

This happens because in the first while (which shows the report) Iterator has already been fully covered. When it comes to the second while (which updates the totals), there are no more elements to be covered, so it even enters this loop, leaving the totals zeroed.

Anyway, a simpler way to scroll through the list and do what you need is simply by using a Enhanced for:

ArrayList<PenDrive> pendrives = new ArrayList<PenDrive>();
// preenche a lista de pendrives ...

System.out.println("Marca Modelo Capacidade Preço");
System.out.println("----- ------ ---------- ------");
for (PenDrive pendrive : pendrives) {
    pendrive.relatorio();
}
System.out.println("----- ------ ---------- ------");

for (PenDrive pendrive : pendrives) {
    totCapacidade += pendrive.getCapacidade();
    totPreco += pendrive.getPreco();
}

I changed the name of the list to pendrives (plural). Since it is a list that can have one or more pendrives, the plural name makes it clearer (call it penDrive, in the singular, may imply - erroneously - that it is only one). It may seem like a minor detail, but giving better names helps a lot when programming.

Although in this case, you can use only one loop, taking advantage to compute the totals at the same time as printing the report:

for (PenDrive pendrive : pendrives) {
    pendrive.relatorio();
    totCapacidade += pendrive.getCapacidade();
    totPreco += pendrive.getPreco();
}

Also note that you were adding the ability to totPreco and vice versa.

Anyway, the problem was the way you were using the Iterator.


If you want to keep using Iterator, you must create a new one each time you want to iterate through the list. Another detail is that each call from next advances to the next element, and as you were calling next twice inside the loop, This causes it to advance two elements (i.e., it takes the price of one and the capacity of the next). To avoid this, call next only once for each iteration and save a variable:

Iterator<PenDrive> iterar = pendrives.iterator();
while (iterar.hasNext()) {
    PenDrive pendrive = iterar.next();
    pendrive.relatorio();
}

// para iterar novamente pela lista, crie outro Iterator
iterar = pendrives.iterator();
while (iterar.hasNext()) {
    PenDrive pendrive = iterar.next(); // só chame next uma vez, senão ele vai pegar o próximo a cada chamada
    totCapacidade += pendrive.getCapacidade();
    totPreco += pendrive.getPreco();
}

In the first while it was not so necessary to guard the return of next in a variable, since you only use the element once. But in the second it does, as already explained.

Reinforcement that also gives to do everything in the same loop (print the report and update the totals), as indicated above.


While you’re at it, you don’t need one either Iterator in the part that shows the options for one to be removed, just use a for simple:

for (int i = 0; i < pendrives.size(); i++) {
    System.out.print("[" + i + "] = ");
    pendrives.get(i).relatorio();
}
System.out.print("Excluir [#]: ");
digito = Integer.parseInt(kb.nextLine());
pendrives.remove(digito);

In this case I didn’t use the Enhanced for because you need the index, so the simplest way is to use a for traditional.

Of course, it was missing to check if the number entered does not exceed the limits of the array, among other details that can be improved but are already beyond the scope of the question.

  • Oops, I was going to answer all this to him now but you were faster! :)

  • 1

    No words to thank you and Flávio, who helped me on another platform. I knew the "for each" from other periods but did not want to use because my current teacher did not teach, only with iterator - that you also helped. Thanks.

-1

Yes, you can do this using Java reflect. Use the Field.setAccessible(true) command if you are accessing from a different class:

import java.lang.reflect.*;

class Other
{
    private String str;
    public void setStr(String value)
    {
        str = value;
    }
}

class Test
{
    public static void main(String[] args) {
        Other t = new Other();
        t.setStr("hi");
        Field field = Other.class.getDeclaredField("str");
        field.setAccessible(true);
        Object value = field.get(t);
        System.out.println(value);
    }
}

Remembering that this should be used carefully since you are violating the class encapsulation.

Browser other questions tagged

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