How to access an attribute in an ArrayList in JAVA?

I have created an application that receives some data and gathers into a ArrayList of a class that is in another package. How do I retrieve an attribute that is private by the 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 get 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 from another class and sum with another in the application class?

Author: hkotsubo, 2020-06-01

2 answers

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

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

Anyway, a simpler way to go 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 (in the plural). Since it is a list that can have one or more pendrives, the name in the plural makes this clearer (calling it penDrive, in the singular, may imply-erroneously - that it is only one). It may seem like a beast detail, but giving better names helps a lot when it comes to programming.

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

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

Also notice that you were adding the capacity in totPreco and vice versa.

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


If you want to continue 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 since 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 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 save the return of next in a variable, since you only use the element once. But in the second does, as already explained.

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


Taking advantage, you also do not need a Iterator in the part that shows the options for one to be removed, just use a simple for:

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 did not use enhanced for because you need the index, then the simplest way is using a traditional for.

of course it was missing to check if the number entered does not exceed the limits of the array, among other details that you can improve but already escape the scope of the question.

 1
Author: hkotsubo, 2020-06-01 14:30:51

Yes, it is possible to do this using Java reflect. Use the Field command.setAccessible (true) 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 encapsulation of the class.

 -1
Author: danieltc07, 2020-06-01 13:18:49