Java 8 alternative for validating data inside multiple nested loops

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
8
down vote

favorite












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?










share|improve this question



















  • 7




    are you throwing the same error on each condition ? if so, what type of error?
    – Aomine
    Dec 5 at 12:42











  • yes, throwing same error on each condition, the error will be InvalidParameterException
    – hades
    Dec 5 at 13:10










  • You might find useful docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
    – Federico Piazza
    Dec 5 at 13:22






  • 3




    don't get me wrong but have you considered a framework with support for @NotNull?
    – Eugene
    Dec 5 at 13:28










  • @Eugene Exactly what I wanted to point out as well. I mean that's what something like javax.validation.constraints are meant for.
    – nullpointer
    Dec 5 at 13:33














up vote
8
down vote

favorite












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?










share|improve this question



















  • 7




    are you throwing the same error on each condition ? if so, what type of error?
    – Aomine
    Dec 5 at 12:42











  • yes, throwing same error on each condition, the error will be InvalidParameterException
    – hades
    Dec 5 at 13:10










  • You might find useful docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
    – Federico Piazza
    Dec 5 at 13:22






  • 3




    don't get me wrong but have you considered a framework with support for @NotNull?
    – Eugene
    Dec 5 at 13:28










  • @Eugene Exactly what I wanted to point out as well. I mean that's what something like javax.validation.constraints are meant for.
    – nullpointer
    Dec 5 at 13:33












up vote
8
down vote

favorite









up vote
8
down vote

favorite











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?










share|improve this question















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?







java java-8






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 6 at 4:17









Boann

36.6k1287121




36.6k1287121










asked Dec 5 at 12:36









hades

69411030




69411030







  • 7




    are you throwing the same error on each condition ? if so, what type of error?
    – Aomine
    Dec 5 at 12:42











  • yes, throwing same error on each condition, the error will be InvalidParameterException
    – hades
    Dec 5 at 13:10










  • You might find useful docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
    – Federico Piazza
    Dec 5 at 13:22






  • 3




    don't get me wrong but have you considered a framework with support for @NotNull?
    – Eugene
    Dec 5 at 13:28










  • @Eugene Exactly what I wanted to point out as well. I mean that's what something like javax.validation.constraints are meant for.
    – nullpointer
    Dec 5 at 13:33












  • 7




    are you throwing the same error on each condition ? if so, what type of error?
    – Aomine
    Dec 5 at 12:42











  • yes, throwing same error on each condition, the error will be InvalidParameterException
    – hades
    Dec 5 at 13:10










  • You might find useful docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
    – Federico Piazza
    Dec 5 at 13:22






  • 3




    don't get me wrong but have you considered a framework with support for @NotNull?
    – Eugene
    Dec 5 at 13:28










  • @Eugene Exactly what I wanted to point out as well. I mean that's what something like javax.validation.constraints are meant for.
    – nullpointer
    Dec 5 at 13:33







7




7




are you throwing the same error on each condition ? if so, what type of error?
– Aomine
Dec 5 at 12:42





are you throwing the same error on each condition ? if so, what type of error?
– Aomine
Dec 5 at 12:42













yes, throwing same error on each condition, the error will be InvalidParameterException
– hades
Dec 5 at 13:10




yes, throwing same error on each condition, the error will be InvalidParameterException
– hades
Dec 5 at 13:10












You might find useful docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
– Federico Piazza
Dec 5 at 13:22




You might find useful docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
– Federico Piazza
Dec 5 at 13:22




3




3




don't get me wrong but have you considered a framework with support for @NotNull?
– Eugene
Dec 5 at 13:28




don't get me wrong but have you considered a framework with support for @NotNull?
– Eugene
Dec 5 at 13:28












@Eugene Exactly what I wanted to point out as well. I mean that's what something like javax.validation.constraints are meant for.
– nullpointer
Dec 5 at 13:33




@Eugene Exactly what I wanted to point out as well. I mean that's what something like javax.validation.constraints are meant for.
– nullpointer
Dec 5 at 13:33












6 Answers
6






active

oldest

votes

















up vote
4
down vote













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.






share|improve this answer






















  • yeah, i actually know about hibernate validator, normally i use it to validate object request in @RequestBody.
    – hades
    Dec 5 at 13:43










  • Thanks for the reminder, it don't come into my mind because i thought there is no way triggering the validation process, but it actually has.
    – hades
    Dec 5 at 14:20

















