莫得感情的杀手 發表於 2025-5-19 20:31:00

Java-Stream API

<p>Stream API 基础(初识)</p>
<h2 id="基本步骤">基本步骤</h2>
<ol>
<li>
<p>获取Stream流</p>
</li>
<li>
<p>对Stream流进行操作</p>
</li>
<li>
<p>获取处理结果</p>
</li>
</ol>
<h2 id="目的">目的</h2>
<p>简化对集合,数组等的操作,使代码更加简洁美观,减少工程量</p>
<h2 id="1获取stream流">1.获取Stream流:</h2>
<ul>
<li>
<p>获取集合(Collection)的Stream流:</p>
<p><img src="https://s3.bmp.ovh/imgs/2025/05/19/b0e99b8d98f439d4.png" alt="" loading="lazy"></p>
</li>
<li>
<p>获取数组的Stream流:</p>
<p><img src="https://s3.bmp.ovh/imgs/2025/05/19/b1ddd5bb976fa8c3.png" alt="" loading="lazy"></p>
</li>
<li>
<p>获取Map的Stream流:</p>
<p>对于Map,不同于前两种,有三种获取方法,一种是对于Key,一种是对于Value,还有一种就是对于键值对(虽然作者还没有看懂怎么对键值对进行操作)</p>
</li>
</ul>
<pre><code class="language-java">//1.获取Stream流,调用集合提供的Stream方法
      Collection&lt;String&gt; s = new ArrayList&lt;&gt;();
      Stream&lt;String&gt; k = s.stream();

      //Map流的获取
      Map&lt;String,Integer&gt; m = new HashMap&lt;&gt;();
      Stream&lt;String&gt;key = m.keySet().stream();
      Stream&lt;Integer&gt; value = m.values().stream();
      Stream&lt;Map.Entry&lt;String,Integer&gt;&gt; dou = m.entrySet().stream();

      //数组
      String[] p = {"112","111","11","321"};
      Stream&lt;String&gt; a =Arrays.stream(p);
      Stream&lt;String&gt; a1 = Stream.of(p);
      Stream&lt;String&gt; a2 = Stream.of("112","111","11","321");
</code></pre>
<h2 id="2中间方法">2.中间方法:</h2>
<h5 id="包含排序过滤去重等等">包含:排序,过滤,去重等等。</h5>
<p><img src="https://s3.bmp.ovh/imgs/2025/05/19/37896ba7bf9944d2.png" alt="" loading="lazy"></p>
<h4 id="过滤">过滤:</h4>
<pre><code class="language-java">//过滤
      a.filter(t -&gt; t.startsWith("1") &amp;&amp; t.length() &gt; 2).forEach(t -&gt; System.out.println(t));
      System.out.println("---------------------------------------");
      //等于
      String[] c = a1.filter(t -&gt; t.startsWith("1") &amp;&amp; t.length() &gt; 2).toArray(String[]::new);
      //对于数组要用toArray
      //但对于集合要用Collectors
      //因为Stream有toArray方法,而变为集合要调用Collectors的静态方法
      List&lt;String&gt; b = k.filter(t -&gt; t.startsWith("1") &amp;&amp; t.length() &gt; 2).collect(Collectors.toList());
</code></pre>
<p>使用lambda函数进行编写过滤条件,注意filter前面跟的是一个流,经过filter筛选得到一个新流,原流保持不变。</p>
<h4 id="排序">排序:</h4>
<pre><code class="language-java">//排序
//排序一般用于浮点数,整数之间
List&lt;Integer&gt; num = new ArrayList&lt;&gt;();
num.add(1);
num.add(12);
num.add(121);
num.add(321);
List&lt;Integer&gt; list = num.stream().sorted().collect(Collectors.toList());
System.out.println(list);
System.out.println("------------------------------------------------");
num.stream().sorted((s1,s2)-&gt;Integer.compare(s2,s1)).forEach(System.out::println);
</code></pre>
<p>排序严格来说使用于有ToCompare方法的对象,因为在sorted里进行比较需要用到compare静态方法,所以对数据类型有所限定。</p>
<pre><code class="language-java">System.out::println
</code></pre>
<p>类似于这种用法是方法引用,有兴趣可以去了解。另外,获取数据后再打印是打印列表,而直接在流下打印则是对数据进行直接打印,不同如下:</p>
<p><img src="https://s3.bmp.ovh/imgs/2025/05/19/5d448d0751ad6e43.png" alt="" loading="lazy"></p>
<h4 id="跳过去重合并等-">跳过,去重,合并等 :</h4>
<p><strong>跳过</strong> :skip(long n),是对流进行处理的操作,可以跳过前n个数据。</p>
<p><strong>保留(我喜欢这么叫)</strong> :limit(maxSize)对应跳过操作,保留前maxSize个数据。</p>
<p><strong>去重</strong>:distinct(),如果要对自定义对象进行去重操作,需要重写它的hashCode和equals.</p>
<p><strong>合并</strong>:concat(stream a1,stream a2),是对两个流进行合并。</p>
<p><strong>映射/加工方法</strong>:对原数据进行处理,返回新流。</p>
<p>示例如下:</p>
<pre><code class="language-java">//跳过,保留
num.stream().skip(2).forEach(System.out::println);
System.out.println("--------------");
num.stream().limit(2).forEach(System.out::println);
System.out.println("--------------");
//如果希望自定义对象可以去重复,那么需要重写hashCode和equals方法,才可以去重
num.stream().distinct().forEach(System.out::println);
System.out.println("--------------");
//假如我想要num中的每一个数都增加10,那么就可以使用map;
//叫做映射/加工方法
num.stream().map(t-&gt;"增加10后: " + (t + 10)).forEach(System.out::println);

