有一个java类:
public class Test {
private Integer parentId;
private Integer systemId;
private Integer id;
private Integer weight;
//With their setter and getter
}
并且有一个Test类(List<Test>
)的集合,其数据如下:
parentId systemId id weight
------------------------------------------
10 100 1 200
10 100 2 300
10 300 3 400
20 400 4 200
20 400 5 600
20 500 6 6
20 500 7 4
我想通过parentId和systemId进行分组,分组的结果是List不是Map。
分组后,列表内容将为:
parentId systemId weight
---------------------------------
10 100 500
10 300 400
20 400 800
20 500 10
分组结果List
不是Map
答案 0 :(得分:0)
就像这样。您可以将<?php
header("Access-Control-Allow-Origin: *");
if(isset($_SERVER['HTTP_ORIGIN']))
{
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day
}
//Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS')
{
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers:
{$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
exit(0);
}
$con = mysqli_connect("localhost","root","upload","ampache");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$postdata = file_get_contents("php://input");
if(isset($postdata))
{
$request = json_decode($postdata);
$name = $request->testname;
$id = $request->testid;
$file = $request->testfile;
$filename = basename("c:\fakepath\ $file");
echo $filename;
$artist_name = $request->testartist;
$catalog = 1;
$enabled = 1;
$channels = 2;
$update_time = 0;
$user_upload = 1;
$bitrate = 192000;
$rate = 44100;
$mode = "cbr";
$filepath = 'C:\\\xampp\\\htdocs\\\ampache-3.8.6_all\\\songs\\\admin\\\
';
$audiopath = $filepath.$artist_name."/".$name."\\\ ".$filename;
$path = mkdir("C:/xampp/htdocs/ampache-3.8.6_all/songs/admin/" .
$artist_name . "/" . $name. "/", 0700);
if($name != "" && $id != "")
{
$con = mysqli_connect("localhost","root","upload","ampache");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
else
{
//echo "Name: " .$name;
//echo "id: " .$id;
//$sql = "INSERT INTO album(name, album_artist) VALUES
// ('$name', '$id')";
$sql = "INSERT INTO album(name, album_artist) VALUES ('$name',
'$id')";
$stmt = mysqli_query($con, $sql) or die ("MySQL
Error:".mysqli_error($con));
echo "successfully inserted !";
}
$lastid = mysqli_insert_id($con);
$sql1 = "INSERT INTO song(catalog, enabled, channels, update_time,
user_upload, mode, bitrate, rate, artist, album, title, file) VALUES
('$catalog', '$enabled', '$channels', '$update_time', '$user_upload',
'$mode', '$bitrate', '$rate', '$id', '$lastid', '$filename',
'$audiopath')";
$stmt1 = mysqli_query($con, $sql1) or die ("MySQL
Error:".mysqli_error($con));
}
else
{
echo "Empty name and description parameter!";
}
}
else
{
echo "Not called properly with name and description parameter!";
}
?>
与合并功能结合使用。
toMap
然后将其转换为HashMap<Pair<Integer, Integer>, Integer> map = list.stream()
.collect(Collectors
.toMap(item -> new Pair<>(item.parentId, item.systemId),
item -> item.weight, Integer::sum, LinkedHashMap::new));
列表。
Test(Integer parentId, Integer systemId, Integer weight)
答案 1 :(得分:0)
这应该这样做,
Map<Integer, Map<Integer, List<Test>>> groupMap = test.stream()
.collect(Collectors.groupingBy(Test::getParentId, Collectors.groupingBy(Test::getSystemId)));
List<Test> orderedObjects = groupMap.entrySet().stream()
.flatMap(e -> e.getValue().entrySet().stream()
.map(mp -> mp.getValue().stream().reduce((t1, t2) -> new Test(t1.getParentId(),
t1.getSystemId(), t1.getId(), t1.getWeight() + t2.getWeight())).orElse(null)))
.collect(Collectors.toList());
答案 2 :(得分:0)
没有明确需要首先以Map
的形式获得结果,然后转换为List
。
这是直接返回List
的解决方案。关键的想法是将具有相同Test
和parentId
的所有systemId
对象减少到包含Test
字段总和的结果weight
对象。 / p>
但是,您必须覆盖equals()
类的hashCode()
和Test
方法。
以下是解决方案:
inputList = new ArrayList<>(
Arrays.asList(
new Test(10, 100, 1, 200),
new Test(10, 100, 2, 300),
new Test(10, 300, 3, 400),
new Test(20, 400, 4, 200),
new Test(20, 400, 5, 600),
new Test(20, 500, 6, 6),
new Test(20, 500, 7, 4)
)
);
BinaryOperator<Test> accumulator = (d1, d2) ->
new Test(d1.getParentId(), d1.getSystemId(), d1.getWeight() + d2.getWeight());
List<Test> resultList = inputList.stream()
.map(test1 -> inputList.stream()
.filter(test2 -> !(test1.getId().equals(test2.getId())) && test1.getParentId().equals(test2.getParentId()) && test1.getSystemId().equals(test2.getSystemId()))
.reduce(new Test(test1.getParentId(), test1.getSystemId(), test1.getWeight()), accumulator)
)
.distinct()
.collect(Collectors.toList());
equals()
类的被覆盖的hashCode()
和Test
方法(仅供参考):
@Override
public boolean equals(Object obj){
if(obj == null)
return false;
Test d2 = (Test)obj;
if (parentId.equals(d2.getParentId()) && systemId.equals(d2.getSystemId()) && weight.equals(d2.getWeight())) {
if (id != null) {
if (id.equals(d2.getId())) {
return true;
} else{
return false;
}
}
return true;
}
return false;
}
@Override
public int hashCode() {
int hash = 7;
hash = 71 * hash + Objects.hashCode(this.parentId);
hash = 71 * hash + Objects.hashCode(this.systemId);
hash = 71 * hash + Objects.hashCode(this.weight);
return hash;
}
我没有在id
方法中使用equals()
字段,因为在所需的输出中省略了该字段。
答案 3 :(得分:0)
混合溶液怎么样?您可以在 @Ravindra Ranwala 答案中找到Stream
解决方案。它有效,但我认为这对于实现和支持来说有点复杂。我提供了另一种解决方案,对我来说更清楚。
这是将List<Test>
合并到Test
的功能。我认为将其与组逻辑分开是更清楚的。这次它只是对给定列表中的所有weight
求和。您可以在此处添加更多字段。
Function<List<Test>, Test> merge = notEmptyGroup -> {
Test test = notEmptyGroup.iterator().next();
int weight = notEmptyGroup.stream().map(Test::getWeight).mapToInt(w -> w).sum();
return new Test(test.getParentId(), test.getSystemId(), weight);
};
这是分组方法。这只是组逻辑和merge
函数,它接受要合并的一个组中的所有Test
。
public static List<Test> groupByParentIdAndSystemId(List<Test> tests, Function<List<Test>, Test> merge) {
List<Test> results = new LinkedList<>();
Map<Integer, Map<Integer, List<Test>>> map = tests.stream().collect(Collectors.groupingBy(Test::getParentId,
Collectors.groupingBy(Test::getSystemId)));
map.values().forEach(parentTests ->
parentTests.values().forEach(systemTests ->
results.add(merge.apply(systemTests))));
results.sort(Comparator.comparingInt(Test::getParentId).thenComparingInt(Test::getSystemId));
return results;
}
这是客户端代码:
List<Test> res = groupByParentIdAndSystemId(tests, merge);
答案 4 :(得分:0)
com.google.android.material.bottomappbar.BottomAppBar
android.support.design.bottomappbar.BottomAppBar
结果
Map<Integer, Map<Integer, Integer>> groupped = input.stream()
.collect(Collectors.groupingBy(Test::getParentId,Collectors.groupingBy(Test::getSystemId,Collectors.summingInt(Test::getWeight))));
Stream<List<Test>> stream = groupped.entrySet().stream().map(grouppedEntry -> {
Integer parentId = grouppedEntry.getKey();
return grouppedEntry
.getValue().entrySet().stream().map(systemIdAndSummedWeight -> new Test(parentId,
systemIdAndSummedWeight.getKey(), systemIdAndSummedWeight.getValue()))
.collect(Collectors.toList());
});
List<Test> result = stream.flatMap(List::stream).sorted(
Comparator.comparing(Test::getParentId).thenComparing(Comparator.comparing(Test::getSystemId)))
.collect(Collectors.toList());