小编Vit*_*liy的帖子

为什么Java Streams一次性关闭?

与C#不同IEnumerable,执行管道可以根据需要执行多次,在Java中,流只能"迭代"一次.

对终端操作的任何调用都会关闭流,使其无法使用.这个"功能"消耗了很多力量.

我想这个的原因不是技术性的.这个奇怪限制背后的设计考虑是什么?

编辑:为了演示我在说什么,请考虑以下C#中的Quick-Sort实现:

IEnumerable<int> QuickSort(IEnumerable<int> ints)
{
  if (!ints.Any()) {
    return Enumerable.Empty<int>();
  }

  int pivot = ints.First();

  IEnumerable<int> lt = ints.Where(i => i < pivot);
  IEnumerable<int> gt = ints.Where(i => i > pivot);

  return QuickSort(lt).Concat(new int[] { pivot }).Concat(QuickSort(gt));
}
Run Code Online (Sandbox Code Playgroud)

现在可以肯定的是,我并不是说这是一个很好的快速排序!然而,它是lambda表达式与流操作相结合的表达能力的一个很好的例子.

它不能用Java完成!我甚至无法询问流是否为空而不使其无法使用.

java api-design java-8 java-stream

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

为什么Stream.limit在此代码段中没有按预期工作?

List<Integer> integer = Stream.generate(new Supplier<Integer>() {
    int i = 0 ;

    @Override
    public Integer get() {
        return ++i;
    }
}).filter(j -> j < 5)
  .limit(10)   // Note the call to limit here
  .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

与我的期望相反,collect呼叫永远不会回来.设置limit之前filter产生预期结果.为什么?

java java-8 java-stream

34
推荐指数
4
解决办法
1324
查看次数

为什么原始Stream没有收集(收藏家)?

我正在为新手程序员编写一个库,所以我试图保持API尽可能干净.

我的库需要做的一件事就是对大量的int或long进行一些复杂的计算.我的用户需要从中计算这些值所需的大量场景和业务对象,因此我认为最好的方法是使用流来允许用户将业务对象映射到IntStream或者LongStream然后计算收集器内的计算.

但是IntStream和LongStream只有3参数collect方法:

collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R,R> combiner)
Run Code Online (Sandbox Code Playgroud)

而且没有简单的collect(Collector)方法Stream<T>.

所以不是能够做到的

Collection<T> businessObjs = ...
MyResult result = businessObjs.stream()
                              .mapToInt( ... )
                              .collect( new MyComplexComputation(...));
Run Code Online (Sandbox Code Playgroud)

我必须提供像这样的供应商,蓄电池和组合器:

MyResult result = businessObjs.stream()
                              .mapToInt( ... )
                              .collect( 
                                  ()-> new MyComplexComputationBuilder(...),
                                  (builder, v)-> builder.add(v),
                                  (a,b)-> a.merge(b))
                              .build(); //prev collect returns Builder object
Run Code Online (Sandbox Code Playgroud)

对于我的新手用户来说这太复杂了,而且非常容易出错.

我的工作是创建一个静态方法,它接受IntStreamLongStream作为输入,并为您隐藏收集器的创建和执行

public static MyResult compute(IntStream stream, ...){
       return .collect( 
                        ()-> new MyComplexComputationBuilder(...),
                        (builder, v)-> builder.add(v),
                        (a,b)-> a.merge(b))
               .build();
} …
Run Code Online (Sandbox Code Playgroud)

java api-design java-8 java-stream

30
推荐指数
2
解决办法
4811
查看次数

为什么我们不能在枚举其键时更改字典的值?

