How to optimally read a list of Arraylist dependencies?

Asked

Viewed 202 times

2

I’m in four classes, each class has one ArrayList, where the last element depends on another ArrayList: Example Genêro->Artists->Albuns->Music

To read the songs I’m doing as follows.

for (Genero ge : objeto.getLista()) {
for (ArtistaObj art : ge.getArtistas()) {
     for (AlbunsObj alb : art.getAlbuns()) {
          for (MusicasObj mus : alb.getMusicas()) {
          }
      }
 }

Inside every room I use getters to get all the items on the list, I’m using this to record in a bank and I think q is half pork because on the table Musicas I’m using 4 for.

  • It doesn’t seem like there’s much to improve on. Unless you give more details of what you’re doing it looks like this way is ok.

  • I just asked to know if it has an optimized shape, this way works but using 4 "for" goes against good programming practices.

  • 1

    Where did you see this? You need to review your concepts or stop reading things written by those who do not understand the subject. If you need to scan 4 nested lists and grab each of the elements from each of them, there is no different way. You can write otherwise but in the background the result will be the same. There is a case that can even get worse. There may even be a way to improve me but it would depend on circumstances that don’t seem to be your case.

  • Maybe if you post other parts, explain better, give p/ think of something better. An important detail is that if you will record in bank, the for is the least.

  • You from a given genre want to know all your songs?

  • @daniel12345smith Take a look at [tour]. You can accept an answer if it solved your problem. You can vote on every post on the site as well. Did any help you more? Need something to be improved?

Show 1 more comment

2 answers

3

Given the description of the problem, unless I have not understood something, there is nothing better that can be done.

If you have some detail not explained, eventually you can find an optimization but there is no miracle. Only if there is a criterion that makes it easier to take some shortcut.

One thing you can do is have a single list that has all the data, but it’s hardly a good idea, it makes it easier on the one hand, it makes it harder on the other.

Even with this solution, you may have a for. So what? Why is this a better code? Just because it has fewer ties? That doesn’t mean that the code is better written. Anyway I’d probably have to have three if to identify the cluster break, then perhaps it would be even worse. And another, changes the data structure because of the algorithm. Then it would be a beautiful bad practice in most situations.

And understand that good or bad practice refers to common cases, to a large number of cases. They cannot be followed in all cases.

What you can do is separate it into methods for each interaction, so you would only have one for in each method. But there would still be 4 for. Does this make the code better? In some chaos, yes. But not necessarily, it depends on the goal. Separating too much can bring as many problems as piling too much. It would be something like this (roughly speaking):

void getGeneros(ArrayList biblioteca) {
    for (Genero genero : biblioteca.getLista()) {
        getArtistas(genero);
    }
}

void getArtistas(ArrayList genero) {
    for (Artista artistas : genero.getLista()) {
        getAlbuns(artistas);
    }
}

void getAlbuns(ArrayList artista) {
    for (Album album : artista.getLista()) {
        getMusicas(album);
    }
}

void getMusicas(ArrayList album) {
    for (Musica musica : album.getLista()) {
        GravaMusica(musica);
    }
}

I put in the Github for future reference.

It’s just an example. I have doubts if it’s better, I think it got worse, got repetitive depending on each GetLista() makes. Anyway I think the names of variables and types are better defined there. Since you like good practices, try to name everything in your program, this helps a lot. Could be a better example but I don’t know the whole context.

If the problem is performance it may be possible to break the operation and put the processors to work in parallel, but then the problem would be different from what was described. And it might not even be worth the effort.

0

Use a Functional Programming Style

Within the question you made, there is only this language and programming that you put and another one facing Java 8. At the end I quote another option, but it involves JPA

For each genero, record the same, and return the nested list of Artists it to the pàoxima Funcão.

Or formally: Apply the save function to the Genero parameter - the result of the application of the function is the same as the Generos List

Let’s go to the code

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) throws Exception {
        class MusicasObj {
        }
        class AlbunsObj {
            List<MusicasObj> listMusic = new ArrayList<>();
        }
        class ArtistaObj {
            List<AlbunsObj> listAlbuns = new ArrayList<>();
        }
        class Genero {
            List<ArtistaObj> listArts = new ArrayList<>();
        }
        //Simpleficacão da classe DAO, aqui vc terá o seu método que grava os dados do Genero no Banco, vc precisará de mais DAOs
        class GenDAO{
            Genero save(Genero gen){System.out.println("salvar seu genereo"+gen);return gen;}
        }
        GenDAO dao = new GenDAO();
        List<Genero> listGenero = new ArrayList<>();
        listGenero
            .forEach(g -> dao.save(g)
                    .listArts //Passe a funcão que le os valores do genero e grava ele
                        .forEach(a -> a.listAlbuns
                            .forEach(al -> al.listMusic
                                .forEach(m -> System.out.println(m)))));
    }
}

(Please note, how these class definitions within the method main are for explanatory purposes)

The main difference is a verbosity reduction, however you need to be used to writing Lambda Expressions, based on Lambda Calculus - https://en.wikipedia.org/wiki/Lambda_calculus

The other option is through a ORM Framework - Object Relational Mapping, in this case, I recommend JPA - you map your entities, to database tables creating relationships, between them through metadata - Annotations - finally, the implementation of JPA, as Hibernate will do all the work of inserting and updating the tables, and you do not need to create all this code.

Example with JPA: https://en.wikibooks.org/wiki/Java_Persistence/ManyToOne

Just one more detail, this example code is not complete, you will need to change it and adapt it.

Browser other questions tagged

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