System.out.println("--------------");

//合并流
Stream&lt;Double&gt; q1 = Stream.of(1.0,2.0,3.0,4.0);
Stream&lt;String&gt; q2 = Stream.of("hi","bye","ok");
Stream&lt;Object&gt; con= Stream.concat(q1,q2);
System.out.println(con.count());
</code></pre>
<h2 id="3收集终结">3.收集,终结:</h2>
<h4 id="终结方法">终结方法:</h4>
<p>一旦使用终结方法后,流就不可以再次使用,也不会返回流。</p>
<p><img src="https://s3.bmp.ovh/imgs/2025/05/19/38da00b441fdec5e.png" alt="" loading="lazy"></p>
<ul>
<li>
<p>forEach,其实就是增强循环,用来遍历操作</p>
</li>
<li>
<p>count是得到流中数据个数的</p>
</li>
<li>
<p>max和min返回类型是Option<t>,因为返回的数据有可能为空,避免空指针异常。</t></p>
</li>
</ul>
<pre><code class="language-java">List&lt;Employee&gt; employee = new ArrayList&lt;&gt;();
      employee.add(new Employee("张三", 3000, 23));
      employee.add(new Employee("李四",10000,20));
      employee.add(new Employee("王五",5000,30));

      employee.stream().filter(t-&gt;t.getSalary() &gt;= 5000).forEach(System.out::println);
</code></pre>
<p>在运行这段代码之后,我想得到过滤后的员工信息,但是我却得到了</p>
<p><strong>Employee@4f023edb</strong> 和<strong>Employee@3a71f4dd</strong> ,这是因为我并没有在Employee中重写toString方法,下面是Employee的最终实现:</p>
<pre><code class="language-java">public class Employee {
    private String name;
    private double salary;
    private int age;

    public Employee(String name,double salary,int age)
    {
      this.name = name;
      this.salary = salary;
      this.age = age;
    }

    public double getSalary()
    {
      return salary;
    }

    @Override
    public String toString() {
      return String.format("[员工] 姓名: %s | 薪资: %d | 年龄: %d", name, salary, age);
    }
}
</code></pre>
<p>接下来是对终结方法的使用:</p>
<pre><code class="language-java">List&lt;Employee&gt; employee = new ArrayList&lt;&gt;();
      employee.add(new Employee("张三", 3000, 23));
      employee.add(new Employee("李四",10000,20));
      employee.add(new Employee("王五",5000,30));

      //得到月薪不低于5000的员工
      employee.stream().filter(t-&gt;t.getSalary() &gt;= 5000).forEach(System.out::println);
      //得到员工的数量
      System.out.println(employee.stream().count());
      //获取薪水最高的员工
      Optional&lt;Employee&gt; max = employee.stream().max((t1,t2) -&gt; Double.compare(t1.getSalary(),t2.getSalary()));
      Employee maxemployee = max.get();
      System.out.println(maxemployee);
</code></pre>
<h4 id="收集方法">收集方法:</h4>
<p><img src="https://s3.bmp.ovh/imgs/2025/05/19/11e5563a70632b97.png" alt="" loading="lazy"></p>
<h2 id="总结">总结:</h2>
<p>Stream流的使用模板其实就是:集合/数组等 <strong>.</strong> 中间方法 <strong>.</strong> 终结方法/收集</p><br><br>
来源:https://www.cnblogs.com/Kley51/p/18884845
頁: [1]
查看完整版本: Java-Stream API