如何使用Java 8 Stream方法获取最大prizeAmount值
使用Java 8 Stream提取所有Hit的最大prizeAmount
没问题,这就给你梳理清楚怎么实现这个需求——从CSV读取数据到ArrayList<Round>,再用Java 8 Stream提取所有Hit的prizeAmount最大值。
第一步:定义实体类
首先得先把Hit和Round这两个实体类写好,确保有对应的getter方法(Stream需要访问字段值):
Hit类
public class Hit { private int numberOfGames; private int prizeAmount; // 构造器 public Hit(int numberOfGames, int prizeAmount) { this.numberOfGames = numberOfGames; this.prizeAmount = prizeAmount; } // 必须的getter,用于Stream提取字段 public int getPrizeAmount() { return prizeAmount; } // 可选:toString方法方便调试 @Override public String toString() { return "Hit{" + "numberOfGames=" + numberOfGames + ", prizeAmount=" + prizeAmount + '}'; } }
Round类
import java.util.List; public class Round { private List<Hit> hits; public Round(List<Hit> hits) { this.hits = hits; } // 必须的getter,用于Stream访问hits列表 public List<Hit> getHits() { return hits; } }
第二步:读取CSV到ArrayList
这里用原生Java的BufferedReader读取CSV,提供两种场景的实现:
场景1:所有Hit存入单个Round
假设CSV每行对应一个Hit(格式:numberOfGames,prizeAmount):
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class CsvToRoundList { public static ArrayList<Round> readCsvIntoSingleRound(String csvFilePath) throws IOException { ArrayList<Round> arrRound = new ArrayList<>(); try (BufferedReader br = new BufferedReader(new FileReader(csvFilePath))) { // 跳过CSV表头(如果没有表头可删除此行) br.readLine(); // 读取所有行并转换为Hit列表 List<Hit> allHits = br.lines() .map(line -> line.split(",")) .filter(parts -> parts.length == 2) .map(parts -> new Hit( Integer.parseInt(parts[0].trim()), Integer.parseInt(parts[1].trim()) )) .collect(Collectors.toList()); // 存入单个Round arrRound.add(new Round(allHits)); } return arrRound; } }
场景2:按CSV的分组字段生成多个Round
如果CSV包含Round分组标识(格式:roundId,numberOfGames,prizeAmount):
public static ArrayList<Round> readCsvWithRoundGroups(String csvFilePath) throws IOException { ArrayList<Round> arrRound = new ArrayList<>(); try (BufferedReader br = new BufferedReader(new FileReader(csvFilePath))) { br.readLine(); // 跳过表头 // 按roundId分组,生成对应Round对象 arrRound = br.lines() .map(line -> line.split(",")) .filter(parts -> parts.length == 3) .collect(Collectors.groupingBy( parts -> Integer.parseInt(parts[0].trim()), Collectors.mapping( parts -> new Hit( Integer.parseInt(parts[1].trim()), Integer.parseInt(parts[2].trim()) ), Collectors.toList() ) )) .values() .stream() .map(Round::new) .collect(Collectors.toCollection(ArrayList::new)); } return arrRound; }
第三步:用Java 8 Stream提取最大prizeAmount
核心逻辑是扁平化流→提取字段→安全找最大值,用OptionalInt处理空流场景:
import java.util.ArrayList; import java.util.OptionalInt; public class MaxPrizeFinder { public static void main(String[] args) { try { // 根据你的CSV格式选择对应读取方法 ArrayList<Round> arrRound = CsvToRoundList.readCsvIntoSingleRound("your_csv_file_path.csv"); // 核心Stream操作 OptionalInt maxPrize = arrRound.stream() // 扁平化:把每个Round的hits列表展开为Hit流 .flatMap(round -> round.getHits().stream()) // 提取prizeAmount,转为IntStream提升效率 .mapToInt(Hit::getPrizeAmount) // 获取最大值,返回OptionalInt避免空流异常 .max(); // 处理结果 if (maxPrize.isPresent()) { System.out.println("所有Hit中的最大奖金金额: " + maxPrize.getAsInt()); } else { System.out.println("没有找到任何有效的奖金数据"); } } catch (IOException e) { e.printStackTrace(); } } }
关键步骤解释
flatMap扁平化:将每个Round的List<Hit>拆分为单个Hit对象的流,让后续操作能直接遍历所有Hit。mapToInt类型转换:将Hit对象转为对应的prizeAmount整数,使用IntStream比Stream<Integer>更高效,且提供原生的max()方法。OptionalInt安全处理:如果没有任何Hit数据,max()会返回空的OptionalInt,通过isPresent()判断后再取值,避免抛出NoSuchElementException。
内容的提问来源于stack exchange,提问作者Kokufuu
相关产品推荐
相关产品推荐

