Как переписать код со стримами для Java 7?

Рейтинг: 1Ответов: 2Опубликовано: 14.02.2025

Этот код был создан для Java 8+, а вот Java 7 его не понимает и не компилирует, пишет что не понятно .stream().filter()

Вопрос, что нужно изменить в данном коде, чтобы он мог быть скомпилирован на Java 7?

public void run()
{               
    adjustPotentialIndexOutOfBounds();
    List<FakePlayer> fakePlayers = FakePlayerManager.INSTANCE.getFakePlayers().subList(_from, _to);     
    try {
        fakePlayers.stream().filter(x-> !x.getFakeAi().isBusyThinking()).forEach(x-> x.getFakeAi().thinkAndAct());  
    } catch(Exception ex) {
        ex.printStackTrace();
    }
}

Второй фрагмент:

if (player.getTarget() == null) {
    List<Creature> targets = player.getKnownTypeInRadius(creatureClass, radius).stream()
                    .filter(x->!x.isDead())                 
                    .collect(Collectors.toList());
            
    if (!player.isDead())
        targets.add(player);        
            
    List<Creature> sortedTargets = targets.stream().sorted((x1, x2) -> Double.compare(x1.getCurrentHp(), x2.getCurrentHp())).collect(Collectors.toList());
            
    if (!sortedTargets.isEmpty()) {
        Creature target = sortedTargets.get(0);
        player.setTarget(target);               
    }
// ....
}

Ответы

▲ 3

Проще всего было бы компилировать представленный код той версией компилятора, для которой он написан, то есть, для Java 8, вышедшей весной 2014 года, или выше.

Однако, если есть какая-то существенная причина, что доступна только Java 7, то этот код достаточно просто переписать в "старом" (или классическом) стиле, когда методам в Stream API соответствуют следующие "классические" операторы, подходящие для данного случая:

  • цикл for-each вместо stream().forEach()
  • условный оператор if вместо filter()

Тогда преобразованный код первого фрагмента будет выглядеть так:

public void run() {               
    adjustPotentialIndexOutOfBounds();
    List<FakePlayer> fakePlayers = FakePlayerManager.INSTANCE.getFakePlayers().subList(_from, _to);
    try {
        for (FakePlayer x : fakePlayers) {          // stream()
            if (!x.getFakeAi().isBusyThinking()) {  // filter(x -> Predicate)
                x.getFakeAi().thinkAndAct();        // forEach(x -> Consumer)
            }
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }    
}   

Во втором фрагменте кода нужно получить отфильтрованный список targets и выполнить его сортировку, например при помощи метода JDK 7: Collections.sort.

При этом придётся создать реализацию интерфейса Comparator в виде анонимного класса и перенести в метод compare(Creature x1, Creature x2) содержимое лямбда-функции из метода .sorted в начальном коде:

if (player.getTarget() == null) {
    List<Creature> source = player.getKnownTypeInRadius(creatureClass, radius);
    List<Creature> targets = new ArrayList<>(source.size());

    for (Creature x : source) {          // stream
        if (!x.isDead()) targets.add(x); // filter/collect
    }

    if (!player.isDead())
        targets.add(player);

    // избежим создания отдельного сортированного списка
    if (!targets.isEmpty()) {
        Collections.sort(targets, new Comparator<Creature>() {
            @Override
            public int compare(Creature x1, Creature x2) {
                return Double.compare(x1.getCurrentHp(), x2.getCurrentHp());
            }
        });

        Creature target = targets.get(0);
        player.setTarget(target);               
    }
// ....
}
▲ 1

Правильный ответ:

Не пользоваться настолько старыми версиями Java.Тем более, что это код какой-то игрушки и единственной причиной использовать Java 7 в 2025 может быть только требование преподавателя.

Но если всё-таки убрать Stream API нужно, то:

  • Открываем проект в IntelliJ IDEA. Бесплатной Community Edition хватит за глаза.
  • Ставим курсор на вызов .stream() и жмём Alt-Enter
  • В появившемся меню выбираем пункт Replace Stream API ... и жмём Enter

IDEA всё сделает сама. Проверяем результат и идём учить Stream API т.к. в реальных проектах оно будет встречаться на каждом шагу.

Для кода в вопросе IDEA сгенерирует такой результат:

    public void run() {
        adjustPotentialIndexOutOfBounds();
        List<FakePlayer> fakePlayers = FakePlayerManager.INSTANCE.getFakePlayers().subList(_from, _to);
        try {
            for (FakePlayer x : fakePlayers) {
                if (!x.getFakeAi().isBusyThinking()) {
                    x.getFakeAi().thinkAndAct();
                }
            }
        } catch(Exception ex) {
            ex.printStackTrace();
        }
    }
        if (player.getTarget() == null) {
            List<Creature> targets = new ArrayList<>();
            for (Creature x : player.getKnownTypeInRadius(creatureClass, radius)) {
                if (!x.isDead()) {
                    targets.add(x);
                }
            }

            if (!player.isDead())
                targets.add(player);

            List<Creature> sortedTargets = new ArrayList<>(targets);
            sortedTargets.sort(new Comparator<Creature>() {
                @Override
                public int compare(Creature x1, Creature x2) {
                    return Double.compare(x1.getCurrentHp(), x2.getCurrentHp());
                }
            });

            if (!sortedTargets.isEmpty()) {
                Creature target = sortedTargets.get(0);
                player.setTarget(target);
            }
// ....
        }

Как видите, результат довольно близок к ответу @nowhere-man