class Program
    {
        static void Main(string[] args)
        {
            var dictionary = new Dictionary<string, int>()
            {
                {"1", 1}, {"2", 2}, {"3", 3}
            };

            foreach (var s in dictionary.Keys)
            {
                // Throws the "Collection was modified exception..." on the next iteration
                // What's up with that?

                dictionary[s] = 1;  

            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我完全理解为什么在枚举列表时抛出此异常 - 在枚举期间,枚举对象的结构不会改变似乎是合理的.但是,更改字典的值会改变其结构吗?具体来说,其键的结构?

c# dictionary enumeration invalidoperationexception

26
推荐指数
5
解决办法
9572
查看次数

如何配置pom来运行jar中打包的测试?

我有一个maven构建过程,可以将可执行jar及其测试发布到Nexus.我有另一个maven构建过程需要访问这些jar(可执行文件+测试)并运行测试.

我该怎么办呢?到目前为止,只有当jar被分解为类文件时,我才设法做到这一点.我是maven的新手,完全迷失在文档中.

unit-testing jar maven

15
推荐指数
2
解决办法
9888
查看次数

为什么YAML规范在结肠后要求空间?

YAML规范明确规定:

映射使用冒号和空格(":")来标记每个键:值对.

所以这是合法的:

foo: bar
Run Code Online (Sandbox Code Playgroud)

但是,这不是:

foo:bar
Run Code Online (Sandbox Code Playgroud)

我看到网上有很多人在讨论这个空间.我认为他们有一个观点.我自己被它烧了几次.

为什么空间是强制性的?它背后的设计考虑是什么?

yaml language-design

14
推荐指数
1
解决办法
1903
查看次数

迭代DirectoryStream并同时更改目录的内容

DirectoryStream的文档明确指出:

迭代器非常一致.它是线程安全的,但在迭代时不会冻结目录,因此它可能(或可能不)反映在创建DirectoryStream之后发生的目录的更新.

在我的机器上,我在调试模式下对目录执行了一个简单的迭代.在迭代完成之前,我打破了执行,将文件添加到正在迭代的目录并重新开始.迭代没有看到额外的文件.

我的问题:在什么情况下迭代反映更新的目录内容?不幸的是,正式文件对此非常模糊.至少可以说.

java file-io directory-structure java-7

10
推荐指数
1
解决办法
329
查看次数

在jdk7监视服务API中,什么时候会抛出OVERFLOW事件?

对溢出文件规定:

OVERFLOW - 表示事件可能已丢失或丢弃.

它没有说在什么情况下我应该期望事件丢失或丢弃?起初我以为这是将很多文件写入文件夹的结果.我创建了几千个零大小的文件,并将它们移动到受监控的目录.没有溢出.

我错过了什么?

java io java-7 nio2

7
推荐指数
3
解决办法
3820
查看次数

垃圾收集中的疏散和压实之间的根本区别是什么?

我已经阅读了大量有关Java SE 6和7的HotSpot GC的文档.在谈到获得自由记忆的连续区域的策略时,提出了两种"竞争"方法:疏散方法(通常应用于年轻一代) ),将活动对象从"从"复制到空'到'和压缩(CMS的后退),其中活动对象移动到碎片区域内的一侧,形成一个连续的未使用块记忆.

两种方法都与"实时集"的大小成比例.不同之处在于疏散需要x2倍的空间,而实际集合则不需要压缩.

为什么我们需要撤离技术呢?需要完成的复制量是相同的,但是它需要保留更多的堆大小,并且不允许更快地重新映射引用.

是的:疏散可以并行执行(其中 - 压缩不能,或者至少不那么容易),但这个特性从未被提及过,并且看起来并不那么重要(考虑到重新映射比移动要昂贵得多).

java garbage-collection

7
推荐指数
1
解决办法
413
查看次数

为什么Collection <T>实现Stream <T>?

这是关于API设计的问题.在C#中添加扩展方法时,获取IEnumerable所有在所有集合上直接使用lambda表达式的方法.

随着Java中lambdas和默认方法的出现,我希望Collection能够实现Stream并为其所有方法提供默认实现.这样,我们就不需要调用stream()它来利用它提供的功率.

图书馆建筑师选择不太方便的方法的原因是什么?

java lambda api-design java-8

7
推荐指数
1
解决办法
339
查看次数