Java 字符串列表列表
Java list of list of String
我有版本列表(字符串),我想为每个版本制作列表列表
List<List<String>> releases = new ArrayList<List<String>>();
def list = ["7.5.9", "7.5.8", "7.5.7", "7.5.6", "7.5.5", "7.5.4", "7.5.3", "7.5.2", "7.5.1", "7.5.0", "6.5.1", "6.5.0"];
我想收集每个版本
第一个版本列表 1.0.0, 1.0.1, 1.0.2,
第二个版本列表 1.5.0, 1.5.1
版本 2.0.0 的第三个列表......每个版本依此类推
使用流:
List<List<String>> versions =
list.stream()
.collect(Collectors.groupingBy(/* a function which extracts the version */))
.values() /* gives you a Collection<List<String>>, stop here if you don't need it as an actual List */
.stream()
.collect(Collectors.toList());
显示值的“提取版本的函数”示例可以是:
value -> value.substring(0, value.lastIndexOf('.'))
由于发布版本有两位数字,输入列表可以使用 Collectors.groupingBy
按前缀分组(从而得到 String, List<String>
的映射),然后使用 Collectors.groupingBy
对版本列表进行排序Collectors.collectingAndThen
:
List<List<String>> versions = new ArrayList<>(
list
.stream()
.collect(Collectors.groupingBy(
str -> str.substring(0, str.lastIndexOf('.')),
Collectors.collectingAndThen(
Collectors.toList(),
(List<String> lst) -> { lst.sort(String::compareTo); return lst; }
)
))
.values() // Collection<List<String>>
);
versions.forEach(System.out::println);
输出:
[1.0.0, 1.0.1, 1.0.2]
[2.0.0]
[3.0.0, 3.0.1]
[1.5.0, 1.5.1]
[2.5.0]
[3.5.0]
以上代码假定版本中发布部分的格式始终至少有两个点(主要版本和次要版本)。
如果某些版本可能不符合初始格式(例如,有0.1
或1.0.2.1
),以下分组条件应该可以正常工作:
str -> str.substring(0, str.indexOf('.', str.indexOf('.') + 1) + 1),
- 假定发布前缀包含至少 1 个点 .
和最多两个点。
示例 Groovy 实施:
def list = ["3.5.0", "3.0.1", "3.0.0", "2.5.0", "2.0.0", "1.5.1", "1.5.0", "1.0.2", "1.0.1", "1.0.0"]
def versions = new ArrayList<> (list.groupBy {
it.substring(0, it.lastIndexOf('.'))
}.values())
.each { it.sort() }
versions.each {println it }
输出:
[3.5.0]
[3.0.0, 3.0.1]
[2.5.0]
[2.0.0]
[1.5.0, 1.5.1]
[1.0.0, 1.0.1, 1.0.2]
更新
以下 Groovy 代码修复了排序问题并删除了最高版本和空结果:
def list = ["3.5.0", "3.0.1", "3.0.0", "2.5.0", "2.0.0", "1.5.1", "1.5.0", "1.0.1", "1.0.0",
"1.0.10", "1.0.11", "1.0.2", "1.0.3", "1.0.4", "1.0.5", "1.0.6", "1.0.7", "1.0.8", "1.0.9"]
def versions = new ArrayList<> (
list
.sort() // sort initial list
.groupBy {
it.substring(0, it.lastIndexOf('.'))
}.values()
)
.each { it.sort{ a,b -> Integer.compare(
Integer.parseInt(a.substring(a.lastIndexOf('.') + 1)),
Integer.parseInt(b.substring(b.lastIndexOf('.') + 1))
)}.removeAt(it.size() - 1) }
versions.removeIf { it.empty } // remove empty sublists if any found
versions.each {println it }
输出
[1.0.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4, 1.0.5, 1.0.6, 1.0.7, 1.0.8, 1.0.9, 1.0.10]
[1.5.0]
[3.0.0]
试试这个。
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("3.5.0");
list.add("3.0.1");
list.add("3.0.0");
list.add("2.5.0");
list.add("2.0.0");
list.add("1.5.1");
list.add("1.5.0");
list.add("1.0.2");
list.add("1.0.1");
list.add("1.0.0");
Collections.sort(list);
Map<String, List<String>> map = new TreeMap<>();
for (String e : list)
map.computeIfAbsent(e.replaceFirst("\.\d+$", ""), k -> new ArrayList<>()).add(e);
List<List<String>> releases = new ArrayList<>(map.values());
System.out.println(releases);
}
输出:
[[1.0.0, 1.0.1, 1.0.2], [1.5.0, 1.5.1], [2.0.0], [2.5.0], [3.0.0, 3.0.1], [3.5.0]]
下面是一个纯粹惯用的 Groovy 版本 w/o Java 流和其他奇怪的结构:
def list = ["7.5.9", "7.5.8", "7.5.7", "7.5.6", "7.5.5", "7.5.4", "7.5.3", "7.5.2", "7.5.1", "7.5.0", "6.5.1", "6.5.0"]
def collector = {
List asInts = it.split( /\./ )*.toInteger()
[ sum:asInts.reverse().withIndex().collect{ v, ix -> 10.power( ix ) * v }.sum(), major:asInts[ 0 ], original:it ]
}
def listOfSublists = list.collect collector sort{ it.sum } groupBy{ it.major } values()*.collect{ it.original }
assert listOfSublists.toString() == '[[6.5.0, 6.5.1], [7.5.0, 7.5.1, 7.5.2, 7.5.3, 7.5.4, 7.5.5, 7.5.6, 7.5.7, 7.5.8, 7.5.9]]'
我有版本列表(字符串),我想为每个版本制作列表列表
List<List<String>> releases = new ArrayList<List<String>>();
def list = ["7.5.9", "7.5.8", "7.5.7", "7.5.6", "7.5.5", "7.5.4", "7.5.3", "7.5.2", "7.5.1", "7.5.0", "6.5.1", "6.5.0"];
我想收集每个版本 第一个版本列表 1.0.0, 1.0.1, 1.0.2, 第二个版本列表 1.5.0, 1.5.1 版本 2.0.0 的第三个列表......每个版本依此类推
使用流:
List<List<String>> versions =
list.stream()
.collect(Collectors.groupingBy(/* a function which extracts the version */))
.values() /* gives you a Collection<List<String>>, stop here if you don't need it as an actual List */
.stream()
.collect(Collectors.toList());
显示值的“提取版本的函数”示例可以是:
value -> value.substring(0, value.lastIndexOf('.'))
由于发布版本有两位数字,输入列表可以使用 Collectors.groupingBy
按前缀分组(从而得到 String, List<String>
的映射),然后使用 Collectors.groupingBy
对版本列表进行排序Collectors.collectingAndThen
:
List<List<String>> versions = new ArrayList<>(
list
.stream()
.collect(Collectors.groupingBy(
str -> str.substring(0, str.lastIndexOf('.')),
Collectors.collectingAndThen(
Collectors.toList(),
(List<String> lst) -> { lst.sort(String::compareTo); return lst; }
)
))
.values() // Collection<List<String>>
);
versions.forEach(System.out::println);
输出:
[1.0.0, 1.0.1, 1.0.2]
[2.0.0]
[3.0.0, 3.0.1]
[1.5.0, 1.5.1]
[2.5.0]
[3.5.0]
以上代码假定版本中发布部分的格式始终至少有两个点(主要版本和次要版本)。
如果某些版本可能不符合初始格式(例如,有0.1
或1.0.2.1
),以下分组条件应该可以正常工作:
str -> str.substring(0, str.indexOf('.', str.indexOf('.') + 1) + 1),
- 假定发布前缀包含至少 1 个点 .
和最多两个点。
示例 Groovy 实施:
def list = ["3.5.0", "3.0.1", "3.0.0", "2.5.0", "2.0.0", "1.5.1", "1.5.0", "1.0.2", "1.0.1", "1.0.0"]
def versions = new ArrayList<> (list.groupBy {
it.substring(0, it.lastIndexOf('.'))
}.values())
.each { it.sort() }
versions.each {println it }
输出:
[3.5.0]
[3.0.0, 3.0.1]
[2.5.0]
[2.0.0]
[1.5.0, 1.5.1]
[1.0.0, 1.0.1, 1.0.2]
更新
以下 Groovy 代码修复了排序问题并删除了最高版本和空结果:
def list = ["3.5.0", "3.0.1", "3.0.0", "2.5.0", "2.0.0", "1.5.1", "1.5.0", "1.0.1", "1.0.0",
"1.0.10", "1.0.11", "1.0.2", "1.0.3", "1.0.4", "1.0.5", "1.0.6", "1.0.7", "1.0.8", "1.0.9"]
def versions = new ArrayList<> (
list
.sort() // sort initial list
.groupBy {
it.substring(0, it.lastIndexOf('.'))
}.values()
)
.each { it.sort{ a,b -> Integer.compare(
Integer.parseInt(a.substring(a.lastIndexOf('.') + 1)),
Integer.parseInt(b.substring(b.lastIndexOf('.') + 1))
)}.removeAt(it.size() - 1) }
versions.removeIf { it.empty } // remove empty sublists if any found
versions.each {println it }
输出
[1.0.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4, 1.0.5, 1.0.6, 1.0.7, 1.0.8, 1.0.9, 1.0.10]
[1.5.0]
[3.0.0]
试试这个。
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("3.5.0");
list.add("3.0.1");
list.add("3.0.0");
list.add("2.5.0");
list.add("2.0.0");
list.add("1.5.1");
list.add("1.5.0");
list.add("1.0.2");
list.add("1.0.1");
list.add("1.0.0");
Collections.sort(list);
Map<String, List<String>> map = new TreeMap<>();
for (String e : list)
map.computeIfAbsent(e.replaceFirst("\.\d+$", ""), k -> new ArrayList<>()).add(e);
List<List<String>> releases = new ArrayList<>(map.values());
System.out.println(releases);
}
输出:
[[1.0.0, 1.0.1, 1.0.2], [1.5.0, 1.5.1], [2.0.0], [2.5.0], [3.0.0, 3.0.1], [3.5.0]]
下面是一个纯粹惯用的 Groovy 版本 w/o Java 流和其他奇怪的结构:
def list = ["7.5.9", "7.5.8", "7.5.7", "7.5.6", "7.5.5", "7.5.4", "7.5.3", "7.5.2", "7.5.1", "7.5.0", "6.5.1", "6.5.0"]
def collector = {
List asInts = it.split( /\./ )*.toInteger()
[ sum:asInts.reverse().withIndex().collect{ v, ix -> 10.power( ix ) * v }.sum(), major:asInts[ 0 ], original:it ]
}
def listOfSublists = list.collect collector sort{ it.sum } groupBy{ it.major } values()*.collect{ it.original }
assert listOfSublists.toString() == '[[6.5.0, 6.5.1], [7.5.0, 7.5.1, 7.5.2, 7.5.3, 7.5.4, 7.5.5, 7.5.6, 7.5.7, 7.5.8, 7.5.9]]'