up vote
3
down vote













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

private boolean validateObject2(Object2 o)

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;







share|improve this answer


















  • 3




    I really dislike this - you put the validation conditions inside the POJO itself - is this ever a good idea? what if there are 100 of these?
    – Eugene
    Dec 5 at 13:24










  • good one, but I think these isValid methods should be moved out of the POJO classes
    – Andrew Tobilko
    Dec 5 at 13:24










  • @Bentaye nope, the field names are different - this would not work
    – Eugene
    Dec 5 at 13:27










  • @Eugene Added an other version where the check is done by an external object
    – Bentaye
    Dec 5 at 14:22










  • @Bentaye well that is a bit better, I agree. But now, imagine supporting that and testing it correctly, with at least 10 different validation types and rules... you might be on the verge of the next mission impossible movie, which I would not want to be part of
    – Eugene
    Dec 5 at 14:23

















up vote
1
down vote













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.






share|improve this answer


















  • 6




    to me, it's way worse than OP's approach
    – Andrew Tobilko
    Dec 5 at 13:12






  • 1




    @AndrewTobilko the goal was to remove the nesting, and even in terms of efficiency that really depends on the number of elements in the source.
    – Aomine
    Dec 5 at 13:14






  • 2




    Yeah, flatmap that shit.
    – michid
    Dec 5 at 13:24

















up vote
1
down vote













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();





share|improve this answer






















  • now imagine supporting this for numerous rules and fields... seriously, don't.
    – Eugene
    Dec 5 at 13:40










  • @Eugene that's what validation is about - check each model and each field. Of course that validation can be delegated to a framework, such as using Bean Validation (JSR-380) which drives field validations over annotations.
    – Peter Walser
    Dec 5 at 13:47










  • would you write this code or use a framework? that was my point
    – Eugene
    Dec 5 at 13:48










  • I would certainly use a framework, in particular Bean Validation (JSR-380, beanvalidation.org/specification)
    – Peter Walser
    Dec 5 at 14:07

















up vote
0
down vote













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.






