JAva 8 in action:第4章学習,ストリームStreamの導入,ストリームと集合の比較

3907 ワード

ストリームはjava 8 APIの新しいメンバーです.宣言的にデータ・セットを処理できます.マルチスレッドコードを書く必要がなく、透明に並列に処理する利点があります.
前のdemo:
   :
  public class Dish {

private String name;
private boolean vegetarian;
private int calories;
private Type type;

public enum Type{Meat,Fish,Other}

public Dish(String name, boolean vegetarian, int calories, Type type) {
    super();
    this.name = name;
    this.vegetarian = vegetarian;
    this.calories = calories;
    this.type = type;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public boolean isVegetarian() {
    return vegetarian;
}
public void setVegetarian(boolean vegetarian) {
    this.vegetarian = vegetarian;
}
public int getCalories() {
    return calories;
}
public void setCalories(int calories) {
    this.calories = calories;
}
public Type getType() {
    return type;
}
public void setType(Type type) {
    this.type = type;
}
@Override
public String toString() {
    return "Dish [name=" + name + ", vegetarian=" + vegetarian + ", calories=" + calories + ", type=" + type + "]";
}

}
caloriesが500未満の食べ物の名前を検索します.
public class Test {
public static List menu=Arrays.asList(
        new Dish("pork", false, 800, Type.Meat),
        new Dish("beef", false, 700, Dish.Type.Meat),
        new Dish("chicken", false, 400, Dish.Type.Fish),
        new Dish("french fries", true, 530, Dish.Type.Other),
        new Dish("rice", true, 350, Dish.Type.Other));

public static void main(String[] args) {
    
    List lowCaloricDishesName=menu.stream()
            .filter(d -> d.getCalories()<500)
            .sorted(Comparator.comparing(Dish::getCalories))
            .map(Dish::getName)
            .collect(toList());
    
    System.out.println(lowCaloricDishesName);
}
}

導入されたクラスを覚えています.
import static java.util.stream.Collectors.toList;

JAva 8 in actionこの本の対流の定義:データ処理操作をサポートするソース生産の要素シーケンスから.
上記の例では、menu.stream()がストリームを得ると、データソースはmenuであり、要素シーケンス(特定の値にアクセスする秩序値のセット)、filter、sorted、map、limit、collect対流を提供して動作します.collectは最後にストリームを処理して結果を返します.
上のdemoをいくつか拡張して、caloriesが300より大きい最初の3つの食べ物の名前を検索します.
List threeNames=menu.stream()
            .filter(d -> d.getCalories()>500)
            .sorted(Comparator.comparing(Dish::getCalories))
            .map(Dish::getName)
            .limit(3)
            .collect(toList());

次に、ストリームのいくつかの特徴を共有します.集合とは違う場所でもあります.
一度しか巡りません##
List names=Arrays.asList("Tom","Jim","Joe");
    Stream s=names.stream();
    s.forEach(System.out::println);
    s.forEach(System.out::println);

    s.forEach(System.out::println);   :
   java.lang.IllegalStateException: stream has already been operated upon or closed
at java.util.stream.AbstractPipeline.sourceStageSpliterator(Unknown Source)

stream has already been operated upon or closedストリームが動作または閉じられています.この異常は明らかだ.
外部反復と内部反復##
demoを直接見て、食べ物の名前を見て、コレクションに追加します.
//      
    List names1=new ArrayList<>();
    for (Dish d:menu) {
        names1.add(d.getName());
    }
    
    //     
    List names2=menu.stream()
                        .map(Dish::getName)
                        .collect(toList());

両者の扱い方は直感的だ.コレクションはforeach外部反復を使用し、ストリームは内部反復の方法です.つまり流れが処理してくれたのです.foreachについては、並列問題に関連しており、明らかにある時の表現はStreamに及ばない.
流れのいくつかの一般的な方法##
中間操作、すなわち流を形成する流水線.
filter,map,limit,sorted,distinct戻りタイプはいずれもStreamである.
端末操作:forEach,count(注意はlong型),collect
   forEach  :
  menu.forEach(System.out::println);
  menu.forEach(d -> System.out.print(d.getName()+"\t"));