我不熟悉Java 8:Streams
和Collectors
类。
我正在读取一个文件,其内容需要保存在LinkedHashMap<Integer, String>
中,其中<keys>
是文件的行号,而<values>
是每一行的内容。
在这里,我想使用Stream
的概念,但是我无法使用Collectors.toMap
自动递增<keys>
,需要将其保存在{{1}中}对象。取而代之的是,我得到了例外。
以下是我正在尝试的代码:
LinnkedHashMap
答案 0 :(得分:1)
您可以使用IntStream.range
:
IntStream.range(0, list.size())
.boxed()
.collect(Collectors.toMap(Function.identity(), i -> list.get(i)));
另一种选择是使用LineNumberReader
API。
答案 1 :(得分:0)
尝试此代码:
public static void main(String[] args) {
List<String> list = Arrays.asList("A", "B", "C");
list.forEach( System.out::println );
AtomicInteger i = new AtomicInteger(0);
Map<Integer, String> fileNumWithContentMapper = list.stream()
.collect( Collectors.toMap( n->i.incrementAndGet(),s1->s1));
System.out.println(fileNumWithContentMapper);
}
答案 2 :(得分:0)
有很多方法可以做到这一点。但是在这里我将解释我的方式:
IntStream
对象的大小。首先,只要您有List<E>
个对象(即E
可以是String
,Integers
,Objects
等),就可以对其进行转换使用Map<Integer, E>
类将其转换为IntStream
。此类是一系列原始整数值元素,它们支持顺序和并行聚合操作。这意味着就像一个巨大的柜台。如果我们已经有一个计数器,则需要设置一些限制,IntStream.range(int start, int end)
方法将为我们提供帮助。此方法将以1的增量步从IntStream
(包括)向start
(不包括)返回顺序的end
。因此,如果要使用我们IntStream
的大小使用以下方法:
List
List<Integer> numbers = Arrays.asList(4, 5, 4, 3);
IntStream stream = IntStream.range(0, numbers.size);
对象。现在,我们有一个您的Stream
大小的计数器,但是我们需要一个IntStream
。好了,现在我们将使用List<E>
。此方法返回一个Map<Integer, E>
,该元素由该流的元素组成,每个元素都装在IntStream.boxed()
中。这是Stream
。我们快完成了。
Integer
Stream<Integer>
对象转换为Stream<Integer> streamBoxed = stream.boxed();
对象最后,我们可以使用Stream
方法创建地图。此方法对该流的元素执行可变还原操作。如果没有Map
方法的帮助,这种减少将变得很复杂。该收集器可用于将Stream元素收集到Map实例中。为此,我们需要提供两个功能:Stream.collect()
和Collectors.toMap()
。 keyMapper
将用于从valueMapper
元素中提取keyMapper
键,Map
将被用于提取与给定{{ 1}}。对于我们的示例,我们将使用Stream
。 valueMapper
将是我们可以使用<value>
提取的<key>
流的值,而Map<Integer, Integer>
应该是我们将获得的keyMapper
列表的值像这样使用steamBoxed
的人:
i -> i
这三个部分可以通过以下简单代码组合在一起:
valueMapper
此外,您还会发现一些作者更喜欢将numbers
方法用作i -> numbers.get(i)
,而将Map<Integer, Integer> result = streamBoxed.collect(Collectors.toMap(i -> i, i -> numbers.get(i)))
lambda表达式用作List<Integer> numbers = Arrays.asList(4, 5, 4, 3);
Map<Integer, Integer> result = IntStream
.range(0, numbers.size); // IntStream
.boxed(); // Stream<Integer>
.collect(Collectors.toMap(i -> i, i -> numbers.get(i))) // Map<Integer, Integer>
。 他们为什么使用这些表达式? Function.identity()
方法将始终返回相同的实例。因此,使用keyMapper
代替numbers::get
可以节省一些内存。但是,valueMapper
比Function.identity()
更具可读性,但是因为创建自己的实例并具有不同的实现类会消耗更多的内存。 Function.identity()
lambda表达式只是方法参考捕获。
好吧,像这样:
i -> i
另类
i -> i
答案 3 :(得分:0)
假设您有List
,如下所示:
List<String> list = Arrays.asList("Vishwa","Ram","Mohan","Sohan");
现在您要输出,如以下:
0 Vishwa
1 Ram
2 Mohan
3 Sohan
public class Someclass{
static int j=0;
static int count(int de){
return de++;
}
public static void main(String[] args) {
List<String> list = Arrays.asList("Vishwa","Ram","Mohan","Sohan");
Map<Integer,String> map;
map = list.stream().collect(Collectors.toMap(s->{count(j);return j++;}, Function.identity()));
map.forEach((k,v)-> {
System.out.print(k+" ");
System.out.println(v);
});
}
}
答案 4 :(得分:0)
SELECT users.name, messages.message
FROM users, messages
WHERE messages.from_id = 1 OR messages.to_id = 1
GROUP BY ??
ORDER BY messages.id DESC
打印:
Stream.of("A", "B", "C").collect(TreeMap<Integer, String>::new
,(map, element) -> map.put(Optional.ofNullable(map.lastEntry()).map(e -> e.getKey() + 1).orElse(1), element)
,(m1, m2) -> {})
.forEach((i, e) -> System.out.println(i + " " + e));