Add the 5 highest values to an array

Asked

Viewed 715 times

4

I have the following method:

public static void topFiveSales(int idEmpresa) {
    List < Entidade > allList = Entidade.findByEmpresa(idEmpresa);
    float totalVendasByEntidade;
    Float[] totais = new Float[5];

    for (Entidade ent: allList) {
        totalVendasByEntidade = entidade.valor;
        for (int i = 0; i < 5; i++) {
            if (totalVendasByEntidade > totais[i]) {
                totais[i] = totalVendasByEntidade;
            }
        }
    }
}

What will be the best way for me to receive the value totalVendasByEntidade and add it to a Array of 5 positions and each time I receive that value from each entity, I compare it to the 5 values of the Array and if it is larger than one of them, replace it with the minor?

2 answers

3


Let’s do in 3 steps what you need.

first) Your entity needs to be compared to another entity so we can sort the list. To do so, we will implement the Comparable interface and say that when comparing one Entity with the other, we will compare the value of the entities. Thus:

public class Entidade implements Comparable<Entidade>{
   // codigo que ja tinha antes
   @Override
   public int compareTo(Entidade outraEntidade){
        if (this.valor < outraEntidade.valor) {
            return -1;
        }
        else if (this.valor > outraEntidade.valor) {
            return 1;
        }
        else return 0;
   }

2nd) To sort the array using the functions of the Collections class, we need to create a "comparator" that compares one entity with the other. We will do this we will implement the Comparator interface, as the following code:

public class EntidadeComparator implements Comparator<Entidade> {
    public int compare(Entidade entidade, Entidade outraEntidade) {
        return Entidade.getValor().
                compareTo(outraEntidade.getValor());
    }
}

3º) At last, your way topFiveSales, return the list with listTopFiveSales.

SUGGESTION: methods represent actions in our class. For better code coherence, I suggest changing the name of the topFiveSales for listTopFiveSales or getTopFiveSales

His code is simple:

  • Search the complete list (allList)
  • Sort the list ascendantly
  • If size(list) is less than or equal to 5 elements, returns the list
  • Otherwise, we take the last five elements and return
  • I also put the option to return the ascending or descending list

Follows the code:

public static List<Entidade> getTopFiveSales(int idEmpresa) {
        List < Entidade > allList = Entidade.findByEmpresa(idEmpresa);
        Collections.sort(allList, new EntidadeComparator());
        List<Entidade> listTopFive = null;
        if(allList.size() <= 5){
           listTopFive = allList;
        }
        else{
          listTopFive = allList.sublist(allList.size()-5,allList.size());
        }
        return listTopFive; //retorna a lista de forma crescente
        // return Collections.reverse(listTopFive); // retorna a lista de forma decrescente
    }

Recapturing what has been done:

1) Our Entity has implemented the Comparable interface saying how one Entity will be compared to the other.
2) Create a Comparator that compares 2 entities.
3) We have implemented the method and used Collections.Sort(array,Comparator) using the framework we created.

I hope I’ve been helpful.

Source: Blog da Caelum

EDIT: explanation of the method sublist

According to the documentation of Arraylist, the method
subList(int fromIndex, int toIndex) returns a sublist of fromIndex inclusive up to the toIndex exclusive.

In our method we use listTopFive = allList.sublist(allList.size()-5,allList.size()); Using an array of 7 positions as an example : [0,1,2,3,4,5,6] , we’ll get size-5 = 2 (inclusive) until size(exclusive), i.e.: size-1 So we’ll get the elements [2,3,4,5,6] which are the last 5 array.

1

One way is to first sort the vector in descending order, and then just take the first five elements of the vector.

// Declara um vetor temporário do mesmo tamanho que a lista.
Float[] temp = new Float[allList.size()];

// Adiciona todos os valores para o vetor temporário.
for(int i=0; i< allList.size(); i++) {
    temp[i] = allList[i].valor;
}

// Ordena o vetor em ordem decrescente
Float.sort(temp, (a, b) -> Float.compare(b, a), false);

// Adiciona para o vetor de totais os cinco primeiros maiores valores
for (int i = 0; i < 5; i++) {
    totais[i] = temp[i];
}
  • Can you give me an example of how to do that ?

  • I don’t know if you noticed but my vector is of 5 positions and start with all the values to 0, and later it is that comparing and replacing.

  • Yes, I did. I updated my answer with an example code.

  • the variable 'a' and 'b' are what? used thus?

  • They can be any name, and are the values of the vector being compared. For example, for a vector [1, 3, 7, 10], when comparing 1 with 3 to see which value is higher the 'a' would be 1 and the 'b' would be the three. The process is repeated for all elements of the vector until the vector is ordered.

  • The point is that allList is a List of the 'Entity' object and I need to have access to that entity to fetch the 'value'

  • Wouldn’t a cast solve this case? As in temp[i] = ((Entity)allList[i]). value

  • No, it does not work, as well as Float.Sort gives error :s

  • Today I’m out of time :s I’m sorry, I’m at work

  • @Ulysses Alves, I made a step by step response, see if it helps

  • @Hugomachado see the answer

Show 7 more comments

Browser other questions tagged

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