Java 8 alternative for validating data inside multiple nested loops

javax validation constraints java 8
java form validation
hibernate validator
mandatory field validation in java
data validation java
java validator pattern
java input validation
java validation library

I have a question regarding validating data in a nested for loop.

public class Object1{
  private String obj1Name;

  private String obj1Desc;

  private List<Object2> object2List;

  //Setters and getters
}


public class Object2{
  private String obj2Name;

  private String obj2Desc;

  private List<Object3> object3List;

  //Setters and getters
}

public class Object3{
  private String obj3Name;

  private String obj3Desc;
  //Setters and getters
}

I wish to validate both name and desc in all objects, instead of using a nested loop like the following:

List<Object1> object1List = getObject1List();

for(Object1 object1 : object1List ){
   if(object1.getObj1Name() == null){
     //throw error
   }

   if(object1.getObj1Desc() == null){
     //throw error
   }

   for(Object2 object2 : object1.getObject2List()){
        if(object2.getObj2Name() == null){
            //throw error
        }

        if(object2.getObj2Desc() == null){
            //throw error
        }

        //loop Object 3 ...
   }
}

Is there any better way to do it?


I am just going to say it here, so that no one does what you want to do - use a proper framework for this, personally I would go for Hibernate Validator - super easy to integrate and use IMO. It will support that nesting that you have without any problems and there are tons of tutorials online (even their own is good) and how to achieve that; hint: a few dependencies and a few annotations and you are done.

Java Concepts: Late Objects, HashMap<K, V> class, A-22 HashSet constructor, java.util. 11 writing, 8–10 HelloPrinter.java class, 11 high-level languages, 6 history of computers Altair definition, 84 duplicate code in branches, 90 ending with a semicolon, 88 flowchart for, 118–120 multiple alternatives, 98–101 nesting, 102–107 sample program,  If you are lucky, you can replace the loops with for-each loops. However, often the indices are required for computations inside the loop. In such a case you can come up with a simple utility


EDIT: An idea to externalize the check, you need to create Functional Interface

ObjectValidatorInterface ov = new ObjectValidator();
if(!object1List.stream().allMatch(o -> ov.validate(o, Object1.class))) {
        // throw error;
}

And the interface

@FunctionalInterface
interface ObjectValidatorInterface {
    boolean validate(Object object, Class clazz);
}

class ObjectValidator implements ObjectValidatorInterface {

    public boolean validate(Object object, Class clazz) {
        boolean valid = false;

        if(Object1.class.getName().equals(clazz.getName())) {
            valid = validateObject1((Object1) object);

        } else if(Object2.class.getName().equals(clazz.getName())) {
            valid = validateObject2((Object2) object);

        } else if(Object3.class.getName().equals(clazz.getName())) {
            valid = validateObject3((Object3) object);
        }

        return valid;
    }

    private boolean validateObject1(Object1 o) {
        boolean valid;
        valid = o.getObj1Name() != null && o.getObj1Desc() != null;
        if(!(o.getObject2List() == null || o.getObject2List().isEmpty())) {
            valid = valid && o.getObject2List().stream().allMatch(o2 -> validate(o2, Object2.class));
        }
        return valid;
    }

    private boolean validateObject2(Object2 o) {
        boolean valid;
        valid = o.getObj2Name() != null && o.getObj2Desc() != null;
        if(!(o.getObject3List() == null || o.getObject3List().isEmpty())) {
            valid = valid && o.getObject3List().stream().allMatch(o3 -> validate(o3, Object3.class));
        }
        return valid;
    }

    private boolean validateObject3(Object3 o) {
        return o.getObj3Name() != null && o.getObj3Desc() != null;
    }
}

ORIGINAL ANSWER

You might be able to do it by delegating the validation to each object:

List<Object1> object1List = getObject1List();

if(!object1List.stream().allMatch(Object1::isValid)) {
    //throw error
}

And add an isValid method to each object

public class Object1 {
    private String obj1Name;
    private String obj1Desc;
    private List<Object2> object2List;

    public boolean isValid() {
        return obj1Name != null
            && obj1Desc != null
            && object2List.stream().allMatch(Object2::isValid);
    }
}

public class Object2 {
    private String obj2Name;
    private String obj2Desc;
    private List<Object3> object3List;

    public boolean isValid() {
        return obj2Name != null
            && obj2Desc != null
            && object3List.stream().allMatch(Object3::isValid);
    }
}

public class Object3 {
    private String obj3Name;
    private String obj3Desc;

    public boolean isValid() {
        return obj3Name != null
            && obj3Desc != null;
    }
}

Are too many if-else statements for validation bad?, so I wrote this in notepad using C# syntax (which might be identical to JAVA). Rules change all the time in banks and rules have complex relationships with each Then all of those if-then-else statements can be replaced by a simple loop I would use Data Annotations or similar attribute based validation framework. Nested Loops In Java: Java Nested loops are very common in programming, when we have to call a loop multiple times. For e.g., printing 1 2 3 4 5, can be done using a


Well, you can definitely avoid the "nesting" by using the Stream API:

if(object1List.stream()
                .anyMatch(a -> a.getObj1Name() == null ||
                        a.getObj1Desc() == null)){
    // throw error
}else if(object1List.stream()
                .anyMatch(a -> a.getObject2List().stream()
                       .anyMatch(b -> b.getObj2Name() == null ||
                                            b.getObj2Desc() == null))){
    // throw error
}else if(object1List.stream()
                .anyMatch(a -> a.getObject2List().stream()
                        .anyMatch(b -> b.getObject3List().stream()
                                .anyMatch(c -> c.getObj3Name() == null ||
                                                      c.getObj3Desc() == null)))){
     // throw error
}

