JDK1.8之stream用法

文章详细介绍了Java中对列表数据进行操作的各种方法,包括使用流(Stream)进行过滤、筛选,按不同条件分组,排序,去重,拼接字符串,转换Map和List,以及统计和计算各种极值。这些技术在处理集合数据时非常实用。

过滤

//根据指定sn,过滤出符合的数据: List<Map<String, Object>> deviceDataList

List<Map<String, Object>> tempDeviceDataList = deviceDataList.stream().filter(map -> map.get("sn").toString().equals(sn)).collect(Collectors.toList());

//筛选出工资大于10000的职员

List<Employee> newList = list.stream().filter(item -> {

return item.getSalary().compareTo(new BigDecimal(10000)) > 0 && !item.getWorkType().equals("项目经理");

}).collect(Collectors.toList());

分组

// 按照sn分组: List<Map<String, Object>> dataList

Map<String, List<Map<String, Object>>> dataMap = dataList.stream().collect(Collectors.groupingBy(e -> e.get("sn") + ""));

//按照职员部分分组: List<Employee> list

Map<String, List<Employee>> collect = list.stream().collect(Collectors.groupingBy(i -> i.getUnitName()));

//多条件分组

Map<String, Map<String,List<Employee>>> collect =list.stream().collect(Collectors.groupingBy(i -> i.getUnitName(),Collectors.groupingBy(i -> i.getWorkType())));

//按年龄分组,年龄相同的是一组

Map<Integer, List<Person>> 分组 = list.stream().collect(Collectors.groupingBy(Person::getAge));

//按年龄分组后按工资分组,多级分组

Map<Integer, Map<String, List<Person>>> 多级分组 = list.stream().collect(Collectors.groupingBy(Person::getAge, Collectors.groupingBy(x -> {

return x.getSalary() > 3000 ? "高" : "低";

})));

// 分组排序 ,拿已经排好序的过来分组

LinkedHashMap<String, List<AttendanceRuleGroup>> groupingByruleGroupList = ruleGroupList.stream().collect(Collectors.groupingBy(AttendanceRuleGroup::getCategory, LinkedHashMap::new, Collectors.toList()));

// 分组排序,集合没排序,我们自己按我们想要的排序

LinkedHashMap<String, List<AttendanceRuleGroup>> groupingByruleGroupList = ruleGroupList.stream().sorted(Comparator.comparingLong(AttendanceRuleGroup::getSort).reversed()).collect(Collectors.groupingBy(AttendanceRuleGroup::getCategory, LinkedHashMap::new, Collectors.toList()));

分区

//List<Employee> list

//单层分区

Map<Boolean, List<Employee>> collect = list.stream().collect(Collectors.partitioningBy(i -> i.getId() == 1));

//分区 满足条件的一个区,不满足条件的一个区

Map<Boolean, List<Person>> collect1 = list.stream().collect(Collectors.partitioningBy(e -> e.getSalary() < 2000));

//多层分区

Map<Boolean, Map<Boolean,List<Employee>>> collect = list.stream().collect(Collectors.partitioningBy(i -> i.getId() == 1,Collectors.partitioningBy(i -> i.getSalary().compareTo(new BigDecimal(20000)) == 0)));

拼接

//将某个字段,按照某个字符串拼接: List<Map<String, Object>> deviceMapList

String sns = deviceMapList.stream()

.map((m)->m.get("sn")+"").collect(Collectors.joining(","));

//使用场景很多,在sql里面用于组织in的值.比如:

SELECT sn,time,value FROM electric_real_time WHERE FIND_IN_SET(sn,?)

List<Map<String, Object>> dataList = JdbcUtil.getJdbcTemplate().queryForList(dataSql, sns)

List<String> strs = Arrays.asList("a","b","cd");

//连接所有内容

String str = strs.stream().collect(Collectors.joining());

System.out.println(str);

//输出:abcd

//连接所有内容,中间加一个逗号隔开

String str1 = strs.stream().collect(Collectors.joining(","));

System.out.println(str1);

//输出:a,b,cd

//连接所有内容,中间加一个逗号隔开,两边加上括号

String str2 = strs.stream().collect(Collectors.joining(",","(",")"));

System.out.println(str2);

//输出:(a,b,cd)

list转map

// (k1,k2)->k2 避免键重复 k1-取第一个数据;k2-取最后一条数据

//key和value,都可以根据传入的值返回不同的Map

Map<String, String> deviceMap = hecmEnergyDevicesList.stream().collect(Collectors.toMap(i -> i.getDeviceNum(), j -> j.getDeviceName(), (k1, k2) -> k1));

