-2

I have a class called Human (accepts name(string) and height(int) in the constructor) and need too create a supplier of this class that will create an object but I want the object's name to let's say be between 5-10 characters, and the height should be between 110-250. Is it possible to do so in Java?

2 Answers2

0

here is one approach, rejecting invalid arguments

public class Human {

    private final String name;
    private final int height;

    public Human(String name, int height) {
        validateName(name);
        validateHeight(height);
        this.height = height;
        this.name = name;
    }

    private void validateName(String name) {
        if(name==null || name.length()<5 || name.length()>10)
            throw new IllegalArgumentException("Name should be between 5-10 chars long but  "+name);
    }

    private void validateHeight(int height) {
        if(height<110 || height>250) 
            throw new IllegalArgumentException("Height should be between 110-250 but "+height);
    }
}

Note that this is a RuntimeException, variations include throwing a checked exception instead and let the client code have a workaround. Or, perhaps have a static factory method and return a InvalidHuman object if not valid.

UPDATE

Ok, I think you want something like this

public class HumanProvider {

    private static final Random r = new Random();

    private static String vowels = "aeiou";
    private static String cons = "bcdfghjklmnpqrstvwxyz";

    private static String[] patterns = "cvc vc cv cvvc vcc".split(" ");

    private HumanProvider() {
    } // don't instantiate

    public static Human createRandom() {

        String name;
        do {
            name = getRandomString();
        } while (name.length() < 5 || name.length() > 10);

        int height = r.nextInt(251 - 110) + 110;

        return new Human(name, height);
    }


    private static String getRandomString() {
        int numSyllabels = r.nextInt(5) + 1;
        StringBuilder name = new StringBuilder();
        for (int i = 0; i < numSyllabels; i++) {
            String pattern = patterns[r.nextInt(patterns.length)];
            for (char c : pattern.toCharArray()) {
                name.append(randomChar((c == 'c') ? cons : vowels));
            }
        }
        return name.toString();
    }

    private static char randomChar(String list) {
        return list.charAt(r.nextInt(list.length()));
    }
}
karakfa
  • 66,216
  • 7
  • 41
  • 56
  • Let's say I have a similar Human class to yours but without validateName and validateHeight. I want sth like this: Supplier i = ()-> {return new Person()}; – cooktheprogrammer Nov 15 '17 at 20:57
  • You could always just put that logic in the constructor instead of in those methods, but why? – D M Nov 15 '17 at 20:59
  • That's because I want the Supplier class to generate Human objects with randomized attributes but within the constraints that were mentioned. – cooktheprogrammer Nov 15 '17 at 21:02
  • Then, you should constrain the random value generator instead. – karakfa Nov 15 '17 at 21:02
  • @karakfa Yeah, I just stumbled upon the Random() class so the height is quite easy. What about the string argument, is there some kind of regex generator in Java? – cooktheprogrammer Nov 15 '17 at 21:05
  • added a pattern driven primitive random String generator, you can fine tune the patterns and change char frequencies by adding extra instances of high frequency letters. – karakfa Nov 15 '17 at 21:34
-1

A constructor can't directly return null, but you could use something called a factory method. A factory method would look something like this:

public static Human createHuman(String name, int height)
{
    if (height < 110 || height > 250) 
        return null;
    if (name == null || name.length() < 5 || name.length() > 10)
        return null;
    else
        return new Human(name, height);
}

private Human (String name, int height)  // note that this is private
{
    this.name = name;
    this.height = height;
}

You could call it like this:

Human.createHuman("Steve", 117);

(Or in your case, perhaps like this:)

Supplier<Human> i = ()-> {return Human.createHuman(someName, someHeight)};
D M
  • 1,410
  • 1
  • 8
  • 12