share|improve this answer



























    up vote
    0
    down vote













    If their validation seems to be the same, only the type change, then use interface have Object1, Object2 and Object3 implements ICommon:



    interface ICommon 
    String getField1();
    int getField2();
    Iterable<? extends ICommon> getChildren();



    Then have this:



    private void validate0(String prefix, ICommon common) 
    if (common.getField1() == null) throw new ValidationException(prefix + ".field1 can't be null");
    if (common.getField2() == null) throw new ValidationException(prefix + ".field2 can't be null");
    int index = 0;
    for (ICommon child : getChildren())
    validate0(prefix + ".children[" + index + "]", child);
    ++index;



    public void validate(ICommon common)
    validate0("common", common);



    You may also invert this using a BiConsumer<String, ICommon> (or Consumer<ICommon>) to validate if you don't care about proper error reporting).



    • This will also make it clearer about which validation may apply on your object

    • Using stream does not (always) make it clearer (see Peter Walser answer and try to understand the big stream :)).





    share|improve this answer




















      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53632516%2fjava-8-alternative-for-validating-data-inside-multiple-nested-loops%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      6 Answers
      6






      active

      oldest

      votes








      6 Answers
      6






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      4
      down vote













      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.






      share|improve this answer






















      • yeah, i actually know about hibernate validator, normally i use it to validate object request in @RequestBody.
        – hades
        Dec 5 at 13:43










      • Thanks for the reminder, it don't come into my mind because i thought there is no way triggering the validation process, but it actually has.
        – hades
        Dec 5 at 14:20














      up vote
      4
      down vote













      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.






      share|improve this answer






















      • yeah, i actually know about hibernate validator, normally i use it to validate object request in @RequestBody.
        – hades
        Dec 5 at 13:43










      • Thanks for the reminder, it don't come into my mind because i thought there is no way triggering the validation process, but it actually has.
        – hades
        Dec 5 at 14:20












      up vote
      4
      down vote










      up vote
      4
      down vote









      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.






      share|improve this answer














      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.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Dec 5 at 19:18

























      answered Dec 5 at 13:39









      Eugene

      67.6k997160




      67.6k997160











      • yeah, i actually know about hibernate validator, normally i use it to validate object request in @RequestBody.
        – hades
        Dec 5 at 13:43










      • Thanks for the reminder, it don't come into my mind because i thought there is no way triggering the validation process, but it actually has.
        – hades
        Dec 5 at 14:20
















      • yeah, i actually know about hibernate validator, normally i use it to validate object request in @RequestBody.
        – hades
        Dec 5 at 13:43










      • Thanks for the reminder, it don't come into my mind because i thought there is no way triggering the validation process, but it actually has.
        – hades
        Dec 5 at 14:20















      yeah, i actually know about hibernate validator, normally i use it to validate object request in @RequestBody.
      – hades
      Dec 5 at 13:43




      yeah, i actually know about hibernate validator, normally i use it to validate object request in @RequestBody.
      – hades
      Dec 5 at 13:43












      Thanks for the reminder, it don't come into my mind because i thought there is no way triggering the validation process, but it actually has.
      – hades
      Dec 5 at 14:20




      Thanks for the reminder, it don't come into my mind because i thought there is no way triggering the validation process, but it actually has.
      – hades
      Dec 5 at 14:20












      up vote
      3
      down vote













      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

      private boolean validateObject2(Object2 o)

      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;







      share|improve this answer


















      • 3




        I really dislike this - you put the validation conditions inside the POJO itself - is this ever a good idea? what if there are 100 of these?
        – Eugene
        Dec 5 at 13:24










      • good one, but I think these isValid methods should be moved out of the POJO classes
        – Andrew Tobilko
        Dec 5 at 13:24










      • @Bentaye nope, the field names are different - this would not work
        – Eugene
        Dec 5 at 13:27










      • @Eugene Added an other version where the check is done by an external object
        – Bentaye
        Dec 5 at 14:22










      • @Bentaye well that is a bit better, I agree. But now, imagine supporting that and testing it correctly, with at least 10 different validation types and rules... you might be on the verge of the next mission impossible movie, which I would not want to be part of
        – Eugene
        Dec 5 at 14:23














      up vote
      3
      down vote













      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

      private boolean validateObject2(Object2 o)

      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;







      share|improve this answer


















      • 3




        I really dislike this - you put the validation conditions inside the POJO itself - is this ever a good idea? what if there are 100 of these?
        – Eugene
        Dec 5 at 13:24










      • good one, but I think these isValid methods should be moved out of the POJO classes
        – Andrew Tobilko
        Dec 5 at 13:24










      • @Bentaye nope, the field names are different - this would not work
        – Eugene
        Dec 5 at 13:27










      • @Eugene Added an other version where the check is done by an external object
        – Bentaye
        Dec 5 at 14:22










      • @Bentaye well that is a bit better, I agree. But now, imagine supporting that and testing it correctly, with at least 10 different validation types and rules... you might be on the verge of the next mission impossible movie, which I would not want to be part of
        – Eugene
        Dec 5 at 14:23












      up vote
      3
      down vote










      up vote
      3
      down vote









      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

      private boolean validateObject2(Object2 o)

      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;







      share|improve this answer














      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

      private boolean validateObject2(Object2 o)

      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;








      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Dec 5 at 14:20

























      answered Dec 5 at 13:19









      Bentaye

      3,77131729




      3,77131729







      • 3




        I really dislike this - you put the validation conditions inside the POJO itself - is this ever a good idea? what if there are 100 of these?
        – Eugene
        Dec 5 at 13:24










      • good one, but I think these isValid methods should be moved out of the POJO classes
        – Andrew Tobilko
        Dec 5 at 13:24










      • @Bentaye nope, the field names are different - this would not work
        – Eugene
        Dec 5 at 13:27










      • @Eugene Added an other version where the check is done by an external object
        – Bentaye
        Dec 5 at 14:22










      • @Bentaye well that is a bit better, I agree. But now, imagine supporting that and testing it correctly, with at least 10 different validation types and rules... you might be on the verge of the next mission impossible movie, which I would not want to be part of
        – Eugene
        Dec 5 at 14:23












      • 3




        I really dislike this - you put the validation conditions inside the POJO itself - is this ever a good idea? what if there are 100 of these?
        – Eugene
        Dec 5 at 13:24










      • good one, but I think these isValid methods should be moved out of the POJO classes
        – Andrew Tobilko
        Dec 5 at 13:24










      • @Bentaye nope, the field names are different - this would not work
        – Eugene
        Dec 5 at 13:27










      • @Eugene Added an other version where the check is done by an external object
        – Bentaye
        Dec 5 at 14:22










      • @Bentaye well that is a bit better, I agree. But now, imagine supporting that and testing it correctly, with at least 10 different validation types and rules... you might be on the verge of the next mission impossible movie, which I would not want to be part of
        – Eugene
        Dec 5 at 14:23







      3




      3




      I really dislike this - you put the validation conditions inside the POJO itself - is this ever a good idea? what if there are 100 of these?
      – Eugene
      Dec 5 at 13:24




      I really dislike this - you put the validation conditions inside the POJO itself - is this ever a good idea? what if there are 100 of these?
      – Eugene
      Dec 5 at 13:24












      good one, but I think these isValid methods should be moved out of the POJO classes
      – Andrew Tobilko
      Dec 5 at 13:24




      good one, but I think these isValid methods should be moved out of the POJO classes
      – Andrew Tobilko
      Dec 5 at 13:24












      @Bentaye nope, the field names are different - this would not work
      – Eugene
      Dec 5 at 13:27




      @Bentaye nope, the field names are different - this would not work
      – Eugene
      Dec 5 at 13:27












      @Eugene Added an other version where the check is done by an external object
      – Bentaye
      Dec 5 at 14:22




      @Eugene Added an other version where the check is done by an external object
      – Bentaye
      Dec 5 at 14:22












      @Bentaye well that is a bit better, I agree. But now, imagine supporting that and testing it correctly, with at least 10 different validation types and rules... you might be on the verge of the next mission impossible movie, which I would not want to be part of
      – Eugene
      Dec 5 at 14:23




      @Bentaye well that is a bit better, I agree. But now, imagine supporting that and testing it correctly, with at least 10 different validation types and rules... you might be on the verge of the next mission impossible movie, which I would not want to be part of
      – Eugene
      Dec 5 at 14:23










      up vote
      1
      down vote













      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.






      share|improve this answer


















      • 6




        to me, it's way worse than OP's approach
        – Andrew Tobilko
        Dec 5 at 13:12






      • 1




        @AndrewTobilko the goal was to remove the nesting, and even in terms of efficiency that really depends on the number of elements in the source.
        – Aomine
        Dec 5 at 13:14






      • 2




        Yeah, flatmap that shit.
        – michid
        Dec 5 at 13:24














      up vote
      1
      down vote













      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.






      share|improve this answer


















      • 6




        to me, it's way worse than OP's approach
        – Andrew Tobilko
        Dec 5 at 13:12






      • 1




        @AndrewTobilko the goal was to remove the nesting, and even in terms of efficiency that really depends on the number of elements in the source.
        – Aomine
        Dec 5 at 13:14






      • 2




        Yeah, flatmap that shit.
        – michid
        Dec 5 at 13:24












      up vote
      1
      down vote










      up vote
      1
      down vote









      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.






      share|improve this answer














      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.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Dec 5 at 13:13

























      answered Dec 5 at 13:11









      Aomine

      36.3k62961




      36.3k62961







      • 6




        to me, it's way worse than OP's approach
        – Andrew Tobilko
        Dec 5 at 13:12






      • 1




        @AndrewTobilko the goal was to remove the nesting, and even in terms of efficiency that really depends on the number of elements in the source.
        – Aomine
        Dec 5 at 13:14






      • 2




        Yeah, flatmap that shit.
        – michid
        Dec 5 at 13:24












      • 6




        to me, it's way worse than OP's approach
        – Andrew Tobilko
        Dec 5 at 13:12






      • 1




        @AndrewTobilko the goal was to remove the nesting, and even in terms of efficiency that really depends on the number of elements in the source.
        – Aomine
        Dec 5 at 13:14






      • 2




        Yeah, flatmap that shit.
        – michid
        Dec 5 at 13:24







      6




      6




      to me, it's way worse than OP's approach
      – Andrew Tobilko
      Dec 5 at 13:12




      to me, it's way worse than OP's approach
      – Andrew Tobilko
      Dec 5 at 13:12




      1




      1




      @AndrewTobilko the goal was to remove the nesting, and even in terms of efficiency that really depends on the number of elements in the source.
      – Aomine
      Dec 5 at 13:14




      @AndrewTobilko the goal was to remove the nesting, and even in terms of efficiency that really depends on the number of elements in the source.
      – Aomine
      Dec 5 at 13:14




      2




      2




      Yeah, flatmap that shit.
      – michid
      Dec 5 at 13:24




      Yeah, flatmap that shit.
      – michid
      Dec 5 at 13:24










      up vote
      1
      down vote













      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();





      share|improve this answer






















      • now imagine supporting this for numerous rules and fields... seriously, don't.
        – Eugene
        Dec 5 at 13:40










      • @Eugene that's what validation is about - check each model and each field. Of course that validation can be delegated to a framework, such as using Bean Validation (JSR-380) which drives field validations over annotations.
        – Peter Walser
        Dec 5 at 13:47










      • would you write this code or use a framework? that was my point
        – Eugene
        Dec 5 at 13:48










      • I would certainly use a framework, in particular Bean Validation (JSR-380, beanvalidation.org/specification)
        – Peter Walser
        Dec 5 at 14:07














      up vote
      1
      down vote













      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();





      share|improve this answer






















      • now imagine supporting this for numerous rules and fields... seriously, don't.
        – Eugene
        Dec 5 at 13:40










      • @Eugene that's what validation is about - check each model and each field. Of course that validation can be delegated to a framework, such as using Bean Validation (JSR-380) which drives field validations over annotations.
        – Peter Walser
        Dec 5 at 13:47










      • would you write this code or use a framework? that was my point
        – Eugene
        Dec 5 at 13:48










      • I would certainly use a framework, in particular Bean Validation (JSR-380, beanvalidation.org/specification)
        – Peter Walser
        Dec 5 at 14:07












      up vote
      1
      down vote










      up vote
      1
      down vote









      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();





      share|improve this answer














      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();






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Dec 5 at 13:43

























      answered Dec 5 at 13:29









      Peter Walser

      10.3k23455




      10.3k23455











      • now imagine supporting this for numerous rules and fields... seriously, don't.
        – Eugene
        Dec 5 at 13:40










      • @Eugene that's what validation is about - check each model and each field. Of course that validation can be delegated to a framework, such as using Bean Validation (JSR-380) which drives field validations over annotations.
        – Peter Walser
        Dec 5 at 13:47










      • would you write this code or use a framework? that was my point
        – Eugene
        Dec 5 at 13:48










      • I would certainly use a framework, in particular Bean Validation (JSR-380, beanvalidation.org/specification)
        – Peter Walser
        Dec 5 at 14:07
















      • now imagine supporting this for numerous rules and fields... seriously, don't.
        – Eugene
        Dec 5 at 13:40










      • @Eugene that's what validation is about - check each model and each field. Of course that validation can be delegated to a framework, such as using Bean Validation (JSR-380) which drives field validations over annotations.
        – Peter Walser
        Dec 5 at 13:47










      • would you write this code or use a framework? that was my point
        – Eugene
        Dec 5 at 13:48










      • I would certainly use a framework, in particular Bean Validation (JSR-380, beanvalidation.org/specification)
        – Peter Walser
        Dec 5 at 14:07















      now imagine supporting this for numerous rules and fields... seriously, don't.
      – Eugene
      Dec 5 at 13:40




      now imagine supporting this for numerous rules and fields... seriously, don't.
      – Eugene
      Dec 5 at 13:40












      @Eugene that's what validation is about - check each model and each field. Of course that validation can be delegated to a framework, such as using Bean Validation (JSR-380) which drives field validations over annotations.
      – Peter Walser
      Dec 5 at 13:47




      @Eugene that's what validation is about - check each model and each field. Of course that validation can be delegated to a framework, such as using Bean Validation (JSR-380) which drives field validations over annotations.
      – Peter Walser
      Dec 5 at 13:47












      would you write this code or use a framework? that was my point
      – Eugene
      Dec 5 at 13:48




      would you write this code or use a framework? that was my point
      – Eugene
      Dec 5 at 13:48












      I would certainly use a framework, in particular Bean Validation (JSR-380, beanvalidation.org/specification)
      – Peter Walser
      Dec 5 at 14:07




      I would certainly use a framework, in particular Bean Validation (JSR-380, beanvalidation.org/specification)
      – Peter Walser
      Dec 5 at 14:07










      up vote
      0
      down vote













      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.






      share|improve this answer
























        up vote
        0
        down vote













        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.






        share|improve this answer






















          up vote
          0
          down vote










          up vote
          0
          down vote









          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.






          share|improve this answer












          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.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Dec 5 at 13:20









          benignfoppery

          394




          394




















              up vote
              0
              down vote













              If their validation seems to be the same, only the type change, then use interface have Object1, Object2 and Object3 implements ICommon:



              interface ICommon 
              String getField1();
              int getField2();
              Iterable<? extends ICommon> getChildren();



              Then have this:



              private void validate0(String prefix, ICommon common) 
              if (common.getField1() == null) throw new ValidationException(prefix + ".field1 can't be null");
              if (common.getField2() == null) throw new ValidationException(prefix + ".field2 can't be null");
              int index = 0;
              for (ICommon child : getChildren())
              validate0(prefix + ".children[" + index + "]", child);
              ++index;



              public void validate(ICommon common)
              validate0("common", common);



              You may also invert this using a BiConsumer<String, ICommon> (or Consumer<ICommon>) to validate if you don't care about proper error reporting).



              • This will also make it clearer about which validation may apply on your object

              • Using stream does not (always) make it clearer (see Peter Walser answer and try to understand the big stream :)).





              share|improve this answer
























                up vote
                0
                down vote













                If their validation seems to be the same, only the type change, then use interface have Object1, Object2 and Object3 implements ICommon:



                interface ICommon 
                String getField1();
                int getField2();
                Iterable<? extends ICommon> getChildren();



                Then have this:



                private void validate0(String prefix, ICommon common) 
                if (common.getField1() == null) throw new ValidationException(prefix + ".field1 can't be null");
                if (common.getField2() == null) throw new ValidationException(prefix + ".field2 can't be null");
                int index = 0;
                for (ICommon child : getChildren())
                validate0(prefix + ".children[" + index + "]", child);
                ++index;



                public void validate(ICommon common)
                validate0("common", common);



                You may also invert this using a BiConsumer<String, ICommon> (or Consumer<ICommon>) to validate if you don't care about proper error reporting).



                • This will also make it clearer about which validation may apply on your object

                • Using stream does not (always) make it clearer (see Peter Walser answer and try to understand the big stream :)).





                share|improve this answer






















                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  If their validation seems to be the same, only the type change, then use interface have Object1, Object2 and Object3 implements ICommon:



                  interface ICommon 
                  String getField1();
                  int getField2();
                  Iterable<? extends ICommon> getChildren();



                  Then have this:



                  private void validate0(String prefix, ICommon common) 
                  if (common.getField1() == null) throw new ValidationException(prefix + ".field1 can't be null");
                  if (common.getField2() == null) throw new ValidationException(prefix + ".field2 can't be null");
                  int index = 0;
                  for (ICommon child : getChildren())
                  validate0(prefix + ".children[" + index + "]", child);
                  ++index;



                  public void validate(ICommon common)
                  validate0("common", common);



                  You may also invert this using a BiConsumer<String, ICommon> (or Consumer<ICommon>) to validate if you don't care about proper error reporting).



                  • This will also make it clearer about which validation may apply on your object

                  • Using stream does not (always) make it clearer (see Peter Walser answer and try to understand the big stream :)).





                  share|improve this answer












                  If their validation seems to be the same, only the type change, then use interface have Object1, Object2 and Object3 implements ICommon:



                  interface ICommon 
                  String getField1();
                  int getField2();
                  Iterable<? extends ICommon> getChildren();



                  Then have this:



                  private void validate0(String prefix, ICommon common) 
                  if (common.getField1() == null) throw new ValidationException(prefix + ".field1 can't be null");
                  if (common.getField2() == null) throw new ValidationException(prefix + ".field2 can't be null");
                  int index = 0;
                  for (ICommon child : getChildren())
                  validate0(prefix + ".children[" + index + "]", child);
                  ++index;



                  public void validate(ICommon common)
                  validate0("common", common);



                  You may also invert this using a BiConsumer<String, ICommon> (or Consumer<ICommon>) to validate if you don't care about proper error reporting).



                  • This will also make it clearer about which validation may apply on your object

                  • Using stream does not (always) make it clearer (see Peter Walser answer and try to understand the big stream :)).






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Dec 5 at 14:08









                  NoDataFound

                  5,5621740




                  5,5621740



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53632516%2fjava-8-alternative-for-validating-data-inside-multiple-nested-loops%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown






                      Popular posts from this blog

                      How to check contact read email or not when send email to Individual?

                      Displaying single band from multi-band raster using QGIS

                      How many registers does an x86_64 CPU actually have?