//

Map<String, Object> map = list.stream()

.collect(Collectors.toMap(i -> i.getEmpName() + i.getUnitName(), j -> j, (k1, k2) -> k1));

map转list

//在.map里面构造数据 return什么数据就转成什么类型的list

List<Employee> collect = map.entrySet().stream().map(item -> {

Employee employee = new Employee();

employee.setId(item.getKey());

employee.setEmpName(item.getValue());

return employee;

}).collect(Collectors.toList());

去重

//去重之后进行拼接: List<String> deviceNodeList

Srting deviceNodeStr = deviceNodeList.stream().distinct().collect(Collectors.joining("','"));

//直接去重返回list

// List<String> deviceIdList

List<String> deviceIdList = deviceIdList.stream().distinct().collect(Collectors.toList());

排序

//按照时间排序 1升 -1降

Collections.sort(listFast, (p1, p2) -> {

return String.valueOf(p1.get("time")).compareTo(p2.get("time") + "");

});

// s1-s2 升序 s2-s1降序

Collections.sort(list,(s1,s2) -> s1.getSalary().compareTo(s2.getSalary()));

//多条件排序: List<Employee> list, s1-s2 升序 s2-s1降序

list.sort(Comparator.comparing(Employee::getSalary).reversed().thenComparing(Employee::getId).reversed());

求和/极值

//在egyList里面求cols的和

public static BigDecimal getSumBig(List<Map<String,Object>> egyList, String cols){

BigDecimal consuBig = egyList.stream()

.filter((Map m)->StringUtils.isNotEmpty(m.get(cols)+"") && !"null".equals(String.valueOf(m.get(cols)))

&& !"-".equals(String.valueOf(m.get(cols))))

.map((Map m)->new BigDecimal(m.get(cols)+""))

.reduce(BigDecimal.ZERO,BigDecimal::add);

return consuBig;

}

//List<Employee> list

//Bigdecimal求和/极值:

BigDecimal sum = list.stream().map(Employee::getSalary).reduce(BigDecimal.ZERO,BigDecimal::add);

BigDecimal max = list.stream().map(Employee::getSalary).reduce(BigDecimal.ZERO,BigDecimal::max);

//基本数据类型求和/极值:

Integer sum = list.stream().mapToInt(Employee::getId).sum();

OptionalInt optionalMax = list.stream().mapToInt(Employee::getId).max();

optionalMax.getAsInt();

统计

//统计:和、数量、最大值、最小值、平均值: List<Employee> list

IntSummaryStatistics collect = list.stream().collect(Collectors.summarizingInt(Employee::getId));

System.out.println("和:" + collect.getSum());

System.out.println("数量:" + collect.getCount());

System.out.println("最大值:" + collect.getMax());

System.out.println("最小值:" + collect.getMin());

System.out.println("平均值:" + collect.getAverage());

求最大/最小值的对象

Optional<Employee> optional = list.stream().collect(Collectors.maxBy(Comparator.comparing(Employee::getId)));

if (optional.isPresent()) { // 判断是否有值

Employee user = optional.get();

}

return optional.orElse(new Employee());

平均值

OptionalDouble average = list.stream().mapToInt(Employee::getId).average();

average.getAsDouble();

某个值的数量

//List<Employee> list

Map<BigDecimal, Long> collect = list.stream().collect(Collectors.groupingBy(i -> i.getSalary(),Collectors.counting()));

//List<Map<String,Object>> egyList

long count = egyList.stream()

.filter((Map m)->StringUtils.isNotEmpty(m.get(cols)+""))

.map((Map m)->new BigDecimal(m.get(cols)+""))

.count();

收集

//取出所有年龄放到list集合中

List<Integer> toList = list.stream().map(Person::getAge)

.collect(Collectors.toList());

//取出所有年龄放到set集合中

Set<Integer> toSet = list.stream().map(Person::getAge)

.collect(Collectors.toSet());

//取出所有年龄放到hashSet集合中

HashSet<Integer> toHashSet = list.stream().map(Person::getAge)

.collect(Collectors.toCollection(HashSet::new));

//获取集合中元素总和

Long count = list.stream().collect(Collectors.counting());

//获取年龄平均值

Double avg = list.stream().collect(Collectors.averagingInt(Person::getAge));

//获取工资总和

Double sum = list.stream().collect(Collectors.summingDouble(Person::getSalary));

//获取工资最大值的人

