简体   繁体   中英

Generalizing an iterative function over a collection of Objects in Java

I have to generalize this repeating and repeating code into a single method is it possible ?

//attrrischio
        SagTblObjAttrischioang sagTblObjAttrischioang = elemtOut.getAttrischio();

        if(sagTblObjAttrischioang.length()>0)
        {
            for (int j = 0; j <sagTblObjAttrischioang.length(); j++) {
                SagObjAttrischioang item = sagTblObjAttrischioang.getElement(j);

                System.out.println(ToStringEntities.toString(item));
            }
        }

//          beni

SagTblObjBeniang sagTblObjBeniang = elemtOut.getBeni();

        if(sagTblObjBeniang.length()>0)
        {
            for (int j = 0; j <sagTblObjBeniang.length(); j++) {
                SagObjBeniang item = sagTblObjBeniang.getElement(j);

                System.out.println(ToStringEntities.toString(item));
            }
        }

and over and over again

If all the behaviour you need in both loops is to print the toString() of each item, then a method such as this should suffice:

public void printItems(Iterator<Object> items){
    while(items.hasNext()){
        Object item = items.next();
        System.out.println(item.toString());
    }
}

where you override the toString method of all your entities to print in the format you need.

Both SagTblObjAttrischioang and SagTblObjBeniang implement a common interface (eg SagTabObj and implement method like length and getElement to return another common interface SabTab .

then create a common method like

public void printItems(SabTabObj item){
   if(item.length()>0)
    {
        for (int j = 0; j < item.length(); j++) {
            SagTab sabTab = item.getElement(j);

            System.out.println(ToStringEntities.toString(sabTab));
        }
    }
}

I see that your SagObjAttrischioang and SagTblObjBeniang (whatever those may be ?) classes both support a getElement(int) method. If they do not both inherit from an abstract class or implement an interface, then you should refactor your code of these classes. Then you can refactor your elemtOut to a Collection of this abstract class or interface, which will make it much easier to iterate over. Why don't you post the code of your classes you are you using ? I think the design of your classes needs some improvement.

If you want to cover both arrays and Iterable (which is the interface that concerns you question ... since you need to iter through them). Use something like that:

import java.util.Arrays;

[...]

public static void printAll(Object[] stuff) {
    printAll(Arrays.asList(stuff));
}

public static void printAll(Iterable<?> stuff) {
    for (Object o : stuff) {
        System.out.println(o);
    }
}

You need two functions because of the peculiar kind of object that are arrays in Java. The "foreach" loop will take care of the case in which the collection is empty (so does the normal for loop by the way, checking that length > 0 only save you an int declaration).

Also object.toString() is called automatically on println() if the object is not one of the primitive base types (byte, char, short, int, long, float, double and boolean), so no need to use it yourself in the code (make your code as short as possible).

I think about two solutions :

  1. You should make your classes implement the same interface (or inherit from the same class). see Sajan Chandran answer's for such a possibility.
  2. It might look stupid but if your classes SagObjAttrischioang and SagTblObjBeniang only implement lenght() and getElement(int) , why not use List instead? (or even collection).

How about encapsulating it in:

public void myMethod()
{
  ... your code...
}

and then looping:

while (true)
  myMethod();

That should do it :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM