Вопрос по лямбдам в Java, функции map, filter

477
16 августа 2018, 18:30

Пытаюсь переделать данные методы в stream, используя filter и map методы.

В учебнике предлагается переделать метод

printSightingsBy(int spotter)

в следующий:

    public void printSightingsBy(int spotter)
{
     sightings.stream()
      .filter(sighting -> sighting.getSpotter() == spotter)
      .map(sighting -> sighting.getDetails())
      .forEach (details -> System.out.println (details))
 }

Почему нельзя сделать так:

 public void printSightingsBy(int spotter)
    {
         sightings.stream()
          .filter(sighting -> sighting.getSpotter() == spotter)//получаем человека
          //получаем детали о животных, которые отслеживаются данным человеком
          .forEach (sighting -> System.out.println (sighting.getDetails()));
     }

Код класса следующий:

import java.util.ArrayList;
import java.util.Iterator;
/**
 * Monitor counts of different types of animal.
 * Sightings are recorded by spotters.
 * 
 * @author David J. Barnes and Michael Kölling
 * @version 2016.02.29 (imperative)
 */
public class AnimalMonitor 
{
    // Records of all the sightings of animals.
private ArrayList<Sighting> sightings;
/**
 * Create an AnimalMonitor.
 */
public AnimalMonitor()
{
    this.sightings = new ArrayList<>();
}
/**
 * Add the sightings recorded in the given filename to the current list.
 * @param filename A CSV file of Sighting records.
 */
public void addSightings(String filename)
{
    SightingReader reader = new SightingReader();
    sightings.addAll(reader.getSightings(filename));
}
/**
 * Print details of all the sightings.
 */
public void printList()
{
    //for(Sighting record : sightings) {
     //   System.out.println(record.getDetails());
    //}
    sightings.forEach(record -> System.out.println(record.getDetails()));
}
/**
 * Print the details of all the sightings of the given animal.
 * @param animal The type of animal.
 */
public void printSightingsOf(String animal)
{
    for(Sighting record : sightings) {
        if(animal.equals(record.getAnimal())) {
            System.out.println(record.getDetails());
        }
    }
}
/**
 * Print all the sightings by the given spotter.
 * @param spotter The ID of the spotter.
 */
public void printSightingsBy(int spotter)
{
    for(Sighting record : sightings) {
        if(record.getSpotter() == spotter) {
            System.out.println(record.getDetails());
        }
    }        
}
/**
 * Print a list of the types of animal considered to be endangered.
 * @param animalNames A list of animals names.
 * @param dangerThreshold Counts less-than or equal-to to this level
 *                        are considered to be dangerous.
 */
public void printEndangered(ArrayList<String> animalNames, 
                            int dangerThreshold)
{
    for(String animal : animalNames) {
        if(getCount(animal) <= dangerThreshold) {
            System.out.println(animal + " is endangered.");
        }
    }
}
/**
 * Return a count of the number of sightings of the given animal.
 * @param animal The type of animal.
 * @return The count of sightings of the given animal.
 */
public int getCount(String animal)
{
    int total = 0;
    for(Sighting sighting : sightings) {
        if(animal.equals(sighting.getAnimal())) {
            total = total + sighting.getCount();
        }
    }
    return total;
}
/**
 * Remove from the sightings list all of those records with
 * a count of zero.
 */
public void removeZeroCounts()
{
    Iterator<Sighting> it = sightings.iterator();
    while(it.hasNext()) {
        Sighting record = it.next();
        if(record.getCount() == 0) {
            it.remove();
        }
    }
}
/**
 * Return a list of all sightings of the given type of animal
 * in a particular area.
 * @param animal The type of animal.
 * @param area The ID of the area.
 * @return A list of sightings.
 */
public ArrayList<Sighting> getSightingsInArea(String animal, int area)
{
    ArrayList<Sighting> records = new ArrayList<>();
    for(Sighting record : sightings) {
        if(animal.equals(record.getAnimal())) {
            if(record.getArea() == area) {
                records.add(record);
            }
        }
    }
    return records;
}
/**
 * Return a list of all the sightings of the given animal.
 * @param animal The type of animal.
 * @return A list of all sightings of the given animal.
 */
public ArrayList<Sighting> getSightingsOf(String animal)
{
    ArrayList<Sighting> filtered = new ArrayList<>();
    for(Sighting record : sightings) {
        if(animal.equals(record.getAnimal())) {
            filtered.add(record);
        }
    }
    return filtered;
}
}

Код класса, определяющий информацию о нахождении животных:

public class Sighting
{

 // The animal spotted.
    private final String animal;
    // The ID of the spotter.
    private final int spotter;
    // How many were seen.
    private final int count;
    // The ID of the area in which they were seen.
    private final int area;
    // The reporting period.
    private final int period;
    /**
     * Create a record of a sighting of a particular type of animal.
     * @param animal The animal spotted.
     * @param spotter The ID of the spotter.
     * @param count How many were seen (>= 0).
     * @param area The ID of the area in which they were seen.
     * @param period The reporting period.
     */
public Sighting(String animal, int spotter, int count, int area, int period)
{
    this.animal = animal;
    this.spotter = spotter;
    this.count = count;
    this.area = area;
    this.period = period;
}
/**
 * Return the type of animal spotted.
 * @return The animal type.
 */
public String getAnimal() 
{
    return animal;
}
/**
 * Return the ID of the spotter.
 * @return The spotter's ID.
 */
public int getSpotter() 
{
    return spotter;
}
/**
 * Return how many were spotted.
 * @return The number seen.
 */
public int getCount() 
{
    return count;
}
/**
 * Return the ID of the area in which they were seen.
 * @return Where they were seen.
 */
public int getArea() 
{
    return area;
}
/**
 * Return the period in which they were seen.
 * @return When they were seen.
 */
public int getPeriod() 
{
    return period;
}
/**
 * Return a string containing details of the animal, the number seen,
 * where they were seen, who spotted them and when.
 * @return A string giving details of the sighting.
 */
public String getDetails() 
{
    return animal + 
           ", count = " + count + 
           ", area = " + area + 
           ", spotter = " + spotter + 
           ", period = " + period;
}
}
Answer 1

Потому, что каждый этап обработки стрима должен быть максимально кратким и узкоспециализированным, а также минимально сцепленным с обрабатываемыми данными. Это облегчает восприятие кода и упрощает его сопровождение. В частности, в вашем примере задача операции передаваемой в forEach только выводить текст в консоль, ей не нужно для этого знать структуру класса Sighting.

READ ALSO
JVM: где находится TLAB?

JVM: где находится TLAB?

Мною была прочитана статья на хабре о TLAB Понятно, что у каждого трэда есть свои выделенные куски памятиНо откуда они выделяются? Из хипа? Наблюдаю...

159
Front nodejs (vue) и Spring end безопасность взаимодействия

Front nodejs (vue) и Spring end безопасность взаимодействия

Хочу разработать фронт на vue, который крутится на nodejsСерверная часть будет на spring boot через restapi

181
Хотелось бы по кнопке останавливать код другой кнопки, где задержка

Хотелось бы по кнопке останавливать код другой кнопки, где задержка

у меня код у кнопки, где задержка на закрытие активити, как я бы мог по нажатию другой кнопки останавливать его?

158
Импорт геометок из Google maps

Импорт геометок из Google maps

В приложении есть Google карта, каким образом сделать так, чтобы она отображала только геометки достопримечательностей?

192