Krushnat Khavale
Krushnat Khavale

Reputation: 426

Functional programming in java: Cloning Vs Mutating. Good or bad?

Mutating:

"transformEmployeeNameToUpperCase" function to transform employee name to uppercase.

List<Employee> employeesStartsWithDInUppercase1 = employees.stream()
            .filter(employee -> employee.getName().startsWith("D"))
            .map(Main::transformEmployeeNameToUpperCase)
            .collect(Collectors.toList());

public static Employee transformEmployeeNameToUpperCase(Employee employee){
    employee.setName(employee.getName().toUpperCase());
    return employee;
}

Cloning:

"createEmployeeWithUpperCaseName" function to new employee with name in uppercase.

List<Employee> employeesStartsWithDInUppercase2 = employees.stream()
            .filter(employee -> employee.getName().startsWith("D"))
            .map(Main::createEmployeeWithUpperCaseName)
            .collect(Collectors.toList());


public static Employee createEmployeeWithUpperCaseName(Employee e){
    return new Employee( e.getId(), e.getName().toUpperCase(), e.getDesignation(), e.getAge());
}

Upvotes: 0

Views: 468

Answers (2)

Sahil Verma
Sahil Verma

Reputation: 141

Agree with @JB Nizet, but still if you don't want to change the original object but want to change the name of employee to Uppercase. use object cloning.

pseudo code:

List<Employee> employeeWithUpperCaseName = employees.parallelStream()
                .filter(e -> e.getName().startsWith("D"))
                .map(x -> {
                    Employee s = null;
                    try {
                        s = (Employee) x.clone();
                        s.setName(x.getName().toUpperCase());
                    } catch (CloneNotSupportedException e) {
                        e.printStackTrace();
                    } finally {
                        return s;
                    }
                })
                .collect(Collectors.toList());

you can write it in better way.

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 692073

Does "createEmployeeWithUpperCaseName" follow rule 1(above) as they say

yes: the employee is not being modified

In case of "transformEmployeeNameToUpperCase", does it follow rule 2(above)?

yes, although the rule uses an incorrect terminology. It creates an object, not a variable. You can't create a variable.

Is it good practice to use transformEmployeeNameToUpperCase way?

No, at least not the way you're doing it. There's nothing bad per se in modifying mutable objects: they're mutable for a reason. But a map() operation shouldn't modify its input and return it. You're perverting its purpose. A future reader of your code wouldn't expect a map operation to mutate its input, and you're thus making your code do unexpected things, leading to bugs and/or misunderstandings. It would be better to do it this way:

employees.stream()
         .filter(employee -> employee.getName().startsWith("D"))
         .forEach(e -> e.setName(e.getName().toUpperCase()));

That way, it makes it clear that the point of the pipeline is to have a side effect on the elements of the list. And it doesn't create a (probably) useless copy of the list, too.

Upvotes: 4

Related Questions