Java中从方法访问ArrayList的方式及函数式编程实现偶数输出咨询
Hey George, let's tackle your two questions one by one—first covering how to access an ArrayList from methods, then refactoring your code to follow Java functional programming principles.
1. Ways to Access an ArrayList from Methods
There are a few common approaches, each with its own use case:
Pass it as a method parameter
This is the cleanest and most encapsulated approach. Just pass the list directly to any method that needs to work with it. For example:public static void addToEvenList(ArrayList<Double> list, double num) { if (num % 2 == 0) { list.add(num); } }Call it from main like
addToEvenList(listEven, inputNum);—no shared state, no unexpected side effects.Make it a static class field
If multiple static methods in your class need to access the same list, declare it as a static variable at the class level. Note: Static fields are shared across all instances of the class, so use this cautiously to avoid unintended state changes. Example:private static ArrayList<Double> listEven = new ArrayList<>(); public static void inputRecursion() { // You can access listEven directly here }Return it from a method
If a method is responsible for collecting or generating the list, have it return the list to the caller. Then you can pass that returned list to other methods as needed. Like:public static ArrayList<Double> collectInputNumbers() { ArrayList<Double> numbers = new ArrayList<>(); Scanner in = new Scanner(System.in); // Populate the list here return numbers; } public static void main(String[] args) { ArrayList<Double> listEven = collectInputNumbers(); printEvenNumbers(listEven); }Use an instance field (for OOP-style code)
If you're moving away from static methods, declare the ArrayList as an instance variable of a class. Create an object of that class and access the list via its methods—great for encapsulation in object-oriented code:public class NumberProcessor { private ArrayList<Double> evenNumbers = new ArrayList<>(); public void collectInput() { // Access this.evenNumbers here } public void printEvens() { // Access this.evenNumbers here } }
2. Refactoring Your Code for Functional Programming Principles
First, the immediate issue: your listEven is declared inside main, so inputRecursion and outputRecursion can't see it. Let's fix that while leaning into functional concepts like immutability, pure functions, and streams.
Here's a revised version that follows functional programming best practices:
import java.util.List; import java.util.Scanner; import java.util.stream.Collectors; import java.util.stream.Stream; public class EvenNumberPrinter { // Pure function: takes input, returns a list without modifying external state private static List<Double> readNumbersRecursively(Scanner scanner) { if (!scanner.hasNextDouble()) { return List.of(); // Return empty immutable list when input ends } double num = scanner.nextDouble(); List<Double> rest = readNumbersRecursively(scanner); // Build a new list instead of mutating an existing one return Stream.concat(Stream.of(num), rest.stream()) .collect(Collectors.toList()); } public static void main(String[] args) { try (Scanner scanner = new Scanner(System.in)) { // Read all input numbers recursively List<Double> allNumbers = readNumbersRecursively(scanner); // Filter even numbers using streams (declarative, functional approach) List<Double> evenNumbers = allNumbers.stream() .filter(num -> num % 2 == 0) // Lambda to check evenness .collect(Collectors.toList()); // Print even numbers using method reference evenNumbers.forEach(System.out::println); } // Scanner auto-closes here with try-with-resources } }
Key Functional Improvements:
- Pure Function:
readNumbersRecursivelydoesn't modify any external variables—it just takes a Scanner and returns a list of numbers. No side effects! - Immutability: Instead of adding to a shared list, we build new lists recursively. Using
List.of()for the base case gives us an immutable list. - Streams & Lambdas: The
stream().filter()call is declarative—we tell the code what we want (even numbers) instead of writing an imperative loop to do it. - Method References:
System.out::printlnis a cleaner alternative to writing a lambda likenum -> System.out.println(num). - Resource Management: Try-with-resources ensures the Scanner is properly closed, which is a good practice regardless of paradigm.
内容的提问来源于stack exchange,提问作者George S.

