Поиск по сайту:

Как преобразовать набор в список в Java


Списки в Java — это упорядоченный набор данных, а наборы — неупорядоченный набор данных. В списке могут быть повторяющиеся записи, а в наборе - нет. Обе структуры данных полезны в разных сценариях.

Полезно знать, как преобразовать набор в список. Он может преобразовывать неупорядоченные данные в упорядоченные данные.

Инициализация набора

Давайте инициализируем набор и добавим в него несколько элементов.

import java.util.*;

public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);
        System.out.println(a);
    }
}

Метод add() класса HashSet добавляет элементы в набор. Обратите внимание, что элементы различны. Невозможно получить элементы в соответствии с порядком их вставки, поскольку наборы неупорядочены.

Преобразование набора в список в Java

Преобразуем множество в список. Есть несколько способов сделать это. Каждый способ отличается от другого, и эти различия неуловимы.

1. Конструктор списка с аргументом Set

Самый простой способ преобразовать набор в список — передать набор в качестве аргумента при создании списка. Это вызывает конструктор, и с этого момента конструктор позаботится обо всем остальном.

import java.util.*;

public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);

     List<Integer> arr = new ArrayList<>(a);
     System.out.println(arr);
     System.out.println(arr.get(1));

    }
}

Поскольку набор был преобразован в список, элементы теперь упорядочены. Это означает, что мы можем использовать метод get() для доступа к элементам по индексу.

2. Использование обычного цикла for

Мы можем использовать старый добрый цикл for, чтобы явно скопировать элементы из набора в список.

import java.util.*;

public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);

     List<Integer> arr = new ArrayList<>(a);
        for (int i : a)
            arr.add(i);
        System.out.println(arr);
        System.out.println(arr.get(1));
    }   
}

Цикл for перебирает заданный элемент за элементом и добавляет элементы в список.

3. Список методов addAll()

У списков есть метод addAll(), который одновременно добавляет в список несколько значений. Вы можете вспомнить эту операцию по ее использованию при слиянии двух списков. addAll() также работает для добавления элементов набора в список.

import java.util.*;

public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);

     List<Integer> arr = new ArrayList<>();
        arr.addAll(a);
        System.out.println(arr);
        System.out.println(arr.get(1));
    }
}

4. Метод collect() потокового API

Stream.collect() доступен начиная с Java 8. Сборщик ToList собирает все элементы Stream в экземпляр List.

import java.util.*;
import java.util.stream.Collectors;


public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);

     List<Integer> arr;

        arr = a.stream().collect(Collectors.toList());
        System.out.println(arr);
        System.out.println(arr.get(1));
    }
}

В документации для stream.collect() упоминается, что нет никаких гарантий относительно типа, изменчивости, сериализуемости или потокобезопасности возвращаемого списка. Если требуется больший контроль над возвращаемым списком, используйте toCollection(Supplier).

Чтобы указать тип списка, используйте toCollection(ArrayList::new)

import java.util.*;
import java.util.stream.Collectors;


public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);

     List<Integer> arr;

  arr = a.stream().collect(Collectors.toCollection(ArrayList::new));
        System.out.println(arr);
        System.out.println(arr.get(1));
    }
}

Рекомендуемая литература: потоки в Java

5. Метод List.copyOf()

В Java 10 и выше List есть метод copyOf(). Метод возвращает неизменяемый список, содержащий элементы данной коллекции, в порядке итерации. Список не может содержать пустых элементов. Если набор содержит null, метод возвращает исключение нулевого указателя.

import java.util.*;
import java.util.stream.Collectors;


public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);

     List<Integer> arr;

        arr = List.copyOf(a);
        System.out.println(arr);
        System.out.println(arr.get(1));
    }
}

Добавление нуля в набор и попытка преобразования в список:

import java.util.*;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);
        a.add(null);

     List<Integer> arr;

        arr = List.copyOf(a);
        System.out.println(arr);
        System.out.println(arr.get(1));
    }
}

Если вы попытаетесь добавить элемент в неизменяемый список, вы получите сообщение об ошибке, похожее на следующее.

Использование метода addAll() для преобразования набора с нулевым элементом в список:

import java.util.*;
import java.util.stream.Collectors;


public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);
        a.add(null);

     List<Integer> arr = new ArrayList<>();
     arr.addAll(a);

      //  arr = List.copyOf(a);
        System.out.println(arr);
        System.out.println(arr.get(1));
    }
}

Обратите внимание, что нуль появляется в начале списка.

Заключение

Мы увидели несколько действительно интересных методов преобразования набора в список. Важно обратить внимание на тип списка, который создается каждым методом. Метод Like copyOf() создает неизменяемый список и не может обрабатывать нулевые элементы. Принимая во внимание, что stream.collect() ничего не гарантирует. Конструктор и addAll() являются наиболее надежными среди пакетов.