Understanding Collections.sort Java 8 Void Cannot Be Converted

In Java programming, sorting collections is a common operation. The Collections.sort method is a well - known utility for sorting lists. However, in Java 8 and later, developers sometimes encounter the error void cannot be converted. This error message can be confusing, especially for those new to Java or those who are not fully aware of the Collections.sort method’s behavior. This blog post aims to explain the core concepts, typical usage scenarios, common pitfalls, and best practices related to this error.

Table of Contents

  1. Core Concepts
  2. Typical Usage Scenarios
  3. Common Pitfalls
  4. Code Examples
  5. Best Practices
  6. Conclusion
  7. FAQ
  8. References

Core Concepts

Collections.sort Method

The Collections.sort method is a static method in the java.util.Collections class. It is used to sort a list in ascending order according to the natural ordering of its elements or according to a specified comparator. The method signature is as follows:

// Sorts the specified list according to the natural ordering of its elements.
public static <T extends Comparable<? super T>> void sort(List<T> list)

// Sorts the specified list according to the order induced by the specified comparator.
public static <T> void sort(List<T> list, Comparator<? super T> c)

The important thing to note is that both versions of the sort method have a return type of void. This means that the method sorts the list in - place and does not return a new sorted list.

“Void Cannot Be Converted” Error

When you try to assign the result of the Collections.sort method to a variable, you will get the “void cannot be converted” error. Since the method returns void, there is no value to assign to a variable, and Java does not allow such an assignment.

Typical Usage Scenarios

Sorting a List of Strings

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class StringSortingExample {
    public static void main(String[] args) {
        List<String> stringList = new ArrayList<>();
        stringList.add("banana");
        stringList.add("apple");
        stringList.add("cherry");

        // Sort the list
        Collections.sort(stringList);

        // Print the sorted list
        for (String fruit : stringList) {
            System.out.println(fruit);
        }
    }
}

In this example, we have a list of strings representing fruits. We use Collections.sort to sort the list in alphabetical order.

Sorting a List of Custom Objects

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

public class CustomObjectSortingExample {
    public static void main(String[] args) {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("Alice", 25));
        personList.add(new Person("Bob", 20));
        personList.add(new Person("Charlie", 30));

        // Sort the list by age using a comparator
        Collections.sort(personList, Comparator.comparingInt(Person::getAge));

        // Print the sorted list
        for (Person person : personList) {
            System.out.println(person);
        }
    }
}

Here, we have a list of Person objects. We use a comparator to sort the list based on the age of the persons.

Common Pitfalls

Assigning the Result of Collections.sort to a Variable

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class PitfallExample {
    public static void main(String[] args) {
        List<String> stringList = new ArrayList<>();
        stringList.add("banana");
        stringList.add("apple");
        stringList.add("cherry");

        // This will cause a "void cannot be converted" error
        // List<String> sortedList = Collections.sort(stringList);

        // Correct way: sort the list in - place
        Collections.sort(stringList);
    }
}

In the commented line, we try to assign the result of Collections.sort to a variable, which leads to the error.

Not Implementing Comparable for Custom Objects

If you try to sort a list of custom objects without implementing the Comparable interface or providing a comparator, you will get a ClassCastException.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class Employee {
    private String name;
    private int salary;

    public Employee(String name, int salary) {
        this.name = name;
        this.salary = salary;
    }
}

public class NoComparableExample {
    public static void main(String[] args) {
        List<Employee> employeeList = new ArrayList<>();
        employeeList.add(new Employee("Alice", 5000));
        employeeList.add(new Employee("Bob", 4000));

        // This will throw a ClassCastException
        // Collections.sort(employeeList);

        // Correct way: use a comparator
        Collections.sort(employeeList, (e1, e2) -> e1.getSalary() - e2.getSalary());
    }
}

In the commented line, we try to sort the list of Employee objects without a proper comparison mechanism.

Code Examples

Sorting a List of Integers

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class IntegerSortingExample {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(3);
        integerList.add(1);
        integerList.add(2);

        // Sort the list
        Collections.sort(integerList);

        // Print the sorted list
        for (Integer num : integerList) {
            System.out.println(num);
        }
    }
}

Sorting in Reverse Order

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ReverseSortingExample {
    public static void main(String[] args) {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(3);
        integerList.add(1);
        integerList.add(2);

        // Sort the list in reverse order
        Collections.sort(integerList, Comparator.reverseOrder());

        // Print the sorted list
        for (Integer num : integerList) {
            System.out.println(num);
        }
    }
}

Best Practices

Use the List After Sorting In - Place

Since Collections.sort sorts the list in - place, you can directly use the original list after sorting.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class BestPracticeExample {
    public static void main(String[] args) {
        List<String> stringList = new ArrayList<>();
        stringList.add("banana");
        stringList.add("apple");
        stringList.add("cherry");

        // Sort the list in - place
        Collections.sort(stringList);

        // Use the sorted list
        for (String fruit : stringList) {
            System.out.println(fruit);
        }
    }
}

Provide a Comparator for Custom Objects

When sorting a list of custom objects, it is a good practice to provide a comparator to define the sorting order.

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

class Book {
    private String title;
    private int year;

    public Book(String title, int year) {
        this.title = title;
        this.year = year;
    }

    public int getYear() {
        return year;
    }

    public String getTitle() {
        return title;
    }

    @Override
    public String toString() {
        return "Book{title='" + title + "', year=" + year + "}";
    }
}

public class CustomObjectBestPractice {
    public static void main(String[] args) {
        List<Book> bookList = new ArrayList<>();
        bookList.add(new Book("Java Programming", 2020));
        bookList.add(new Book("Python Basics", 2018));

        // Sort the list by year using a comparator
        Collections.sort(bookList, Comparator.comparingInt(Book::getYear));

        // Print the sorted list
        for (Book book : bookList) {
            System.out.println(book);
        }
    }
}

Conclusion

The “void cannot be converted” error when using Collections.sort in Java 8 is a common mistake that occurs when developers try to assign the result of the method to a variable. Understanding that Collections.sort sorts the list in - place and has a void return type is crucial. By following the best practices and avoiding common pitfalls, you can effectively use Collections.sort in your Java programs.

FAQ

Q: Can I get a new sorted list without modifying the original list using Collections.sort?

A: No, Collections.sort sorts the list in - place. If you want a new sorted list without modifying the original list, you can create a copy of the list and then sort the copy.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class NewSortedListExample {
    public static void main(String[] args) {
        List<String> originalList = new ArrayList<>();
        originalList.add("banana");
        originalList.add("apple");
        originalList.add("cherry");

        List<String> copyList = new ArrayList<>(originalList);
        Collections.sort(copyList);

        System.out.println("Original list: " + originalList);
        System.out.println("Sorted copy list: " + copyList);
    }
}

Q: What is the difference between Collections.sort and List.sort?

A: Collections.sort is a static method in the Collections class, while List.sort is an instance method introduced in Java 8. Both methods sort the list in - place, but List.sort allows you to use lambda expressions more easily when providing a comparator.

References