标签: java-stream

如何将Java 8 Streams与InputStream一起使用?

我想换一个java.util.streams.Stream围绕InputStream处理一个字节或一次一个字符.我没有找到任何简单的方法来做到这一点.

请考虑以下练习:我们希望计算每个字母在文本文件中出现的次数.我们可以将它存储在一个数组中,以便tally[0]存储在文件中出现的次数,tally[1]存储出现的时间b等等.由于我找不到直接传输文件的方法,我这样做了:

 int[] tally = new int[26];
 Stream<String> lines = Files.lines(Path.get(aFile)).map(s -> s.toLowerCase());
 Consumer<String> charCount = new Consumer<String>() {
   public void accept(String t) {
      for(int i=0; i<t.length(); i++)
         if(Character.isLetter(t.charAt(i) )
            tall[t.charAt(i) - 'a' ]++;
   }
 };
 lines.forEach(charCount);
Run Code Online (Sandbox Code Playgroud)

有没有办法在不使用该lines方法的情况下完成此操作?我可以直接将每个字符作为Stream或Stream处理,而不是为文本文件中的每一行创建字符串.

我可以更直接地转换java.io.InputStream成java.util.Stream.stream?

java io java-8 java-stream

17
推荐指数
1
解决办法
2万
查看次数

java 8 - 流,地图和计数不同

我第一次尝试使用java 8流...

我有一个对象Bid,它代表用户对拍卖中项目的出价.我有一个出价列表,我想制作一张地图,其中包含用户出价的拍卖数量(不同).

这是我的看法:

bids.stream()
         .collect(
             Collectors.groupingBy(
                  bid ->  Bid::getBidderUserId, 
                  mapping(Bid::getAuctionId, Collectors.toSet())
             )
         ).entrySet().stream().collect(Collectors.toMap(
             e-> e.getKey(),e -> e.getValue().size())
        );
Run Code Online (Sandbox Code Playgroud)

它工作,但我觉得我在作弊,因为我流式传输地图的入口集,而不是在初始流上进行操作...必须是一个更正确的方式这样做,但我无法想象出来...

谢谢

java java-8 java-stream

17
推荐指数
1
解决办法
1万
查看次数

如何使用Java 8流将条件与条件分开

请考虑以下代码:

 List<Integer> odd = new ArrayList<Integer>();
 List<Integer> even = null;  
 List<Integer> myList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
 even = myList.stream()
              .filter(item -> {
                   if(item%2 == 0) { return true;}
                   else { 
                           odd.add(item); 
                           return false;
                   }
              })
              .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

我在这里要做的是将列表中的偶数和奇数值分别放入单独的列表中.

stream filter()方法返回true偶数项,流收集器将收集它们.
对于奇数情况,过滤器将返回false,项目将永远不会到达收集器.

所以我在else块之前创建的另一个列表中添加了这些奇数.

我知道这不是一种优雅的流式处理方式.例如,如果我使用并行流,那么奇数列表将出现线程安全问题.由于性能原因,我不能使用不同的过滤器多次运行它(应该是O(n)).

这只是一个用例的示例,列表可以包含任何对象,并且过滤器内的lambda需要根据某些逻辑将它们分离到单独的列表中.

简单来说:从列表中创建多个列表,其中包含基于某些条件分隔的项目.

如果没有流,只需运行for循环并执行简单的if-else并根据条件收集项目.

java data-structures java-8 java-stream

17
推荐指数
1
解决办法
6216
查看次数

Collection.stream()的实现

我已经在JDK 1.8上工作了几天,在那里我遇到了一些与此类似的代码:

List<Integer> list = Arrays.asList(1,2,3,4,5);
list.stream();
Run Code Online (Sandbox Code Playgroud)

现在,对于使用streams(java.util.stream)的人来说,它看起来既简单又干净,我找不到实现该java.util.Collection.stream()方法的实际类.

当我说list.stream():我有以下问题:

  1. 我java.util.stream.Stream从哪里得到的?
  2. 他们是如何实现它而不实际"扰乱"现有的集合?(假设他们没有触及它们)

我也尝试过的单证看java.util.AbstractCollection和java.util.AbstractList,但未能找到它.

java java-8 java-stream

17
推荐指数
4
解决办法
1838
查看次数

如何验证Java 8 Stream中有两个特定元素?

假设我已经List<Car>并且我想搜索该列表以验证我同时拥有思域和焦点.如果它是一个OR,它很容易,因为我可以在它上面应用OR .filter().请记住,我不能filter().filter()为这种类型的AND做.

一个有效的解决方案是:

boolean hasCivic = reportElements.stream()
        .filter(car -> "Civic".equals(car.getModel()))
        .findFirst()
        .isPresent();

boolean hasFocus = reportElements.stream()
        .filter(car -> "Focus".equals(car.getModel()))
        .findFirst()
        .isPresent();

return hasCivic && hasFocus;
Run Code Online (Sandbox Code Playgroud)

但后来我基本上处理了两次列表.我不能&&在过滤器中应用,也不能filter().filter().

有没有办法处理流一次,以查找列表是否包含思域和焦点汽车?

重要更新:提供的解决方案的关键问题是它们都保证O(n),而我的解决方案可以在两次比较后完成.如果我的汽车列表是1000万辆汽车,那么将会有非常显着的性能成本.然而,我的解决方案感觉不对,但也许这是性能最佳的解决方案......

java java-8 java-stream

17
推荐指数
1
解决办法
4351
查看次数

什么更有效:排序流或排序列表?

假设我们在集合中有一些项目,我们想要使用某个比较器对它们进行排序,期望列表中的结果:

Collection<Item> items = ...;
Comparator<Item> itemComparator = ...;
Run Code Online (Sandbox Code Playgroud)

其中一种方法是对列表中的项进行排序,例如:

List<Item> sortedItems = new ArrayList<>(items);
Collections.sort(sortedItems, itemComparator);
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用排序流:

List<Item> sortedItems = items
    .stream()
    .sorted(itemComparator)
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

我想知道,哪种方法更有效率?排序流是否有任何优点(如多核上的紧固排序)?

从运行时复杂性/速度的角度来看,效率很高.

我不相信自己能够实现一个完美的基准,学习SortedOps并没有真正启发我.

java arraylist java-8 java-stream

17
推荐指数
2
解决办法
3503
查看次数

如何使流减少线程安全?

Java 流 API 提供了一种通用.reduce(identity, accumulator)方法。

从 javadocs 中可以清楚地看出累加器应该是一个无状态函数。

但是,我有一个关于identity对象的问题,即它应该是线程安全的吗?

假设 anidentity是一个 java 对象,并且 anaccumulator以修改不是原子的方式修改该对象,例如accumulator查看identity's状态,然后决定如何准确地修改它的内部状态。很明显,可能会同时运行多个 reduce 操作。在这种情况下,会出现几个问题:

  • 这个减少操作应该在identity对象范围内是原子的吗?
  • 仅仅让identity对象不可变并在每次减少时返回一个新实例就足够了吗?

java multithreading java-stream

17
推荐指数
2
解决办法
415
查看次数

使用Java8 Streams创建另一个对象列表

我有以下Java6和Java8代码:

List<ObjectType1> lst1 = // a list of ObjectType1 objects
List<ObjectType2> lst2 = // a list of ObjectType1 objects, same size of lst1

List<ObjectType3> lst3 = new ArrayLis<ObjectType3>(lst1.size());
for(int i=0; i < lst1.size(); i++){
  lst3.add(new ObjectType3(lst1.get(i).getAVal(), lst2.get(i).getAnotherVal()));
}
Run Code Online (Sandbox Code Playgroud)

Java8中是否有任何方法可以使用Lambda以更简洁的方式处理上一个?

java lambda java-8 java-stream

16
推荐指数
2
解决办法
4万
查看次数

如何使用Java 8中的函数映射将Map <K,V1>转换为另一个Map <K,V2>?

我想使用Java 8中的函数映射将a转换Map<String, Integer>为另一个Map<String, Long>映射,在两个映射中将数据与按键匹配的函数进行匹配.您可以假设两个地图都具有相同的键.

我尝试了以下方法:

Map<String, Integer> inputData = new HashMap<>();
inputData.put("A",8);
inputData.put("B",7);
inputData.put("C",6);

Map<String, Function<Integer, Long>> transformers = new HashMap<>();
transformers.put("A", x -> x*2L);
transformers.put("B", x -> x+3L);
transformers.put("C", x -> x+11L);

Map<String, Long> mappedData = inputData.entrySet().stream()
    .map(entry -> new AbstractMap.SimpleEntry<>(
         entry.getKey(),
         transformers.get(entry.getKey()).apply(entry.getValue())))
    .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
Run Code Online (Sandbox Code Playgroud)

预期结果:{A = 16,B = 10,C = 17}.

在Java Streams API中是否有更简单的方法表达" 将变换器的映射应用于按键匹配的inputData映射 "?

java java-8 java-stream

16
推荐指数
1
解决办法
508
查看次数

使用Java 8流方法获取最后的最大值

给定一个具有属性的项目列表,我试图让最后一个项目显示所述属性的最大值.

例如,对于以下对象列表:

t  i
A: 3
D: 7 *
F: 4
C: 5
X: 7 *
M: 6
Run Code Online (Sandbox Code Playgroud)

我可以得到最高的东西之一i:

Thing t = items.stream()
        .max(Comparator.comparingLong(Thing::getI))
        .orElse(null);
Run Code Online (Sandbox Code Playgroud)

但是,这会得到我Thing t = D.是否有一种干净而优雅的方式来获取最后一项,即X在这种情况下?

一种可能的解决方案是使用该reduce功能.但是,该属性是动态计算的,它看起来更像是:

Thing t = items.stream()
        .reduce((left, right) -> {
            long leftValue = valueFunction.apply(left);
            long rightValue = valueFunction.apply(right);
            return leftValue > rightValue ? left : right;
        })
        .orElse(null);
Run Code Online (Sandbox Code Playgroud)

在valueFunction现在需要将近一倍,而调用.

其他明显的迂回解决方案是:

  1. 将对象存储在带有索引的元组中
  2. 将对象存储在具有计算值的元组中
  3. 事先颠倒列表
  4. 不要使用Streams

java java-8 java-stream

16
推荐指数
2
解决办法
1213
查看次数