Another approach being more compact, but probably less efficient:

boolean result = object1List.stream()
                .flatMap(a -> a.getObject2List().stream()
                        .flatMap(b -> b.getObject3List().stream()
                                .flatMap(c -> Stream.of(a.getObj1Name(),
                                        a.getObj1Desc(), b.getObj2Name(),
                                        b.getObj2Desc(), c.getObj3Name(), c.getObj3Desc()))))
                .anyMatch(Objects::isNull); 

if(result){ // throw error }

So, to conclude if performance is a concern then proceed with your approach or try and see if the parallel stream API can do you any good, otherwise, the above should suffice.

Replace your if..else if…/ nested if-not-null -then-get blocks with , Optional is a welcome inclusion in Java 8, famously as an alternative for null values. The main intent nested if-not-null -then-get blocks with Java 8 Optional(​s) As an example, consider the following password validation fragment using the said Optional chaining in Java 8 - DynamoDB Data Modeling. Brought to you by http://www.rasmurtech.com/ The Rasmurtech Community: http://goo.gl/mt6OzH In this tutorial I will show you how to use Nested Loops. Eclipse


A validator, as a functional interface, is a Consumer which consumes a value of a specific type, performs checks and throws an Exception if something is off.

Traversal of the data structure (Tree) can be accomplished over streams (peek to visit a node, flatmap to recurse into the children). For the validation, we introduce a NO-OP map operation, which validates and returns the value, allowing the stream to continue.

BiConsumer<String, Object> checkRequired = (name, value) -> {
    if (value == null) {
        throw new IllegalArgumentException(name + " is required");
    }
};

Consumer<Object1> obj1Validator = obj1 -> {
    checkRequired.accept("Object1", obj1);
    checkRequired.accept("obj1Name", obj1.getObj1Name());
    checkRequired.accept("obj1Desc", obj1.getObj1Desc());
};

Consumer<Object2> obj2Validator = obj2 -> {
    checkRequired.accept("Object2", obj2);
    checkRequired.accept("obj2Name", obj2.getObj2Name());
    checkRequired.accept("obj2Desc", obj2.getObj2Desc());
};

Consumer<Object3> obj3Validator = obj3 -> {
    checkRequired.accept("Object3", obj3);
    checkRequired.accept("obj3Name", obj3.getObj3Name());
    checkRequired.accept("obj3Desc", obj3.getObj3Desc());
};

Object1 obj1 = ...; // assign some value

Stream.of(obj1)
    .peek(obj1Validator)
    .filter(x -> x.getObject2List() != null)
    .map(Object1::getObject2List)
    .filter(Objects::nonNull)
    .flatMap(List::stream)
    .peek(obj2Validator)
    .map(Object2::getObject3List)
    .filter(Objects::nonNull)
    .flatMap(List::stream)
    .peek(obj3Validator)
    .count();

Part 2: Processing Data with Java SE 8 Streams, Combine advanced operations of the Stream API to express rich data processing queries. Originally published in the May/June 2014 issue of Java Magazine. Our first attempt is actually printing the String representation of several streams! For example, Listing 15 shows an alternative way to calculate the sum of all  Instead of multi-loop, If you can categorize all the threads into a loop, you can easily go with the less complexity with the in python, and for the nested loop, it is total standing with the loop in between the loop.


Well, you could use a function/loop which sifts through an object(The generic Object). That way, you won't have to run a separate for loop for each object if the name of the member variable "desc" is uniform in all the three objects. But that's another level of nesting so not sure you'd want to use that if you're just looking to avoid nesting.

Refactoring with Loops and Collection Pipelines, In this article I look at refactoring loops to collection pipelines with a series of For a second example, I'll refactor a simple, doubly nested loop. With Java's streams library, the pipeline has to end with a terminal (such by the data model, such constraints are checked by a validation function such as this. Nested loops have performance considerations (see @Travis-Pesetto's answer), but sometimes it's exactly the correct algorithm, e.g. when you need to access every value in a matrix. Labeling loops in Java allows to prematurely break out of several nested loops when other ways to do this would be cumbersome.


Jakarta Bean Validation, Containers can contain one value, or several values ( Optional vs Collection ). For the metadata build up, I don't think we end up in an infinite loop. Value type is the data type returned by the extractor, for example: Gunnar proposes an alternative to the extractor. Java 8 annotations can be placed on all type use. Nested Loop in Java In this article, you will learn about nested loops and how it works with the help of examples. If a loop exists inside the body of another loop, it's called a nested loop.


Conditionals and Loops, The for loop is an alternate Java construct that allows us even more flexibility when writing It uses several nested if-else statements to test from among a number of Verify this claim by writing a program Ramanujan.java that takes an integer Find an optimal sorting network for 6, 7, and 8 inputs, using 12, 16, and 19 if  Nested loops in java are just a for loop inside a for loop. A common way to use nested loops in java is to get elements from a 2d array. To do that, your outer for loops takes care of the rows and


Hibernate Validator 6.1.5.Final, Validating data is a common task that occurs throughout all Hibernate Validator 6 and Jakarta Bean Validation 2.0 require Java 8 or later if any of the Manufacturer objects contained in the list nested in the map values has a null name While class-level constraints apply to several properties of a bean,  A loop within a loop: nested for loops in Java are a way to perform more complicated tasks and routines. In this lesson, we'll learn the syntax for nested loops and also look at some examples.