java11省流版

局部变量类型推断:var

根据个人习惯使用,var并不是百利无一害

  • 关键字var 不是类型,而是“编译器占位符”

  • 作用范围:只能用于方法内部的局部变量(成员变量、方法参数、返回类型都不行)

  • 编译期行为:IDEA 会立即推导出真实类型,字节码里依旧是强类型,零运行时开销

    flink开发有奇效:

    泛型链很长:DataStream<Tuple3<String,Integer,Long>> → var 一行搞定
    Lambda 返回值复杂:Collector<Tuple2<String,Double>> → var 自动推
    单元测试里各种 RichFunction 匿名类 → var 让表意更集中

     实例:

    java11:

    public class AvgAmountJob {
    public static void main(String[] args) throws Exception {
    var env = StreamExecutionEnvironment.getExecutionEnvironment();
    env.setParallelism(1);

    var source = env.socketTextStream("localhost", 9999); // 1. var
    var parsed = source.map((MapFunction<String, Order>) line -> {
    var arr = line.split(","); // 2. var
    return new Order(arr[0], Double.parseDouble(arr[1]));
    });

    var result = parsed
    .keyBy(Order::getCurrency)
    .window(TumblingProcessingTimeWindows.of(Time.seconds(5)))
    .aggregate(new AvgAggregate()); // 3. var

    result.print(); // 4. var
    env.execute();
    }

    // 聚合函数
    public static class AvgAggregate
    implements AggregateFunction<Order, Tuple2<Double, Long>, Double> {
    @Override
    public Tuple2<Double, Long> createAccumulator() {
    return Tuple2.of(0.0, 0L);
    }
    @Override
    public Tuple2<Double, Long> add(Order value, Tuple2<Double, Long> acc) {
    return Tuple2.of(acc.f0 + value.amount, acc.f1 + 1);
    }
    @Override
    public Double getResult(Tuple2<Double, Long> acc) {
    return acc.f0 / acc.f1;
    }
    @Override
    public Tuple2<Double, Long> merge(Tuple2<Double, Long> a,
    Tuple2<Double, Long> b) {
    return Tuple2.of(a.f0 + b.f0, a.f1 + b.f1);
    }
    }
    }

    对比Java8漫长的类型:

    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    DataStream<String> source = env.socketTextStream("localhost", 9999);
    DataStream<Order> parsed = source.map(...);
    DataStream<Tuple2<String, Double>> result = parsed...

     

    不可变集合工厂:List.of / Set.of / Map.of

    • 位置java.util.List | Set | Map 的静态方法

    • 语义:返回结构不可变(长度固定、元素不可替换)、线程安全的集合

    • 实现:内部专用类 ImmutableCollections.xxx无包装开销、序列化友好

    • 限制

      • 不能存 null(会抛 NullPointerException

      • 增删改操作一律抛 UnsupportedOperationException

    对flink的友好处:

    1. 广播变量BroadcastStream)只需只读数据集 → 用 List.of 一行搞定

    2. 侧输出标签OutputTag)经常需要传小映射 → Map.of 直接塞

    3. 单元测试里造数据:不用 Arrays.asList 再包 Collections.unmodifiableList

    4. 配置型维表(币种汇率、错误码)启动时一次性加载 → 不可变更安全

   实例:

// ① 定义 OutputTag 时直接小映射
OutputTag<String> errorSide = new OutputTag<String>("error"){};
Map<Integer, String> errorMap = Map.of(
1, "金额格式错误",
2, "币种不支持",
3, "超时"
);

// ② 广播出去
BroadcastStream<Map<Integer, String>> broadcast =
env.fromCollection(List.of(errorMap)) // List.of 只读
.broadcast(new MapStateDescriptor<>("errorMap", BasicTypeInfo.INT_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO));

// ③ 主数据流连接广播
DataStream<String> cleaned = mainStream
.connect(broadcast)
.process(new BroadcastProcessFunction<Order, Map<Integer, String>, String>() {
@Override
public void processElement(Order order, ReadOnlyContext ctx,
Collector<String> out) throws Exception {
var map = ctx.getBroadcastState(new MapStateDescriptor<>("errorMap", ...)).get(order.getErrorCode());
if (map != null) {
ctx.output(errorSide, map); // 侧输出
} else {
out.collect(order.toString());
}
}
@Override
public void processBroadcastElement(Map<Integer, String> value, Context ctx, Collector<String> out) {
// 只读,无需防御性拷贝
value.forEach((k, v) -> ctx.getBroadcastState(...).put(k, v));
}
});

string增强API

lines()

isBlank()

strip()

repeat()

 

HTTP Client 新标准(java.net.http)

待补充

 

ZGC 超低延迟 GC

待补充

 

flies新特性:

读取:大文件请使用 Files.lines()

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class ReadStringDemo {
public static void main(String[] args) throws Exception {
Path path = Paths.get("example.txt");

// Java 11 新特性:一行读取文件内容
String content = Files.readString(path);
System.out.println(content);
}
}

 

多行惰性读取:

Path path = Paths.get("data.txt");
try (Stream<String> lines = Files.lines(path)) {
    lines.forEach(System.out::println);
}

写入:

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.charset.StandardCharsets;

public class WriteStringDemo {
public static void main(String[] args) throws Exception {
Path path = Paths.get("output.txt");

// Java 11 新特性:一行写入内容
Files.writeString(path, "Hello, Java 11!\nThis is a new feature.");

// 可选:指定编码(如 UTF-16)
Files.writeString(path, "中文测试", StandardCharsets.UTF_16);
}
}

posted @ 2026-01-08 11:20  ---江北  阅读(0)  评论(0)    收藏  举报
TOP