Practical Applications
Real-World Scenarios for Method References
graph TD
A[Method References] --> B[Sorting]
A --> C[Filtering]
A --> D[Transformation]
A --> E[Collection Processing]
1. Sorting Collections
Sorting with Method References
public class SortingDemo {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// Traditional comparator
Collections.sort(names, (a, b) -> a.compareTo(b));
// Using method reference
Collections.sort(names, String::compareTo);
// Sorting objects by specific attribute
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25)
);
// Sorting by age using method reference
people.sort(Comparator.comparing(Person::getAge));
}
}
class Person {
private String name;
private int age;
// Constructor, getters, setters
public int getAge() {
return age;
}
}
2. Stream Processing
Filtering and Mapping
public class StreamProcessingDemo {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// Filtering with method reference
List<String> longNames = names.stream()
.filter(name -> name.length() > 4)
.collect(Collectors.toList());
// Mapping with method reference
List<Integer> nameLengths = names.stream()
.map(String::length)
.collect(Collectors.toList());
}
}
3. Custom Functional Interfaces
Creating Flexible Callbacks
public class FunctionalInterfaceDemo {
// Custom functional interface
@FunctionalInterface
interface Transformer<T> {
T transform(T input);
}
public static void processData(List<String> data,
Transformer<String> transformer) {
List<String> processedData = data.stream()
.map(transformer::transform)
.collect(Collectors.toList());
}
public static void main(String[] args) {
List<String> names = Arrays.asList("alice", "bob", "charlie");
// Using method reference as transformer
processData(names, String::toUpperCase);
}
}
4. Event Handling in GUI
Listener Methods
public class EventHandlingDemo {
public static void main(String[] args) {
JButton button = new JButton("Click Me");
// Traditional anonymous inner class
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked!");
}
});
// Method reference for event handling
button.addActionListener(this::handleButtonClick);
}
private void handleButtonClick(ActionEvent event) {
System.out.println("Button clicked with method reference!");
}
}
Practical Application Scenarios
Scenario |
Method Reference Type |
Use Case |
Sorting |
Comparator |
Ordering collections |
Stream Processing |
Mapping/Filtering |
Data transformation |
Event Handling |
Instance Method |
Callback mechanisms |
Dependency Injection |
Constructor |
Creating object instances |
- Method references are generally more performant than lambda expressions
- Minimal overhead compared to direct method calls
- Compiler can optimize method reference implementations
Best Practices
- Use method references for simple, single-method operations
- Maintain code readability
- Choose appropriate method reference type
Learn advanced method reference techniques with LabEx to enhance your Java functional programming skills.