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
| Lambda | Method Reference | |
|---|---|---|
| Syntax | t -> t.toUpperCase() | String::toUpperCase |
| Readability | OK | Better (when method name is descriptive) |
| Use when | Logic in lambda | Calls single existing method |
| Performance | Same | Same |
