Есть ли способ оптимизации кода ниже, используя java8? - PullRequest
0 голосов
/ 31 августа 2018

Я столкнулся с кодом ниже в моем проекте. Мне было интересно, можно ли оптимизировать его дальше, используя потоки Java 8 или API-интерфейсы сбора в целом.

private Set<Student> getFilteredSet() {
    Set<Student> unfilteredSet = getAllStudents();
    Set<Student> adminAreaSet = getAdminStudents();

    Set<String> adminAreaID = new HashSet<>();
    Set<Student> filteredSet = new HashSet<>();

    for (final Student student : adminAreaSet) {
        adminAreaID.add(student.getId());
    }
    for (final Student student : unfilteredSet) {
        if (adminAreaID.contains(student.getId())) {
            filteredSet.add(student);
        }
    }   
    return filteredSet;
}

Примечание: unfilteredSet и adminAreaSet содержат различные дочерние типы Student

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

Согласно вашему комментарию, вы ищете оптимизацию скорости. В Интернете много публикаций, сравнивающих Stream и Collection и даже больше. Я рекомендую вам в качестве примера взглянуть на этот вопрос, который сравнивает быстродействие потоков и старого для каждого цикла: Java 8: производительность потоков против коллекций . Поскольку использование Stream создает много промежуточных объектов и вызывает промежуточные методы, кажется нормальным быть медленнее, чем базовый для каждого цикла. Однако вы можете использовать поток, чтобы иметь более читаемый / меньший код.

Чтобы ответить на вопрос, я думаю, ваш код уже очень хорош, учитывая быстродействие. Все, что я вижу, это то, что вы должны инициализировать adminAreaID, потому что вы точно знаете его размер:

    Set<String> adminAreaID = new HashSet<>(adminAreaSet.size(), 1.);

Установив размер и коэффициент загрузки, вы гарантируете, что не будете тратить время на выращивание вашего устройства. Согласно https://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html:

Коэффициент загрузки является мерой того, насколько полна хеш-таблица получить до того, как его емкость будет автоматически увеличена.

Вы должны установить его на 1. потому что вы не увеличите размер adminAreaSet. Более того, если вы укажете значение 0,75 (значение по умолчанию), ваш набор увеличится один раз, когда цикл достигнет 75% своей емкости, что бесполезно.

Если у вас нет проблем с памятью, вы должны сделать то же самое с помощью FilterSet:

    Set<Student> filteredSet = new HashSet<>(unfilteredSet.size(), 1.);

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

0 голосов
/ 31 августа 2018

Поскольку вопрос помечен , одним из способов улучшить читабельность кода может быть преобразование его в:

Set<String> adminAreaID = getAdminStudents().stream()
        .map(Student::getId)
        .collect(Collectors.toSet());

return getAllStudents().stream()
        .filter(student -> adminAreaID.contains(student.getId()))
        .collect(Collectors.toSet());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...