lig*_*ght 6 java functional-programming java-stream
我试图仅使用功能性的编程构造(流,收集器,lambda表达式)来实现这一点。
假设list
是一个String[]
:
{"Apple", "Samsung", "LG", "Oppo", "Apple", "Huawei", "Oppo"}
Run Code Online (Sandbox Code Playgroud)
我想从此数组中打印出不同的品牌名称列表,并为其编号,即:
1. Apple
2. Huawei
3. LG
4. Oppo
5. Samsung
Run Code Online (Sandbox Code Playgroud)
我可以打印出独特的元素(排序):
Stream.of(list)
.distinct()
.sorted()
.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
但这没有显示前面的计数器。我尝试过,Collectors.counting()
但是那当然没有用。
FP专家有什么帮助吗?
编辑:我理解有关在带索引的流上进行迭代的其他一些问题。但是,我不能简单地做:
IntStream.range(0, list.length)
.mapToObj(a -> (a+1) + ". " + list[a])
.collect(Collectors.toList())
.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
因为原始数组包含重复元素。在打印结果之前,可能还会有其他情况,map
并且filter
可能需要在流上执行。
在 Holger\xe2\x80\x99s 评论后编辑:如果你只想要数组中遇到的顺序不同的品牌,你需要做的就是省略排序操作。
\n\n String[] list = {"Apple", "Samsung", "LG", "Oppo", "Apple", "Huawei", "Oppo"};\n Stream.of(list)\n .distinct()\n .forEach(System.out::println);\n
Run Code Online (Sandbox Code Playgroud)\n\n输出是:
\n\n\n\n\nRun Code Online (Sandbox Code Playgroud)\nApple\nSamsung\nLG\nOppo\nHuawei\n
正如 Holger 所说,如果流在操作之前遇到顺序(您的流具有),distinct
则保持遇到顺序。distinct
\n\n\n我实际上需要前面的计数器(1.2.3.4.5.)。
\n
我首选的方法是使用增强for
循环而不使用 lambda:
int counter = 0;\n for (String brand : new LinkedHashSet<>(Arrays.asList(list))) {\n counter++;\n System.out.println("" + counter + ". " + brand);\n }\n
Run Code Online (Sandbox Code Playgroud)\n\n输出是:
\n\n\n\n\nRun Code Online (Sandbox Code Playgroud)\n1. Apple\n2. Samsung\n3. LG\n4. Oppo\n5. Huawei\n
您的进一步评论:
\n\n\n\n\n我想知道什么是“理想的 FP”解决方案。
\n
我\xe2\x80\x99m 不一定相信存在任何好的纯函数式编程解决方案。我的尝试是受到链接的原始问题及其答案的启发:
\n\n List<String> distinctBrands\n = new ArrayList<>(new LinkedHashSet<>(Arrays.asList(list)));\n IntStream.range(0, distinctBrands.size())\n .mapToObj(index -> "" + (index + 1) + ". " + distinctBrands.get(index))\n .forEach(System.out::println);\n
Run Code Online (Sandbox Code Playgroud)\n\nALinkedHashSet
维护插入顺序并删除重复项。输出与之前相同。