Optional<Person> max = list.stream().collect(Collectors.maxBy((p1, p2) -> Double.compare(p1.getSalary(), p2.getSalary())));

System.out.println(max.get());

//获取工资最小值的人

Optional<Person> min = list.stream().collect(Collectors.minBy((p1, p2) -> Double.compare(p1.getSalary(), p2.getSalary())));

System.out.println(min.get());

//获取元素个数、总和、最小值、平均值、最大值

DoubleSummaryStatistics collect = list.stream().collect(Collectors.summarizingDouble(Person::getSalary));

System.out.println(collect);

//输出结果:DoubleSummaryStatistics{count=5, sum=34024.000000, min=99.000000, average=6804.800000, max=9999.000000}

全部转大写

List<String> list = Arrays.asList("a","vvv","ddd");

//中间操作:不会执行任何操作

Stream<String> stream = list.stream()

.map(x -> x.toUpperCase());

//终止操作:一次性执行全部内容,惰性求值

stream.forEach(System.out::println);

查找与匹配

List<Person> list = Arrays.asList(

new Person(18,3939),

new Person(38,9999),

new Person(17,9999),

new Person(19,9988),

new Person(38,99)

);

//是否匹配所有元素 此处返回false

boolean b = list.stream().allMatch(e -> e.getAge() == 18);

System.out.println(b);

//至少匹配一个元素,此处返回true

boolean b1 = list.stream().anyMatch(e -> e.getAge() == 19);

System.out.println(b1);

//流中是否没有匹配元素,此处返回false

boolean b2 = list.stream().noneMatch(e -> e.getAge() == 19);

System.out.println(b2);

//排序后获取第一个元素

Optional<Person> first = list.stream().sorted((x, y) -> x.getAge().compareTo(y.getAge())).findFirst();

System.out.println(first);

//获取流中任意一个元素

list.stream().findAny();

//返回流中元素的总个数

list.stream().count();

//返回流中最大值 此处根据年龄比较

Optional<Person> max = list.stream().max((x, y) -> x.getAge().compareTo(y.getAge()));

System.out.println(max.get());

//返回流中最小值 此处根据年龄比较

Optional<Person> min = list.stream().min((x, y) -> x.getAge().compareTo(y.getAge()));

System.out.println(min.get());

//获取最小的年龄

Optional<Integer> age = list.stream().map(Person::getAge).min(Integer::compareTo);

System.out.println(age.get());

//获取一个并行流,并行流会使用多个线程操作流,stream()获取的是串行流,单个线程操作流

list.parallelStream();

//查找第一个元素

Optional<Dish> collect = menu.stream().filter(dish -> dish.getCalories() > 1000).findFrist();

跳过

List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8);

//中间操作:不会执行任何操作

Stream<Integer> stream = list.stream()

.skip(5);

//终止操作:一次性执行全部内容,惰性求值

stream.forEach(System.out::println);

截断

List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8);

//中间操作:不会执行任何操作

Stream<Integer> stream = list.stream()

.filter(e -> {

System.out.println("过滤 中间操作");

return e>3;

})

.limit(2);

//终止操作:一次性执行全部内容,惰性求值

stream.forEach(System.out::println);

