import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ceshi {
public static void main(String[] args) {
List<实体类> one = new ArrayList<>();
实体类 vo = new 实体类();
vo.setMatchRingId(12345);
vo.setBoss1BetCount("值1");
vo.setBoss2BetCount("值2");
vo.setWinType(1);
vo.setRewardCount("值3");
vo.setRingType(4);
vo.setPump("值5");
one.add(vo);
List<实体类> two = new ArrayList<>();
实体类 vos = new 实体类();
vos.setMatchRingId(12345);
vos.setNzTotal("99999");
vos.setAbTotal("88888");
two.add(vos);
System.out.println("集合1长度:" + one.size() + "==集合2长度:" + two.size());
Map<Integer, 实体类> map = two.stream()
.collect(Collectors.toMap(实体类::getMatchRingId, match -> match));
// 重复问题
/*
* Map<Integer, 实体类> keyRedo = one.stream()
* .collect(Collectors.toMap(实体类::getMatchRingId, Function.identity(),
* (key1, key2) -> key2));
*/
// 合并
one.forEach(n -> {
// 如果等级一致
if (map.containsKey(n.getMatchRingId())) {
实体类 obj = map.get(n.getMatchRingId());
// 把数量复制过去
n.setAbTotal(obj.getAbTotal());
n.setNzTotal(obj.getNzTotal());
}
});
one.forEach(m -> {
System.out.println(m.getMatchRingId() + "==" + m.getNzTotal() + "==" + m.getPump());
});
}
}
java stream处理list根据多个字段判断重复
List去重复 ,我们首先想到的可能是 利用List转Set 集合,因为Set集合不允许重复。 所以达到这个目的。 如果集合里面是简单对象,例如Integer、String等等,这种可以使用这样的方式去重复。但是如果是复杂对象,即我们自己封装的对象。用List转Set 却达不到去重复的目的。 所以,回归根本。 判断Object对象是否一样,我们用的是其equals方法。 所以我们只需要重写equals方法,就可以达到判断对象是否重复的目的。
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
public class TestCollection {
//去重复之前集合
private static List<User> list = Arrays.asList(
new User("张三", BigDecimal.valueOf(35.6), 18),
new User("李四", BigDecimal.valueOf(85), 30),
new User("赵六", BigDecimal.valueOf(66.55), 25),
new User("赵六", BigDecimal.valueOf(66.55), 25),
new User("张三", BigDecimal.valueOf(35.6), 18));
public static void main(String[] args) {
//排除重复
getNoRepeatList(list);
}
/**
* 去除List内复杂字段重复对象
* @param oldList
* @return
*/
private static List<User> getNoRepeatList(List<User> oldList){
List<User> list = new ArrayList<>();
if(CollectionUtils.isNotEmpty(oldList)){
for (User user : oldList) {
//list去重复,内部重写equals
if(!list.contains(user)){
list.add(user);
}
}
}
//输出新集合
System.out.println("去除重复后新集合:");
if(CollectionUtils.isNotEmpty(list)){
for (User user : list) {
System.out.println(user.toString());
}
}
return list;
}
static class User{
private String userName; //姓名
private BigDecimal score;//分数
private Integer age;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public BigDecimal getScore() {
return score;
}
public void setScore(BigDecimal score) {
this.score = score;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public User(String userName, BigDecimal score, Integer age) {
super();
this.userName = userName;
this.score = score;
this.age = age;
}
public User() {
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "姓名:"+ this.userName + ",年龄:" + this.age + ",分数:" + this.score;
}
/**
* 重写equals,用于比较对象属性是否包含
*/
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
User user = (User) obj;
//多重逻辑处理,去除年龄、姓名相同的记录
if (this.getAge() .compareTo(user.getAge())==0
&& this.getUserName().equals(user.getUserName())
&& this.getScore().compareTo(user.getScore())==0) {
return true;
}
return false;
}
}
}
执行结果:
去除重复后新集合:
姓名:张三,年龄:18,分数:35.6
姓名:李四,年龄:30,分数:85
姓名:赵六,年龄:25,分数:66.55
List<Map<String, Object>> orgList使用stream解析
Map<String,List<Map<String,Object>>> list=orgList.stream().collect(Collectors.groupingBy(e->e.get("map的key值").toString()));
此方法使用场景,如想使用orgList中map的value值分组
使用此方法,有个缺陷,如果map的value为空,会抛出空指针异常,示例如下:
public static void main(String[] args) {
List<Map<String, Object>> orgList=new ArrayList<>();
Map<String,Object> one=new HashMap<>();
one.put("你好","有值");
one.put("空值",null);
orgList.add(one);
Map<String,List<Map<String,Object>>> list=orgList.stream().collect(Collectors.groupingBy(e->e.get("你好").toString()));
System.out.println(list.toString());
}
输出结果:
{有值=[{你好=有值, 空值=null}]}
public static void main(String[] args) {
List<Map<String, Object>> orgList=new ArrayList<>();
Map<String,Object> one=new HashMap<>();
one.put("你好","有值");
one.put("空值",null);
orgList.add(one);
Map<String,List<Map<String,Object>>> list=orgList.stream().collect(Collectors.groupingBy(e->e.get("空值").toString()));
System.out.println(list.toString());
}
输出结果:
Exception in thread "main" java.lang.NullPointerException
at net.sppan.base.util.集合解析.lambda$main$0(集合解析.java:16)
可以使用Optional.ofNullable(obj)
:
传 null 进到就得到 Optional.empty(), 非 null 就调用 Optional.of(obj).
Optional.of(obj)
它要求传入的 obj 不能是 null 值的, 否则 NullPointerException.
使用场景:
- 当我们非常非常的明确将要传给 Optional.of(obj) 的 obj 参数不可能为 null 时;
- 当obj 为 null 立即报告 NullPointException 异常, 而不是隐藏空指针异常时.
Optional.empty()
内部value是null
public static void main(String[] args) {
List<Map<String, Object>> orgList=new ArrayList<>();
Map<String,Object> one=new HashMap<>();
one.put("你好","有值");
one.put("空值",null);
orgList.add(one);
Map<Optional<String>,List<Map<String,Object>>> list=orgList.stream().collect(Collectors.groupingBy(e-> Optional.ofNullable(String.valueOf(e.get("空值")))));
System.out.println(list.toString());
}
输出结果:
{Optional[null]=[{你好=有值, 空值=null}]}
Stream的Collectors.groupingBy支持key为null进行分组
场景
在使用Collectors.groupingBy分组时,如果分组的字段中有值为null,会抛出空指针异常
例如:
// An highlighted block
calss User{
private Integer age;
private String sex;
}
public static void main(String[] args){
User user1 = new User(18, "女");
User user2 = new User(19, "女");
User user3 = new User(20, "男");
//没有性别的人需要用null表示
User user4 = new User(18, null);
groupBy(Arrays.aslist(user1,user2,user3,user4))
}
//对用户按照年纪分组
public void groupBy(List<User> userList){
//此时这里会抛出空指针异常
Map<String, List<User>> userMap = userList.stream.collect(Collectors.groupingBy(x -> x.getSex()));
}
解决方案
public void groupBy(List<User> userList){
//使用option包装一层
Map<Option<String>, List<User>> userMap = userList.stream.collect(Collectors.groupingBy(x -> Optional.ofNullable(x.getSex())));
}
过滤list中对象的某个属性非空,然后返回一个新的list
import com.example.demo.entity.UserPO;
import com.google.common.collect.Maps;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 过滤list中对象的某个属性非空,然后返回一个新的list
*/
public class LambdaForList {
public static void main(String[] args) {
//1. 初始化数据
UserPO user1 = new UserPO(1, "java");
UserPO user2 = new UserPO(2, "C");
UserPO user3 = new UserPO(null, "PHP");
List<UserPO> users = new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3);
//2. 过滤list中对象的某个属性非空,然后返回一个新的list
List<UserPO> newUsers = users.stream()
.filter((UserPO user) -> user.getId() !=null).collect(Collectors.toList());
newUsers.forEach((UserPO user) ->
System.out.println(user.getName() + "--->" + user.getId()
));
}
}
输出:
java--->1
C--->2
JDK8 Lamdba表达式转换成Map,value为null问题
// 将list转换成Map类型
Map<String, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName));
// 如果报 map里的value空指针异常,则需要在value,也就是toMap()的第二个参数进行空(null)值的判断逻辑;例如:也就是 Person::getName 改成 p -> p.getName()==null?"":p.getName()就可以解决value为null问题
// <Person, String, String> Collector<Person, ?, Map<String, String>> java.util.stream.Collectors.toMap(Function<? super Person, ? extends String> keyMapper, Function<? super Person, ? extends String> valueMapper, BinaryOperator<String> mergeFunction)
// toMap()第三个参数是当有重复的Key时,会执行这段逻辑,传入2个参数,第一个参数是已经存在Map的value值,第二个是即将覆盖的value值,最终返回哪个值为准
stream将List转map,解决Duplicate key异常
public static void main(String[] args) {
List<Map<String, String>> list = new ArrayList<>(16) ;
Map<String,String> map1 = new HashMap<>(16);
map1.put("key1", "val1");
Map<String,String> map2 = new HashMap<>(16);
map2.put("key1", "val1");
list.add(map1);
list.add(map2);
//打印list里面的数据
list.forEach(System.out::println);
ArrayList<Map<String, String>> data = list.stream().collect(
Collectors.collectingAndThen(Collectors.toCollection(
() -> new TreeSet<>(Comparator.comparing(m -> m.get("key1")))), ArrayList::new));
System.out.println("=======去重前后分界线=======");
//打印过滤后的数据
data.forEach(System.out::println);
}
}
打印结果如下:
{key1=val1}
{key1=val1}
=======去重前后分界线=======
{key1=val1}
public static void main(String[] args) {
List<Map<String, String>> list = new ArrayList<>();
{
Map<String, String> map = new HashMap<>();
map.put("id", "1");
map.put("name", "B");
map.put("age", "C");
list.add(map);
}
{
Map<String, String> map = new HashMap<>();
map.put("id", "1");
map.put("name", "E");
map.put("age", "F");
list.add(map);
}
//1.返回结果{"1","B"},{"2","E"}
// Map<String, String> a = list.stream().collect(Collectors.toMap(l -> l.get("id"), l -> l.get("name")));
//2.两种方法返回结果{"1":{"name":"B","id":"1","age":"C"},"2":{"name":"E","id":"2","age":"F"}}
// Map<String, Map> b = list.stream().collect(Collectors.toMap(l -> l.get("id"), map -> map));
// Map<String, Map> c = list.stream().collect(Collectors.toMap(l -> l.get("id"), Function.identity()));
//3.重复key情况下处理方式返回结果{"1":{"name":"E","id":"1","age":"F"}}
// Map<String, Map> d = list.stream().collect(Collectors.toMap(l -> l.get("id"), Function.identity(), (key1, key2) -> key2));
//4.重复key情况下指定返回数据类型处理方式返回结果{"1":{"name":"E","id":"1","age":"F"}}
// Map<String, Map> e = list.stream().collect(Collectors.toMap(l -> l.get("id"), Function.identity(), (key1, key2) -> key2, LinkedHashMap::new));
//5.list根据key合并并转map;返回结果{"1":[{"name":"B","id":"1","age":"C"},{"name":"E","id":"1","age":"F"}]}
// Map<String, List<Map>> lableGbType = list.stream().collect(Collectors.groupingBy(l -> (String) l.get("id")));
//6.根据key提取list中指定的值转List数组;返回结果["1","1"]
// List<String> ids = list.stream().map(m -> (String) m.get("id")).collect(Collectors.toList());
//7.数组去重并转list
/* String[] str = "1,1,2,3,4,5,".split(",");
List<String> listNames = Arrays.stream(str).filter(name -> !isEmpty(name)).distinct().collect(Collectors.toList());*/
}
使用Java 8 Stream将List(Object)转成List(Map(String, Object))
问题描述:有一个用户列表List<User>,须将每个User部分字段提取出来,重新放入一个Map中,然后将生成的Map放入List中。
原代码如下:
public static List<Map<String, Object>> toListMap(List<User> userList) {
List<Map<String, Object>> result = new ArrayList<>();
Map<String, Object> map;
for (User user : userList) {
map = new HashMap<>();
map.add("username", user.getUserName);
map.add("age", user.getAge);
map.add("gender", user.getGender);
result.add(map);
}
return result;
}
使用Java 8 stream后,代码如下:
private Map<String, Object> toMap(User user) {
Map<String, Object> map = new HashMap<>();
map.add("username", user.getUserName);
map.add("age", user.getAge);
map.add("gender", user.getGender);
return map;
}
List<Map<String, Object>> data = userList.stream()
.map(this::toMap)
.collect(Collectors.toList());