https://github.com/jpcsp/jpcsp ? The Java stream api allows you to process lists of objects in a easy and functional way. Collections in Java are used for storing information in memory while streams process lists of objects in a pipeline fashion by chaining together functions and piping the result into the next one. Streams need a terminal operation at the end to do something with the data or nothing will happen as a result. Some of these terminal operations include collect to get a list, forEach to iterate through the elements and reduce to reduce the elements to a single value. To perform operations on a stream intermediate operations are used such as map to apply a given function to each element, filter to select elements and sorted to sort the stream. Streams in java are not executed until their terminal operation is invoked which is called lazy evaluation. The project that I chose to look at for this assignment is [OpenRocket](https://github.com/openrocket/openrocket), which is open-source simulation software for model rockets. The first example that I found of the use of the stream api was to get all of the children of a rocket component. The last example that I found of the stream api was in updating the motor state of the rockets. https://github.com/openrocket/openrocket/blob/unstable/core/src/main/java/info/openrocket/core/rocketcomponent/Rocket.java#L867 ``` /** * Returns all descendants of the specified component. * * @param component Component to query * @return All descendants * @apiNote Returns an empty set if the component does not have children. */ private Set getDescendants(RocketComponent component) { Objects.requireNonNull(component); var result = new LinkedHashSet(); var queue = new ArrayDeque<>(component.getChildren()); while (!queue.isEmpty()) { var node = queue.pop(); result.add(node); node.getChildren().stream().filter(c -> !result.contains(c)).forEach(queue::add); } return result; } ``` This function takes all of the children of a specified component and then adds them to a queue. It then loops through that queue and adds each child to it as well as any children it has. It uses a stream to ensure that nodes are not added twice using the filter method. It then uses the forEach terminal method to add each node not already in the queue to the queue. Another example that I found of the stream api is in a function to format flight data. https://github.com/openrocket/openrocket/blob/2719a75a0c9fdd4b84e7eda53e80706dca6f9db5/swing/src/main/java/info/openrocket/swing/gui/simulation/AerodynamicLookupDialog.java#L640 ``` static String formatLookupSummary(Translator translator, MachAoALookup table) { String columns = table.getValueColumns().stream() .map(name -> name.toUpperCase(Locale.ROOT)) .collect(java.util.stream.Collectors.joining(", ")); String machMin = formatDouble(table.getMinMach()); String machMax = formatDouble(table.getMaxMach()); if (table.hasAoA()) { String aoaMin = formatDouble(table.getMinAoA()); String aoaMax = formatDouble(table.getMaxAoA()); return String.format(translator.get("AerodynamicLookupDialog.summaryWithAoA"), machMin, machMax, aoaMin, aoaMax, columns); } return String.format(translator.get("AerodynamicLookupDialog.summaryNoAoA"), machMin, machMax, columns); } ``` The stream api is used here to format all of the data columns to make them all upper case and join them with commas in between. This is helpful since it is a much more concise and readable method than using a loop and concatenating strings. The last example that I found of the stream api was in updating the motor state of the rockets. https://github.com/openrocket/openrocket/blob/unstable/core/src/main/java/info/openrocket/core/rocketcomponent/Rocket.java#L867 ``` private void updateMotorState() { Rocket rocket = document.getRocket(); boolean newHasValidConfig = rocket != null && rocket.getIds().stream().anyMatch(rocket::hasMotors); if (newHasValidConfig == hasValidConfig) { return; } hasValidConfig = newHasValidConfig; cardLayout.show(cardPanel, hasValidConfig ? CARD_TABLE : CARD_HELP); } ``` Stream is used here to make sure that all of the flight configs for the rocket have valid motors. The stream api is used to make this much more compact and readable and contains it to one line. In this project it seems like the stream api is mostly used to make the code more concise and readable and as an alternative to loops that might take up more space. It is much easier to understand a forEach function than a loop through an array and it takes up a lot less space. In future projects I will likely use it in a similar way to make my code more understandable to others and take up less space.