我有MainEntity的名单
public class MainEntity {
private String keyword;
private double cost;
private String company;
}我有CompanyEntity
public class CompanyEntity {
private double cost;
private String company;
}我正在尝试将我的列表转换为Map<String,List<CompanyEntity>>,其中的键将是keyword,List<CompanyEntity>将有所有成本的平均值,并进行排序。我正试图在流和Java 8中完成它。
对于一个特定的关键字作为输入,我正在这样做。
List<MainEntity> entityList = keyWordMap.get(entity.getKeyword());
entityList.add(entity);
keyWordMap.put(entity.getKeyword(), entityList);
Map<String, Double> average = (keyWordMap.get(keyword)).stream()
.collect(groupingBy(MainEntity::getCompany,
Collectors.averagingDouble(MainEntity::getCtr)));
result.put(keyword, new ArrayList<>());
for (Map.Entry<String, Double> entity : average.entrySet()) {
result.get(keyword).add(new CompanyEntity(entity.getKey(), entity.getValue()));
}但我试着为所有关键词创建一个地图。是否有可能再次迭代整个列表?目前,keyowordMap是Map<String,MainEntity>类型的,我是通过迭代MainEntity列表来实现的,但是我想要Map<String,List<MainEntity>>。
发布于 2020-08-15 08:16:45
首先,制作一个keyWordMap
Map<String, List<MainEntity>> keyWordMap =
mainEntityList
.stream()
.collect(Collectors.groupingBy(MainEntity::getKeyword));然后迭代映射,对于每个关键字,可以根据平均值直接获取CompanyEntity排序列表,并使用map()转换数据并将其作为列表收集,然后放入result中。
Map<String,List<CompanyEntity>> result = ....
for (Map.Entry<String, List<MainEntity> entry : keyWordMap.entrySet()) {
List<CompanyEntity> list = entry.getValue().stream()
.collect(groupingBy(MainEntity::getCompany,
Collectors.averagingDouble(MainEntity::getCtr)))
.entrySet()
.stream()
.sorted(Comparator.comparing(e -> e.getValue()))
.map(e -> new CompanyEntity(e.getKey(), e.getValue()))
.collect(Collectors.toList());
result.put(entry.getKey(), list);
}或者你想一蹴而就
Map<String,List<CompanyEntity>> mapData =
mainEntityList
.stream()
.collect(Collectors.groupingBy(MainEntity::getKeyWord,
Collectors.groupingBy(MainEntity::getCtr,
Collectors.averagingDouble(MainEntity::getCtr))))
.entrySet()
.stream()
.collect(Collectors.toMap(m -> m.getKey(),
m -> m.entrySet()
.stream()
.sorted(Comparator.comparing(e -> e.getValue()))
.map(e -> new CompanyEntity(e.getKey(), e.getValue()))
.collect(Collectors.toList())));发布于 2020-08-15 08:47:41
另一个答案在最初误解了问题后完全改变了它的答案,并且在良好的StackOverflow精神中它吸引了第一个向上的选票,所以现在被接受并且被最高的支持。但是在代码中还有几个步骤显示了正在发生的事情:
这会让你得到这样的结果:
import java.io.IOException;
import java.util.AbstractMap.SimpleEntry;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.Value;
public class CompanyEntityStackOverflowQuestion {
public static void main(String[] args) throws IOException {
//setup test data
MainEntity one = new MainEntity("key1", 10D, "company1");
MainEntity two = new MainEntity("key2", 5D, "company2");
MainEntity three = new MainEntity("key1", 7D, "company3");
MainEntity four = new MainEntity("key2", 3D, "company4");
List<MainEntity> mainEntityList = List.of(one, two, three, four);
//group list by keyword
Map<String, List<MainEntity>> mainEntityByKeyword = mainEntityList.stream()
.collect(Collectors.groupingBy(MainEntity::getKeyword));
//map to companyEntity object
Stream<SimpleEntry<String, List<CompanyEntity>>> mapped = mainEntityByKeyword.entrySet().stream()
.map(entry -> new SimpleEntry<>(entry.getKey(), entry.getValue().stream().map(
getCompanyListFunction()).collect(Collectors.toList())));
//sort and calculate average
Stream<SimpleEntry<String, CompanyEntityListWithStats>> mappedToListWithStats = mapped
.map(entry -> new SimpleEntry<>(entry.getKey(),
new CompanyEntityListWithStats(entry.getValue().stream().mapToDouble(company -> company.cost).average().orElse(0D), //or use Collectors.averagingDouble(company -> company.cost))
sortList(entry.getValue()))));
//collect back to map
Map<String, CompanyEntityListWithStats> collect = mappedToListWithStats
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
//show result
System.out.println(collect);
}
//sort by cost
private static List<CompanyEntity> sortList(List<CompanyEntity> list) {
list.sort(Comparator.comparing(company -> company.cost));
return list;
}
//map MainEntity to CompanyEntity
private static Function<MainEntity, CompanyEntity> getCompanyListFunction() {
return mainEntity -> new CompanyEntity(mainEntity.cost, mainEntity.company);
}
@Value
public static class MainEntity {
public String keyword;
public double cost;
public String company;
}
@Value
public static class CompanyEntity {
public double cost;
public String company;
}
@Value
public static class CompanyEntityListWithStats {
public double average;
public List<CompanyEntity> companyList;
}
}输出:{key1=CompanyEntityStackOverflowQuestion.CompanyEntityListWithStats(average=8.5, companyList=[CompanyEntityStackOverflowQuestion.CompanyEntity(cost=7.0, company=company3), CompanyEntityStackOverflowQuestion.CompanyEntity(cost=10.0, company=company1)]), key2=CompanyEntityStackOverflowQuestion.CompanyEntityListWithStats(average=4.0, companyList=[CompanyEntityStackOverflowQuestion.CompanyEntity(cost=3.0, company=company4), CompanyEntityStackOverflowQuestion.CompanyEntity(cost=5.0, company=company2)])}
您可能可以跳过一些步骤,这只是快速打印出来。当然,你可以用内嵌的东西来让它看起来更短/更干净,但是这种格式显示了正在发生的事情。
https://stackoverflow.com/questions/63423924
复制相似问题