简体   繁体   中英

Is there a way to write this “if” list in a more elegant way?

Suppose I have an object POJO style and for some of its attributes I have to check if are equals to a particular value; if so I have to add this attribute to a list and throw an exception (just once if one of the attributes is equal to the particular value). Is there a better way to do it than this way?

// pseudocode
List<String> list = new ArrayList<String>();
boolean haveToThrowException = false;
if (object.getAttributeA().equals(“0”) {
     list.add(object.getAttributeA());
     haveToThrowException = true;
}
if (object.getAttributeB().equals(“0”) {
    list.add(object.getAttributeB());
    haveToThrowException = true;
}
if (object.getAttributeC().equals(“0”) {
    list.add(object.getAttributeC());
    haveToThrowException = true;
}//and so on

if (haveToThrownException) {
    throw new Exception(list.toString());
}

You can do it like this:

List<String> list =
    Stream.of(object.getAttributeA(), object.getAttributeB(), object.getAttributeC())
        .filter("0"::equals)
        .collect(toList());
if (!list.isEmpty()) {
  throw new Exception(list.toString());
}

You can get the values of the attributes in a temporary list or string or other holder of data and then check in one IF statement if the holder contains undesired values. My guess is that you are not interested to recieve a list with the undesired values but you are ineterested in the number of occurences of the undesired value:

//Java 9 syntax of list.of
List<String> allValues = List.of(object.getAttributeA(),object.getAttributeB(),object.getAttributeC());

//frequency will give you the number of occurences.
int numberOfOccurences = Collections.frequency(allValues , undesiredString);    
if (numberOfOccurences  > 0) throw new Exception(undesiredString + " : " + numberOfOccurences );

According to the first answer, you could also do something like this:

Stream.of(object.getAttributeA(), object.getAttributeB(), object.getAttributeC())
    .filter("0"::equals)
    .reduce((var1, var2) -> var1 + var2)
    .ifPresent(string -> {
          throw new RuntimeException(string);
     });

And it seems you don't have to have if, at all.

Yes? I think the Strategy Pattern would work great in this case.

This solution has A LOT more code then the other solutions, but has the advantage of not changing the calling class if you have to check more attributes in the future.

Here is some pseudo code...

public class ThrowsException {

    private Strategy strategy;

    public ThrowsException(Strategy strategy) {

        this.strategy = strategy;
    }

    public void doYourMethod(Object object) {

        List<String> values = this.strategy.checkObject(object);

        if (!values.isEmpty) {

            throw new Exception(values.toString());
        }
    }
}

A class that will iterate of individual strategies so that the calling class doesn't know that there can be more than one strategy.

public class ForLoopStrategy implements Strategy {

    private List<CheckObjectStrategy> strategies

    public ForLoopStrategy(List<CheckObjectStrategy> strategies) {

       this.strategies = strategies;
    }

    public List<String> checkObject(Object object) {

        List<String> values = new ArrayList<>();

        for (CheckObjectStrategy strategy : this.strategies) {

            String value = strategy.checkObject(object);

            if (value != null) {

                values.add(value);
            }
        }
    }
}

The actual class that will check a specific attribute. One will be needed for every attribute that you want to check.

public class CheckAttributeA implements CheckObjectStrategy {

    public String checkObject(Object object) {

        String value = null;

        if (object.getAttributeA().equals("0")) {
            value = object.getAttributeA();
        }

        return value; 
    }
}

BTW, I am sure that there is something simpler here if you could use reflection to call the different attributes...

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