<think>我们正在讨论Eclipse项目中使用JDK 1.8Stream写法报错的问题。首先,需要确认错误的具体情况,但根据常见问题,可能有以下几个原因和解决方案: 1. **项目JDK版本设置**:确保Eclipse项目确实设置为使用JDK 1.8。检查方法: - 右键项目 -> Properties -> Java Build Path -> Libraries选项卡,确认JRE System Library是JDK 1.8。 - 同样在Properties -> Java Compiler 中,确保Compiler compliance level为1.8。 2. **Eclipse版本支持**:Eclipse从某个版本开始原生支持Java 8(例如Eclipse Luna SR2及更高版本)。如果使用的是较旧的Eclipse版本(如Kepler),则需要安装Java 8支持插件。但注意,如果已经安装了中文语言包,可能会存在兼容性问题(如引用[^1]提到的)。建议: - 升级到较新的Eclipse版本(如最新版的Eclipse IDE for Enterprise Java Developers)。 - 或者,对于旧版Eclipse,安装Java 8支持插件(具体步骤:Help -> Install New Software,然后添加更新站点,如Luna的更新站点:http://download.eclipse.org/releases/luna,搜索“Java 8”相关的插件并安装)。 3. **编译器设置**:即使项目使用JDK 1.8,但Eclipse的编译器设置可能没有启用Java 8特性。检查: - 项目Properties -> Java Compiler -> 确保已勾选“Enable project specific settings”(如果设置了的话),并且Compiler compliance level为1.8,同时下方“Use default compliance settings”通常保持勾选。 - 另外,在“Configure Workspace Settings...”中,确保编译器合规级别为1.8。 4. **代码错误**:Stream报错也可能是代码本身错误,比如使用了Stream不支持的语法或方法。确保代码符合Java 8语法。 5. **项目配置**:检查是否引入了错误的JRE。有时可能引入了JRE而不是JDK(JRE不包含编译器所需的所有类),建议使用JDK。 6. **清理和重新编译**:修改设置后,执行Project -> Clean...,清理项目并重新编译。 7. **检查IDE错误日志**:如果Eclipse启动或编译时出错,查看错误日志(Workspace路径下的.metadata/.log文件)以获取详细信息。 由于引用[^1]提到了Eclipse版本和语言包兼容性问题,如果上述设置都正确,但问题依旧,可能是Eclipse本身或语言包的问题。此时建议: - 尝试在不使用中文语言包的情况下启动Eclipse(例如通过命令行指定语言:`eclipse -nl en`),然后检查问题是否还存在。如果问题消失,则说明是语言包版本不兼容。 - 更新或重新安装与当前Eclipse版本匹配的中文语言包。 §§相关问题§§ 1. 如何检查Eclipse中当前项目使用的JDK版本? 2. Eclipse中如何升级或安装Java 8支持插件? 3. 如何解决Eclipse的语言包兼容性问题? 4. Stream API在Java 8中的常见错误有哪些? 5. 如何在Eclipse中配置多个JDK版本? </think>### Eclipse项目使用JDK 1.8Stream写法报错的解决方案 在Eclipse中使用JDK 1.8Stream写法报错,通常由以下原因导致。请依次排查: --- #### 1. **检查JDK合规性设置** - **步骤**:右键项目 → Properties → Java Compiler - 确认 "Compiler compliance level" 设置为 `1.8` - 勾选 "Enable project specific settings" - **错误示例**:若设置为低版本(如1.7),会报错: ```java The method stream() is undefined for the type List ``` - **解决**:调整为JDK 1.8级别后,执行 `Project → Clean` 重新编译[^1]。 --- #### 2. **验证JRE系统库** - **步骤**:右键项目 → Properties → Java Build Path → Libraries - 检查 "JRE System Library" 是否为 **JDK 1.8** - 若显示JRE而非JDK(如 "JRE 1.8.0"),需替换: 1. 移除当前JRE 2. 点击 "Add Library" → "JRE System Library" → "Alternate JRE" → 选择JDK 1.8 - **关键点**:JDK包含完整API,JRE可能缺失开发包。 --- #### 3. **配置执行环境** - **步骤**: 1. Window → Preferences → Java → Installed JREs 2. 确保JDK 1.8被添加且勾选 3. 回到项目Properties → Java Build Path → Libraries 4. 编辑JRE System Library → 选择 "Execution environment" → `JavaSE-1.8` --- #### 4. **检查Eclipse版本兼容性** - **要求**:Eclipse需 **4.5 (Mars) 及以上版本** 完整支持Java 8 - 旧版(如Kepler)需手动安装Java 8插件: 1. Help → Install New Software 2. 添加更新站点:`http://download.eclipse.org/eclipse/updates/4.5` 3. 安装 "Eclipse Java 8 Support" - **注意**:若使用中文语言包,需确保其版本与Eclipse主程序严格匹配[^1]。 --- #### 5. **处理依赖冲突** - **场景**:项目依赖的第三方库(如旧版Guava)覆盖了JDK 8Stream API - **排查**: - 检查pom.xml(Maven)或build.gradle(Gradle)中的依赖 - 使用 `mvn dependency:tree` 或 `gradle dependencies` 分析冲突 - **解决**:排除冲突依赖或升级兼容库。 --- #### 6. **代码语法校对** - **常见错误**: ```java // 错误:未正确使用Stream List<Integer> list = Arrays.asList(1, 2, 3); list.stream().forEach(System.out::print); // 正确 list.stream().forEch(System.out::print); // 拼写错误 → 报错 ``` --- ### 验证流程 1. 创建一个测试类: ```java import java.util.Arrays; import java.util.List; public class StreamTest { public static void main(String[] args) { List<String> list = Arrays.asList("a", "b", "c"); list.stream().map(String::toUpperCase).forEach(System.out::println); } } ``` 2. 若输出 `A B C` 则Stream功能正常。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值