当前位置: 首页 > 知识库问答 >
问题:

如何流更有效?

洪琦
2023-03-14

我正在尝试消化stream包,我似乎很难理解。

我正在阅读stream包文档,并试图实现它,以便边做边学。这是我读过的课文:

中间操作返回一个新流。他们总是懒惰;执行filter()之类的中间操作实际上并不执行任何筛选,而是创建一个新流,在遍历该流时,该流包含与给定谓词匹配的初始流的元素。管道源的遍历直到执行管道的终端操作才开始。

        List<String> stringList = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            stringList.add("String" + i);
        }
        long   start  = System.currentTimeMillis();
        Stream stream = stringList.stream().filter(s -> s.contains("99"));
        long   midEnd = System.currentTimeMillis();
        System.out.println("Time is millis before applying terminal operation: " + (midEnd - start));
        System.out.println(stream.findFirst().get());
        long end = System.currentTimeMillis();
        System.out.println("Whole time in millis: " + (end - start));
        System.out.println("Time in millis for Terminal operation: " + (end - midEnd));

        start = System.currentTimeMillis();
        for (String ss1 : stringList) {
            if (ss1.contains("99")) {
                System.out.println(ss1);
                break;
            }
        }
        end = System.currentTimeMillis();
        System.out.println("Time in millis with old standard: " + (end - start));

总体而言,旧的if-else模式要比streams高效得多。所以,这里又有更多的问题:

  1. 我误解了什么吗?
  2. 如果我理解正确,请说明为什么以及何时使用流?
  3. 如果我做错或理解错了什么,请帮助澄清我的概念包java.util.stream好吗?

实际数字:

Time is millis before applying terminal operation: 73
String99
Whole time in millis: 76
Time in millis for Terminal operation: 3
String99
Time in millis with old standard: 0
Time is millis before applying terminal operation: 56
String99
Whole time in millis: 59
Time in millis for Terminal operation: 3
String99
Time in millis with old standard: 0
Time is millis before applying terminal operation: 69
String99
Whole time in millis: 72
Time in millis for Terminal operation: 3
String99
Time in millis with old standard: 0
Memory: 11.6 GiB
Processor: Intel® Core™ i7-3632QM CPU @ 2.20GHz × 8 
OS-Type: 64-bit

共有1个答案

轩辕成天
2023-03-14

Streamapi的原理之一是它消除了for循环的固有假设,即所有迭代都以相同的方式进行。当您使用基于迭代器的for循环时,您正在硬编码迭代逻辑以始终按顺序迭代。考虑这样一个问题:“如果我想用更有效的方法来更改'for'循环的实现,该怎么办?”

Stream api解决了这样的问题--它抽象了迭代的概念,并允许考虑处理多个数据点的其他方法--串行迭代还是并行迭代,如果已知数据是无序的,则添加优化,等等。

考虑您的示例--尽管不能更改for循环的实现,但可以更改流的实现以适应不同的情况。例如,如果每个任务都有更多的CPU密集型操作要做,则可以选择并行流。下面是一个10毫秒延迟的示例,模拟了并行完成的更复杂的处理,结果非常不同:

    List<String> stringList = new ArrayList<>();
    for (int i = 0; i < 10000; i++) {
        stringList.add("String" + i);
    }
    long   start  = System.currentTimeMillis();
    Stream stream = stringList.parallelStream().filter(s -> {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return s.contains("99" );});
    long   midEnd = System.currentTimeMillis();
    System.out.println("Time is millis before applying terminal operation: " + (midEnd - start));
    System.out.println(stream.findAny().get());
    long end = System.currentTimeMillis();
    System.out.println("Whole time in millis: " + (end - start));
    System.out.println("Time in millis for Terminal operation: " + (end - midEnd));

    start = System.currentTimeMillis();
    for (String ss1 : stringList) {
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (ss1.contains("99")) {
            System.out.println(ss1);
            break;
        }
    }
    end = System.currentTimeMillis();
    System.out.println("Time in millis with old standard: " + (end - start));
 类似资料:
  • 假设有Kafka主题顺序。数据以JSON格式存储: 定义订单的状态(待定-1,已完成-2)。 完成后如何在“已完成”上进行更改? 正如我所知,Kafka主题是不可变的,我不能更改消息JSON,只需创建一个带有更改值的新消息,对吗?

  • 我试图在数组中添加一个元素,但不知道是什么导致了我的问题,不知道我是否必须执行插入或更新,我尝试了两者,但两者都不起作用 我搞错了

  • 我正在尝试在现有列表中添加一个新项目,但无法添加。当我调试时,它显示返回为true,但最终新项没有添加到列表中。 我的示例代码如下:Employee employee1=new Employee(5001,“BOB”,financeDept.getDepartment_name());employee2=新员工(5002,“SAM”,FinanceDepartment.getDepartment_

  • 在代码下面执行 输出: 除了3号元素,其他都是平行的吗?想了解并行运算符在后续调用中行为吗? 并行运算符在哪里开始,并行如何继续?

  • 我正在尝试合并一个

  • 为了良好地沟通,你必须认识到它的困难。它本身就是一种技能。与你交流的人本身是有瑕疵的,这一事实使得沟通变得更加困难。他们不会努力去理解你。他们不善言辞。他们经常过度工作或者无聊,至少,有时候只关注他们自己的工作而非你要发表的长篇大论。上课,练习写作,公共演讲,聆听,这些东西的一个好处是,如果你擅长它们,你可以更容易看到问题所在以及解决方法。 程序员是一种社会动物,他们的生存依赖于与团队的交流。高级