</>

Technology

Java Programs

Difficulty

Advanced

Interview Question

Write a Java program to demonstrate varargs, method references, and the Builder pattern for test data.

Answer

Varargs, Method References, and Builder Pattern

Varargs (Variable Arguments)

Java
public class VarargsDemo {

    // sum accepts any number of ints
    public static int sum(int... numbers) {
        int total = 0;
        for (int n : numbers) total += n;
        return total;
    }

    // Can mix regular params with varargs — varargs must be LAST
    public static void printAll(String prefix, String... values) {
        for (String v : values) {
            System.out.println(prefix + v);
        }
    }

    public static void main(String[] args) {
        System.out.println(sum());           // 0
        System.out.println(sum(1, 2));       // 3
        System.out.println(sum(1, 2, 3, 4, 5)); // 15

        printAll("Tool: ", "Selenium", "TestNG", "Cucumber");
    }
}

Output

CODE
0
3
15
Tool: Selenium
Tool: TestNG
Tool: Cucumber

Method References (::)

Java
import java.util.*;
import java.util.stream.*;
import java.util.function.*;

public class MethodReferencesDemo {
    public static void main(String[] args) {
        List<String> tools = Arrays.asList("selenium", "testng", "cucumber", "maven");

        // 1. Static Method Reference: ClassName::staticMethod
        //    equivalent to: t -> Integer.parseInt(t)
        List<String> nums = Arrays.asList("1", "2", "3");
        nums.stream().map(Integer::parseInt).forEach(System.out::println);

        // 2. Instance Method Reference on type: ClassName::instanceMethod
        //    equivalent to: t -> t.toUpperCase()
        tools.stream()
             .map(String::toUpperCase)
             .forEach(System.out::println);

        // 3. Instance Method Reference on object: object::instanceMethod
        //    equivalent to: t -> System.out.println(t)
        tools.forEach(System.out::println);

        // 4. Constructor Reference: ClassName::new
        //    equivalent to: s -> new StringBuilder(s)
        List<StringBuilder> sbs = tools.stream()
            .map(StringBuilder::new)
            .collect(Collectors.toList());

        // Common functional interface → method reference
        Predicate<String>  isEmpty   = String::isEmpty;         // t -> t.isEmpty()
        Function<String,Integer> len = String::length;          // t -> t.length()
        Consumer<Object>  printer    = System.out::println;     // t -> sysout(t)
        Supplier<List<String>> newList = ArrayList::new;        // () -> new ArrayList<>()

        System.out.println(isEmpty.test(""));      // true
        System.out.println(len.apply("Selenium")); // 8
    }
}

Builder Pattern for Test Data

Java
// Without Builder — hard to read, easy to pass args in wrong order
User user1 = new User("John", "john@test.com", "Admin", true, 25, "New York");

// With Builder — readable, flexible, no parameter order confusion
public class User {
    private String name;
    private String email;
    private String role;
    private boolean active;
    private int age;
    private String city;

    // Private constructor — only Builder can create User
    private User(Builder builder) {
        this.name   = builder.name;
        this.email  = builder.email;
        this.role   = builder.role;
        this.active = builder.active;
        this.age    = builder.age;
        this.city   = builder.city;
    }

    @Override
    public String toString() {
        return "User{name='" + name + "', email='" + email +
               "', role='" + role + "', active=" + active +
               ", age=" + age + ", city='" + city + "'}";
    }

    // Static inner Builder class
    public static class Builder {
        private String  name;
        private String  email;
        private String  role   = "User";     // default value
        private boolean active = true;       // default value
        private int     age;
        private String  city   = "Unknown";  // default value

        public Builder name(String name)     { this.name = name;     return this; }
        public Builder email(String email)   { this.email = email;   return this; }
        public Builder role(String role)     { this.role = role;     return this; }
        public Builder active(boolean active){ this.active = active; return this; }
        public Builder age(int age)          { this.age = age;       return this; }
        public Builder city(String city)     { this.city = city;     return this; }

        public User build() {
            // Validate required fields
            if (name == null || email == null)
                throw new IllegalStateException("Name and email are required");
            return new User(this);
        }
    }

    public static void main(String[] args) {
        // Build full user
        User admin = new User.Builder()
            .name("Alice")
            .email("alice@test.com")
            .role("Admin")
            .active(true)
            .age(30)
            .city("New York")
            .build();

        // Build minimal user (uses defaults)
        User guest = new User.Builder()
            .name("Guest")
            .email("guest@test.com")
            .build();  // role=User, active=true, city=Unknown

        System.out.println(admin);
        System.out.println(guest);
    }
}

Output

CODE
User{name='Alice', email='alice@test.com', role='Admin', active=true, age=30, city='New York'}
User{name='Guest', email='guest@test.com', role='User', active=true, age=0, city='Unknown'}

Builder in Automation Testing

Java
// Create test data cleanly for different test scenarios
User loginUser       = new User.Builder().name("John").email("john@qa.com").role("User").build();
User adminUser       = new User.Builder().name("Admin").email("admin@qa.com").role("Admin").build();
User inactiveUser    = new User.Builder().name("Bob").email("bob@qa.com").active(false).build();

// Lombok @Builder annotation (production-grade shortcut)
// @Builder on class generates builder automatically — no manual code needed

Method Reference vs Lambda

LambdaMethod Reference
Syntaxt -> t.toUpperCase()String::toUpperCase
ReadabilityOKBetter (when method name is descriptive)
Use whenLogic in lambdaCalls single existing method
PerformanceSameSame

Follow AutomateQA