1. 数据初始化
这一部分代码用于创建 Product
对象并将它们添加到 result
列表中。
java
// 初始化数据
List<Product> result = new ArrayList<>();
List<Product> resp = new ArrayList<>();
// 添加产品数据
result.add(new Product("手机A", 1500, "电子", 3, 5));
result.add(new Product("手机B", 1600, "电子", 3, 5));
result.add(new Product("手机C", 1800, "电子", 3, 5));
result.add(new Product("电脑A", 13000, "电子", 3, 6));
result.add(new Product("电脑B", 15000, "电子", 3, 6));
result.add(new Product("电脑C", 18000, "电子", 3, 6));
result.add(new Product("床C", 7000, "家具", 1, 4));
result.add(new Product("椅子A", 500, "家具", 1, 3));
result.add(new Product("椅子B", 400, "家具", 1, 3));
result.add(new Product("椅子C", 300, "家具", 1, 3));
result.add(new Product("牙膏A", 15, "洗护", 2, 1));
result.add(new Product("牙膏B", 25, "洗护", 2, 1));
result.add(new Product("牙膏C", 18, "洗护", 2, 1));
result.add(new Product("洗面奶A", 60, "洗护", 2, 2));
result.add(new Product("洗面奶B", 70, "洗护", 2, 2));
result.add(new Product("洗面奶C", 80, "洗护", 2, 2));
说明
Product
类 :表示一个产品对象,包含以下属性:name
:产品名称。price
:产品价格。type
:产品类型(如电子、家具、洗护)。seq0
和seq1
:排序辅助字段。
result
列表:存储所有产品对象。resp
列表:用于存储最终输出的结果。
2. 按价格排序并分组
这一部分代码对 result
列表中的产品按价格排序后,按 type
字段分组。
java
// 按价格排序并分组
Map<String, List<Product>> collect = result.stream()
.sorted(Comparator.comparing(Product::getPrice)) // 按价格升序排序
.collect(Collectors.groupingBy(
Product::getType, // 按类型分组
LinkedHashMap::new, // 保持分组顺序
Collectors.toList() // 分组后每组存为 List
));
说明
- 排序 :使用
Comparator.comparing(Product::getPrice)
对产品按价格升序排序。 - 分组 :使用
Collectors.groupingBy
按type
字段分组。 - 结果 :
collect
是一个Map
,键为产品类型(如 "电子"、"家具"),值为对应类型的产品列表。
3. 对分组后的数据排序
这一部分代码对每个分组内的产品列表进行排序,先按 seq1
正序,再按价格倒序。
java
// 对分组后的数据按 seq1 正序和价格倒序排序
Map<String, List<Product>> sortedCollect = result.stream()
.collect(Collectors.groupingBy(
Product::getType, // 按类型分组
LinkedHashMap::new, // 保持分组顺序
Collectors.collectingAndThen(
Collectors.toList(), // 先收集到 List
list -> list.stream()
.sorted(Comparator.comparing(Product::getPrice).reversed()) // 价格倒序
.sorted(Comparator.comparing(Product::getSeq1)) // seq1 正序
.collect(Collectors.toList()) // 排序后收集为 List
)
));
说明
- 分组 :与上一步类似,按
type
字段分组。 - 排序逻辑 :
- 价格倒序 :
Comparator.comparing(Product::getPrice).reversed()
。 seq1
正序 :Comparator.comparing(Product::getSeq1)
。- 排序优先级 :先按
seq1
排序,再按价格排序。
- 价格倒序 :
- 结果 :
sortedCollect
是一个Map
,每个分组内的产品列表已按上述规则排序。
4. 对分组的键排序
这一部分代码对分组的键(即产品类型)按字典序排序。
java
// 对分组后的 key 进行排序
Map<String, List<Product>> sortedMap2 = sortedCollect.entrySet().stream()
.sorted(Map.Entry.comparingByKey()) // 按键(类型)排序
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(oldVal, newVal) -> oldVal,
LinkedHashMap::new // 保持插入顺序
));
说明
- 排序逻辑 :
Map.Entry.comparingByKey()
按键(类型)字典序排序。 - 结果 :
sortedMap2
是一个按类型排序的Map
,每个分组内的产品列表已按规则排序。
5. 按顺序取出每组的第 i 个元素
这一部分代码从每个分组中依次取出第 i
个元素,直到所有元素都被取出。
java
// 遍历分组数据,按顺序取出每组的第 i 个元素
int index = 0;
boolean done = false;
while (!done) {
done = true;
for (String key : sortedMap2.keySet()) {
List<Product> group = sortedMap2.get(key);
if (index < group.size()) {
String name = sortedMap2.get(key).get(index).name;
System.out.println("name: " + name);
resp.add(group.get(index)); // 添加到结果列表
done = false; // 如果还有未取出的元素,继续循环
}
}
index++;
}
说明
- 逻辑 :
- 遍历每个分组,取出第
index
个元素。 - 如果某个分组的元素已取完,则跳过。
- 当所有分组的元素都取完时,退出循环。
- 遍历每个分组,取出第
- 结果 :
resp
列表按顺序存储所有产品。
6. 按每组的第 i 个元素重新排序
这一部分代码实现了另一种遍历方式,按每组的第 i
个元素重新排序。
java
// 计算每组的最大长度
int count = 0;
for (String key : sortedMap2.keySet()) {
count = Math.max(count, sortedMap2.get(key).size());
}
// 按每组的第 i 个元素重新排序
int j = 0;
for (int i = 0; i < count; i++) {
for (String key : sortedMap2.keySet()) {
if (i >= sortedMap2.get(key).size()) {
continue; // 跳过超出范围的元素
}
String name = sortedMap2.get(key).get(i).name;
System.out.println("name: " + name);
resp.add(j, sortedMap2.get(key).get(i)); // 插入到结果列表
j++;
}
}
说明
- 逻辑 :
- 计算每组的最大长度
count
。 - 遍历每组的第
i
个元素,按顺序插入到resp
列表中。
- 计算每组的最大长度
- 结果 :
resp
列表存储按每组第i
个元素排序的结果。
7. 产品类定义
Product
类是代码的核心数据结构,定义如下:
java
static class Product {
String name;
int price;
String type;
int seq0;
int seq1;
public Product(String name, int price, String type, int seq0, int seq1) {
this.name = name;
this.price = price;
this.type = type;
this.seq0 = seq0;
this.seq1 = seq1;
}
public String getName() {
return name;
}
public int getPrice() {
return price;
}
public String getType() {
return type;
}
public int getSeq0() {
return seq0;
}
public int getSeq1() {
return seq1;
}
}
总结
通过拆分代码,我们可以清晰地看到每个部分的功能:
- 数据初始化。
- 按价格排序并分组。
- 对分组内的产品排序。
- 对分组的键排序。
- 按顺序取出每组的第
i
个元素。 - 按每组的第
i
个元素重新排序。
如果需要进一步优化或补充说明,请随时告知!