Вы не работаете? Цикл for double-layer может быть заменен методом потока.

задняя часть
Вы не работаете? Цикл for double-layer может быть заменен методом потока.

Эта статья приняла участие в мероприятии «Церемония создания новичков» и вместе начала путь создания Nuggets.

Привет всем, меня зовут Тонг Янь Уцзи. В настоящее время я осадный лев, который поступает неправильно. Я верю в то, что «практика приносит истинные знания, жизнь проще», и жажду свободы.签名.PNG

шлаковый код

Java8 отсутствуетStreamМетод потоковой обработки, но в реальном развитии бизнеса большинство студентов все еще подсознательно пишут для двухслойного цикла.

陈旧代码

Процветание с первого взгляда. . . Этот код написан в типичном двухуровневом цикле, давайте посмотрим на бизнес-логику, чтобы судить.List<T>Во всех элементах объекта нет повторений. Если существует повторяющийся первичный ключ объекта, создается бизнес-исключение.

На самом деле, бизнес-сценарий не сложен, вы можете использоватьStreamМетод потоковой обработки, тогда почему вы все еще используете двухслойный цикл for? Это привычка или соображения производительности?

Проведите тест, чтобы убедиться в этом. . .

Полигон

Сначала смоделируйте сценарий:Учащиеся в классе, соответствие учеников и классов, проверка того, действительно ли у учеников есть занятия.

  1. Сначала смоделируйте студенческий класс и класс класса

    学生班级

  2. Количество учеников и классов 10W+ не подозревается в работоспособности? Число слишком маленькое

    学生数量

  3. Сделайте двухслойную петлю for

    // for双层循环的方式
    private static void doubleForMethod(List<Student> studentList, List<NoClass> noClassList) {
        // 现在用学生与班级进行匹配,如果是班级号一致,认为这个学生是本班级的
        for (int i = 0; i < studentList.size(); i++) {
            Student student = studentList.get(i);
            for (int j = 0; j < noClassList.size(); j++) {
                NoClass noClass = noClassList.get(j);
                if (student.getClassesId().equals(noClass.getClassId())) {
                    // System.out.println("该学生:" + student.getStuId() + "是有班级的");
                }
            }
        }
    }
    
  4. Давайте сделаем еще один поток

    private static void streamMethod(List<Student> studentList, List<NoClass> noClassList) {
        // 把班级列表转成map,那么班级id就是唯一的id
        Map<String, NoClass> noClassMap = noClassList.stream().collect(Collectors.toMap(t -> t.getClassId(), t -> t));
        // 现在用学生与班级进行匹配,如果是班级号一致,认为这个学生是本班级的
        studentList.stream().forEach(h -> {
            if (noClassMap.containsKey(h.getClassesId())) {
                // System.out.println("该学生:" + h.getStuId() + "是有班级的");
            }
        });
    }
    
  5. Запустите и сравните трудоемкую ситуацию двух

    耗时代码

    Конечный результат:

    Время работы в режиме двухслойной петли: 80438 мс

    Время потоковой передачи: 80 мс

С бизнес-сценарием оба имеют один и тот же результат, но это отнимает много времени, облако грязи, удивительно.

Что Stream делает за кулисами?

На самом деле, я не очень ясен, давайте учимся вместе.

知识忙去.PNG

Если вы понимаете, как реализован Stream нижнего уровня, как только вы подходите, это полностью против вас; когда вы изучаете «Программирование на языке C», вы узналиfor(int i=0;i<n;i++)Как он завершил обход!

Ответ определенно нет. Чтобы освоить какое-то знание, идите от простого к глубокому, узнайте его характеристики, а затем исследуйте причины.Если вам нужно смотреть исходный код Stream, как только вы подходите, это нормально. Я с нетерпением жду возможности увидеть, как ты тихо выступаешь.看你表演

Классификация потоков

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

操作分类

Официально операции в Stream делятся на две категории: промежуточные операции и терминальные операции. Промежуточная операция только записывает операцию, то есть возвращается только поток, и никакая операция вычисления не выполняется, в то время как конечная операция реализует операцию вычисления.

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

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

Мы обычно также называем промежуточные операции ленивыми операциями, и именно конвейер обработки (конвейер), состоящий из этой ленивой операции в сочетании с конечными операциями и источниками данных, реализует эффективность Stream.

Особенности потока

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

  2. Для обработки коллекции обычно используется метод обхода обходчика Iterator, который представляет собой внешнюю итерацию;

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

Потоковая производительность

Может ли Stream полностью заменить метод for и иметь более высокую производительность? Не обязательно.

Согласно официальным данным эффективности:

  1. Сравнение производительности массива int длиной 100 в конфигурации сервера с многоядерным процессором

    Обычная итерация

  2. В среде конфигурации сервера с многоядерным процессором сравните производительность массива int длиной 1,00E+8;

    Поток параллельно итерации

  3. Многоядерная среда сервера конфигурации CPU, 1.00E + 8 Сравнительный массив объектов Длина пакета объектов производительности фильтра;

    Параллельная итерация потока

  4. В среде конфигурации сервера с одноядерным процессором сравните производительность фильтрующих группировок с длиной массива объектов 1,00E+8;

    Обычная итерация

Рекомендуется больше использовать Stream.

Официальная статистика производительности, например, не может обеспечить более высокую производительность Stream, в частности объем данных, которые должны быть зависимы, то есть фактический сценарий приложения.

Однако в нашем обычном развитии бизнеса я рекомендую использовать метод потока. Эффективность является фактором, который следует учитывать при написании кода, но это не абсолютный фактор. С разработкой технологий эффективность исполнения определенно будет быстро увеличиваться с развитием аппаратного обеспечения; для людей, которые пишет код,Код должен быть кратким, Потеряв немного эффективности, в обмен на хорошо читаемый код, я думаю, это очень выгодно.