Home > database >  Split a method into two separate ones and reuse the same list across the invocations
Split a method into two separate ones and reuse the same list across the invocations

Time:10-23

I have a method as follows (simplified for clarity and brevity):

public static List<Person> getPersons(String a, int b, DataSetX dataSetX, DataSetY dataSetY) {
        List<Person> persons = new ArrayList<>();
        
        if(dataSetX != null) {
            while (dataSetX.hasNext()) {
                // create an instance of person with very specific attributes set                
                persons.add(processX(dataSetX.next()));
            }
        }

        if(dataSetY != null) {
            while (dataSetY.hasNext()) {
               // create an instance of person with very specific attributes set               
                persons.add(processY(dataSetY.next()));
            }
        }
        return persons;        
    } 

The method in reality is a bit more complicate than this (doing a bit more processing using also the a and b variables) but overall this is the method structure.

I was thinking to split this method into 2, one method for dealing with DataSetX and the other with DataSetY.
I was thinking to structure it as follows:

public static List<Person> getPersons(String a, DataSetX dataSetX, List<Person> persons) {
        if(dataSetX != null) {
            while (dataSetX.hasNext()) {
                // create an instance of person with very specific attributes set
                persons.add(processX(dataSetX.next()));
            }
        }
        return persons;
}

I would then call the methods as follows:

List<Person> persons = getPersons(a, dataSetX, new ArrayList<Person>());
getPersons(a, dataSetX, persons);    
// now I can use persons list with the result of both present 

With this approach I reuse the same list and don't need to concat 2 different lists from 2 different methods if I just created the list inside the methods and returned.
On the other side it looks kind of weird and possibly error prone.

Is there a way to be able to split the function and avoid creating multiple lists and merging them (as I need 1 list in the end).
Is there some design pattern suited for this?

CodePudding user response:

In my view, this method is not simple and future user of this method will be surprised that this method adds data to List<Person> persons. Why? As method is named getPersons. In my view, people will be think that this method will just return data, not add new data to List<Person> persons.

So, it is better to be consistent with naming of method and do just one thing in method. So I would just read data in method:

public static List<Person> getPersons(String a, DataSetX dataSetX) {
    List<Person> persons = new ArrayList<>();
    if(dataSetX != null) {
        while (dataSetX.hasNext()) {
            // create an instance of person with very specific attributes set
            persons.add(processX(dataSetX.next()));
        }
    }
    return persons;
}

and the second method should look like the above method:

public static List<Person> getPersons(String a, DataSetY dataSetX) {
    List<Person> persons = new ArrayList<>();
    if(dataSetX != null) {
        while (dataSetX.hasNext()) {
            // create an instance of person with very specific attributes set
            persons.add(processX(dataSetX.next()));
        }
    }
    return persons;
}   

In addition, this method can be placed in repository layer. Read more about Repository pattern.

And then you can create a collection and add these data from two methods. I am not Java guy, however, I think it can be done like this:

List<Person> overallPersons = new ArrayList<>();
Collections.addAll(list, getPersons(String a, DataSetX dataSetX));
Collections.addAll(list, getPersons(String a, DataSetY dataSetX));

Read more how to add multiple items to collection in Java

CodePudding user response:

In case if your datasets can be transformed in Stream you can try something like this:

Stream<Object> streamX = dataSetX.stream().map(e -> processX(e));
Stream<Object> streamY = dataSetY.stream().map(e -> processY(e));
List<Person> persons= Stream.concat(streamX , streamY).collect(Collectors.toList());
  • Related