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

Этот код был создан для 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);               
    }
// ....
}

Ответы (2 шт):

Автор решения: Nowhere Man

Проще всего было бы компилировать представленный код той версией компилятора, для которой он написан, то есть, для 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);               
    }
// ....
}
→ Ссылка
Автор решения: user882813

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

Не пользоваться настолько старыми версиями 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

→ Ссылка