惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

I
InfoQ
G
Google Developers Blog
Engineering at Meta
Engineering at Meta
月光博客
月光博客
博客园 - 聂微东
博客园 - Franky
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
有赞技术团队
有赞技术团队
A
About on SuperTechFans
Microsoft Azure Blog
Microsoft Azure Blog
Blog — PlanetScale
Blog — PlanetScale
U
Unit 42
T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
云风的 BLOG
云风的 BLOG
S
SegmentFault 最新的问题
F
Fortinet All Blogs
H
Help Net Security
J
Java Code Geeks
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 叶小钗
L
LangChain Blog
Martin Fowler
Martin Fowler
N
Netflix TechBlog - Medium

博客园 - harrychinese

机器学习实战示例和基础知识查漏补缺 jupyter notebook上的java kernel 数据分析中几个常用的java类 我认为 C# 几个重要的设计缺陷 Jupyter notebook 最简安装方法 使用Tribuo分析波士顿房产数据 Java 语言常用的技巧 Java AI agent框架 java jbang 工具让java作为脚本语言 VS code + Jypyter 插件构建 Java notebook 环境 【计算机科学速成课】[40集全/精校] - Crash Course Computer Science Handy toolbox for IT developers 中学学校教材下载 深度学习模型训练5个关键步骤 使用SpringBoot实现一个执行通用SQL的Rest接口 学益升X1和国悦K3阅读器 状态机 使用场景规则匹配模式代替复杂的if else条件判断 vscode 数据处理的插件 iPhone XR 升级非最新版IOS duckdb nuget打包部署完整步骤 ML.Net机器学习基本知识 机器学习资料汇总 优化算法知识和类库 C# XML 序列化器 画草图和示意图的好工具 .net debug tools 运筹学/最优化讲义.pdf Lazarus
使用 VS code + Oracle java 插件搭建java语言原生的notebook...
harrychinese · 2026-04-26 · via 博客园 - harrychinese

Oracle java 扩展在Java项目上的支持度不如Redhat或微软的 Java 扩展,智能提示太慢并且代码重构功能很少,但它提供了一个基于java语言原生的notebook环境, 相较于基于Juypter的方案, 有着更快的运行速度, 基于JShell代码补全不是很好,仅能提示出method名, 不能显示完整的参数清单, 另外无法类似实现 inline matplotlib 功能,所以生成的plot显示不是很方便。

安装和配置Oracle java插件

  1. 安装 Oracle 出品 Java 扩展,只有 Oracle java 插件原生支持 notebook 功能, 它并不依赖Python Jupyter环境. 如果已安装Redhat或微软的 Java 扩展,最好卸载, 以免与Oracle java插件命令和配置混淆。
  2. 在VS code命令面板输入 JDK 字样,可以找到 JDK Downloader, 可以自动下载Oracle JDK 或 Open JDK, 下载并按照即可。
  3. 在VS code命令面板输入 JDK 字样,可找到 Select an installed JDK, 选择Java插件绑定哪个JDK 。
  4. Oracle 出品 Java 扩展内置安装一套 maven 程序, 如有必要设置 maven 私服地址
    在 vscode oracle-java 插件安装目录下搜索 maven\conf\settings.xml, 在文件中设置私服地址。

安装和配置 Maven for java 插件

虽然 vscode oracle-java 内置了一个 maven 程序, 但检查maven项目的类库依赖不是很方便, 可以安装 Maven for java 插件,该插件会提供一个Maven管理面板,使用起来很方便。

Oracle java插件主要问题和解决方案

notebook的功能还比较弱,比如代码提示仅仅显示method名,无法给出参数清单,无法类似实现 inline matplotlib 功能, 这些并不致命。

该插件的最大的问题是,当引入的jar太多时候, 会导致启动java命令行报命令行太长错误, 这个问题会直接影响maven项目的运行和调试, 也会影响notebook cell的运行。 根因在于-classpath 参数太长超过windows命令行8K的限制。
经过很多次的探索,包括但不限于:(1)vscode 缺省 terminal 设置为 powershell ;(2)launch.json 强制使用 @argument file,(3)launch.json 强制使用 powershell 命令。 这些方式都不管用。

但我最终还是将这个问题解决了。 方案如下:
增加了3个编译插件,完美地解决了该问题。

  • 应用的运行/调试时,主要起作用的是pom.xml 文件 exec-maven-plugin 插件, 该插件启用了 longClasspath。 即使不安装该插件, Oracle java插件运行程序, 也是通过 exec-maven-plugin 启动程序的,我显式地启用了 longClasspath 后,运行程序将使用 Argument File 而不是 -classpath 参数,这样避免了命令行超长问题。
  • 程序正式部署时,主要起作用的是 spring-boot-maven-plugin 插件, 程序符合springboot项目规范, 通过该插件打包为fat jar,这样就可以实现单jar部署,也规避了命令行超长问题。
  • notebook cell执行时,(1)如果maven项目中依赖的jar包不多,貌似不需要做任何配置,notebook 即可直接import pom.xml中引入的jar和项目本身的class。(2)但如果依赖jar太多,也会遇到命令行超长问题,这时候就需要额外配置settings.json 的 jdk.notebook.classpath 参数才行, 需要将依赖的jar连同应用程序的class输出目录 target/classes 也一并加进去,jdk.notebook.classpath 或 pom.xml 变更后, 最好使用vscode命令 reload window重新加载notebook文件,然后再使用import语句。

使用 Oracle java 插件编写简单程序

  1. 在VS code命令面板输入 Java 字样,选择创建一个 maven 项目,包含一个 pom.xml 和 主程序 java 文件。
  2. 运行和调试: 在主程序 java 文件的 main 方法上方, 会有 Run main和Debug main的镶嵌命令,可以运行或调试。也可从运行/调试面板启动。
  3. 编译: 在VS code命令面板输入 Java 字样,可以选择 compile workspace。

settings.json 文件内容

关键是jdk.notebook.classpath 参数,需要将依赖的jar连同应用程序的class输出目录 target/classes 也一并加进去,我将本地 maven 缓存的所有jar文件集中存在一个 all_jars 目录中,注意该参数不支持通配符,所以需要将每一个jar都配置进去,另外同一个jar如果有不同版本,只能加一个,否则有可能会导致版本冲突。

  "jdk.telemetry.enabled": false,
  "jdk.jdkhome": "D:\\my_program\\java\\jdk-26.0.1",
  "jdk.notebook.classpath": [
    "C:\\Users\\dorothy\\CodeBuddy\\20260319064631\\.codebuddy\\skills\\maven_project\\target\\classes",
    "D:\\maven_packages\\all_jars\\tribuo-core-4.3.2.jar",
    "D:\\maven_packages\\all_jars\\tribuo-data-4.3.2.jar",
    "D:\\maven_packages\\all_jars\\tribuo-interop-core-4.3.2.jar",
  ],
  "maven.executable.path": "C:\\Users\\dorothy\\.vscode\\extensions\\oracle.oracle-java-25.1.0\\nbcode\\java\\maven\\bin\\mvn.cmd",

launch.json 文件内容

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "jdk", //Oracle java插件需要取值为 jdk
      "request": "launch",
      "console": "internalConsole",
      "name": "Launch Java App (oracle java) ",
      "mainClass": "org.yourcompany.yourproject.DemoApplication",
      "cwd": "${workspaceFolder}"
    }
  ]
}

notebook 语法特殊之处

  1. 在同一个notebook中可以声明多个public class
  2. 多个cell可共享同一个变量,也可重新定义同名的变量。
  3. 甚至同一个cell中都可以重新定义一个同名的变量。
  4. notebook 可以引用项目本身定义的class等
int hello=10;
System.out.println(hello);
String hello="a";
System.out.println(hello);

使用 Oracle java 插件编写notebook

  1. 使用vs code打开一个已有的 java 项目中
  2. 在vs code命令面板输入 Java 字样,选择创建 notebook 命令, 即会生成一个ijnb 文件。
  3. 在 notebook 的 java cell中,输入一个 hello world测试一下。
System.out.print("hello world");
  1. 在 notebook 的 java cell 导入 hutool 的 StrUtil测试。
import cn.hutool.core.util.StrUtil;
String hello=StrUtil.upperFirst("hello world");
System.out.print(hello);

搭建一个数据分析工具箱

  1. 引入 tablesaw、tablesaw plotly类库, 它们提供类似于 pandas 和matplotlib的功能
  2. 引入 duckdb 类库, 读取 csv/parquet 文件, 使用sql进行数据分析处理.
  3. (可选)引入 DFLib 类库, 也是另一个类似 pandas dataframe 功能的类库, 相比 tablesaw 相比chart功能较弱.
  4. (可选)优化算法库 jMetal
  5. (可选)计算学习算法库 tribuo/Weka/smile 等, 如需要AutoML 可以使用 H2O。

说明: duckdb/tablesaw/DFLib都可访问csv等外部数据源, duckdb可使用sql进行数据处理, tablesaw/DFLib可使用data frame的方式进行数据处理, 另外tablesaw/DFLib都可通过jdbc访问db, 所以可以结合sql和dataframe两者的优势进行数据处理.

pom.xml 文件内容

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.yourcompany.yourproject</groupId>
    <artifactId>DemoApplication</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.release>26</maven.compiler.release>
        <exec.mainClass>org.yourcompany.yourproject.DemoApplication</exec.mainClass>

        <exec.maven.version>3.6.3</exec.maven.version>
        <hutool.version>5.8.44</hutool.version>
        <duckdb.version>1.5.2.0</duckdb.version>
        <pebble.version>3.1.5</pebble.version>
        <tablesaw.version>0.42.0</tablesaw.version>
        <tablesaw-parquet.version>0.10.0</tablesaw-parquet.version>
        <dflib.version>1.3.0</dflib.version>
        <jmetal.version>6.2</jmetal.version>
        <tribuo.version>4.3.2</tribuo.version>
        <smile.version>3.1.1</smile.version>
        <weka.version>3.8.6</weka.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>4.0.6</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>${exec.maven.version}</version>
        </dependency>

        <!-- spring-boot 核心启动器:包含自动配置、日志、YAML解析等基础功能 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!-- spring-boot-  单元测试  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- hutool -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
        </dependency>

        <!-- duck db-->
        <dependency>
            <groupId>org.duckdb</groupId>
            <artifactId>duckdb_jdbc</artifactId>
            <version>${duckdb.version}</version>
        </dependency>

        <!-- Tablesaw need newer pebble version to support Java 17 -->
        <dependency>
            <groupId>io.pebbletemplates</groupId>
            <artifactId>pebble</artifactId>
            <version>${pebble.version}</version>

        </dependency>

        <!-- Core Tablesaw for data manipulation -->
        <dependency>
            <groupId>tech.tablesaw</groupId>
            <artifactId>tablesaw-core</artifactId>
            <version>${tablesaw.version}</version>
        </dependency>

        <!-- Tablesaw Plotly for charting/visualization -->
        <dependency>
            <groupId>tech.tablesaw</groupId>
            <artifactId>tablesaw-jsplot</artifactId>
            <version>${tablesaw.version}</version>
        </dependency>

        <dependency>
            <groupId>tech.tablesaw</groupId>
            <artifactId>tablesaw-json</artifactId>
            <version>${tablesaw.version}</version>
        </dependency>

        <dependency>
            <groupId>tech.tablesaw</groupId>
            <artifactId>tablesaw-excel</artifactId>
            <version>${tablesaw.version}</version>
        </dependency>

        <dependency>
            <groupId>net.tlabs-data</groupId>
            <artifactId>tablesaw_${tablesaw.version}-parquet</artifactId>
            <version>${tablesaw-parquet.version}</version>
        </dependency>

        <dependency>
            <groupId>org.dflib</groupId>
            <artifactId>dflib</artifactId>
        </dependency>
        <dependency>
            <groupId>org.dflib</groupId>
            <artifactId>dflib-parquet</artifactId>
        </dependency>

        <dependency>
            <groupId>org.dflib</groupId>
            <artifactId>dflib-avro</artifactId>
        </dependency>
        <dependency>
            <groupId>org.dflib</groupId>
            <artifactId>dflib-echarts</artifactId>
        </dependency>
        <dependency>
            <groupId>org.dflib</groupId>
            <artifactId>dflib-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.dflib</groupId>
            <artifactId>dflib-csv</artifactId>
        </dependency>
        <dependency>
            <groupId>org.dflib</groupId>
            <artifactId>dflib-excel</artifactId>
        </dependency>
        <dependency>
            <groupId>org.dflib</groupId>
            <artifactId>dflib-json</artifactId>
        </dependency>


        <dependency>
            <groupId>org.uma.jmetal</groupId>
            <artifactId>jmetal-core</artifactId>
            <version>${jmetal.version}</version>
        </dependency>
        <dependency>
            <groupId>org.uma.jmetal</groupId>
            <artifactId>jmetal-algorithm</artifactId>
            <version>${jmetal.version}</version>
        </dependency>
        <dependency>
            <groupId>org.uma.jmetal</groupId>
            <artifactId>jmetal-problem</artifactId>
            <version>${jmetal.version}</version>
        </dependency>


        <dependency>
            <groupId>com.github.haifengl</groupId>
            <artifactId>smile-core</artifactId>
            <version>${smile.version}</version>
        </dependency>

        <dependency>
            <groupId>org.tribuo</groupId>
            <artifactId>tribuo-all</artifactId>
            <version>${tribuo.version}</version>
            <type>pom</type>
        </dependency>


        <dependency>
            <groupId>nz.ac.waikato.cms.weka</groupId>
            <artifactId>weka-stable</artifactId>
            <version>${weka.version}</version>
        </dependency>

    </dependencies>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.dflib</groupId>
                <artifactId>dflib-bom</artifactId>
                <version>${dflib.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <!-- Oracle java 插件执行/调试都是使用 exec-maven-plugin 启动的进程的,这里设置 longClasspath 为 true,即告知
                exec-maven-plugin 优化 classpath 参数以免超过Windows命令行8K长度限制 -->
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.6.3</version>
                <configuration>
                    <mainClass>${exec.mainClass}</mainClass>
                    <!-- 关键配置: longClasspath -->
                    <longClasspath>true</longClasspath>
                    <useArgumentFile>true</useArgumentFile>
                    <classpathScope>runtime</classpathScope>
                </configuration>
            </plugin>

            <plugin>
                <!-- 使用 org.springframework.boot 插件完成fat jar包的打包, 这样使用单jar即可部署 -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <!-- 主类(通常自动检测,无需配置) -->
                    <mainClass>${exec.mainClass}</mainClass>

                    <!-- 排除 DevTools 打包 -->
                    <excludeDevtools>true</excludeDevtools>

                    <!-- 分层打包(Docker 优化) -->
                    <layers>
                        <enabled>true</enabled>
                    </layers>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <!-- 重新打包为可执行 JAR -->
                            <goal>repackage</goal>
                            <!-- 生成构建信息 -->
                            <goal>build-info</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <!-- 使用 maven-dependency-plugin 插件输出项目所有的依赖,方便将这些依赖文件集中到一起,并方便
                settings.json中的 jdk.notebook.classpath 设置 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.6.1</version>
                <executions>
                    <!-- 定义一个 execution,绑定到 package 阶段 -->
                    <execution>
                        <!-- execution 的唯一标识 -->
                        <id>generate-classpath</id>

                        <!-- 绑定到 package 生命周期阶段 -->
                        <phase>package</phase>

                        <!-- 执行的目标(goal) -->
                        <goals>
                            <goal>build-classpath</goal>
                        </goals>

                        <!-- 该 execution 的配置 -->
                        <configuration>
                            <!-- classpath 输出文件路径 -->
                            <outputFile>${project.build.directory}/classpath.txt</outputFile>

                            <!-- 路径分隔符(显式指定,避免跨平台问题) -->
                            <pathSeparator>;</pathSeparator>

                            <!-- 文件路径分隔符 -->
                            <fileSeparator>/</fileSeparator>

                            <!-- 包含的依赖范围:compile + runtime(不包含 test) -->
                            <includeScope>runtime</includeScope>

                            <!-- 是否去掉版本号(false 保留完整路径) -->
                            <stripVersion>false</stripVersion>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>
</project>

DemoApplication.java 主程序

package org.yourcompany.yourproject;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import cn.hutool.core.util.StrUtil;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean
    public CommandLineRunner run() {
        return args -> {
            System.out.print(StrUtil.upperFirst("hello"));
            System.out.println("Hello! This is a Spring Boot CLI app.");
        };
    }
}


CoinData 类源码

package org.yourcompany.yourproject;

/**
 * CoinData 抛硬币数据类
 */
public class CoinData {

    public int counter;
    public int head;
    public int aggHeadCount;
    public double aggHeadProb;

    @Override
    public String toString() {

        return "counter:" + String.valueOf(counter) + ", head:" + String.valueOf(head) + ", aggHeadCount:" + String.valueOf(aggHeadCount) + ", aggHeadProb:" + String.valueOf(aggHeadProb);
    }
}

notebook 源码 coin.ijnb

{
  "nbformat": 4,
  "nbformat_minor": 5,
  "metadata": {
    "language_info": {
      "name": "java"
    }
  },
  "cells": [
    {
      "id": "a752b509-2da5-4efc-84c0-6224ba317a0c",
      "cell_type": "code",
      "source": "import java.io.File;\r\nimport java.nio.file.Paths;\r\n\r\n\r\n// 打印当前真实的工作目录\r\nSystem.out.println(\"Current Working Directory: \" + Paths.get(\".\").toAbsolutePath());\r\nSystem.out.println(\"Current Working Directory: \" + new File(\".\").getAbsoluteFile());\r\n// 打印当前可访问到的classpath\r\nSystem.out.println(\"classpath: \" + System.getProperty(\"java.class.path\"));",
      "metadata": {
        "language": "java"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "id": "3fd13d2a-7727-4cc2-8168-e8953f4f0fef",
      "cell_type": "markdown",
      "source": "## 定义一个 CoinData 类\r\n\r\n包含如下信息:\r\n- counter: 哪一次抛硬币,\r\n- head: 是否是正面,\r\n- aggHeadCount: 从第一次开始累积正面次数,\r\n- aggHeadProb: 累积正面的概率",
      "metadata": {
        "language": "markdown",
        "id": "3fd13d2a-7727-4cc2-8168-e8953f4f0fef"
      }
    },
    {
      "id": "e1d05a28-286f-4ec9-a5d3-d369e2d51d95",
      "cell_type": "code",
      "source": "\r\n/**\r\n * CoinData2 抛硬币数据类\r\n*/\r\nclass CoinData2{\r\n    public int counter;\r\n    public int head;\r\n    public int aggHeadCount;\r\n    public double aggHeadProb;\r\n\r\n    public String toString(){\r\n        List<String> lst = new ArrayList<>();\r\n        lst.add(\"a\");\r\n        lst.stream().filter(e -> e.equals(\"a\")).toList();\r\n        return \"counter:\"+String.valueOf(counter) +\", head:\"+ String.valueOf(head)+\", aggHeadCount:\" +String.valueOf(aggHeadCount)  +\", aggHeadProb:\"+ String.valueOf(aggHeadProb)   ;\r\n    }\r\n\r\n}",
      "metadata": {
        "language": "java"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "id": "905bfbc8-dde1-4cfd-b76e-bc0acf45dba1",
      "cell_type": "code",
      "source": "import java.util.Random;\r\nimport org.yourcompany.yourproject.CoinData; //可以从当前项目中引入  CoinData 类, 该类的定义同 CoinData2。\r\n\r\nRandom random=new Random();\r\nint count=100; //抛硬币次数\r\n\r\nList<CoinData> coinList=new ArrayList<>();\r\n\r\n//随机完成指定次数的抛硬币动作\r\nfor(int i=1;i<=count;i++){\r\n   CoinData coin=new CoinData();\r\n   coin.counter=i;\r\n   coin.head=random.nextInt(2); //0 or 1\r\n   coin.aggHeadProb=0 ;\r\n   coin.aggHeadCount=0;\r\n   coinList.add(coin);\r\n}\r\n\r\n//计算概率\r\n for(int i=1;i<=count;i++){\r\n   CoinData coin=coinList.get(i-1);\r\n   CoinData previousCoin=null;\r\n   if (i==1){\r\n    previousCoin=new CoinData();\r\n    previousCoin.counter=0;\r\n    previousCoin.head=0;\r\n    previousCoin.aggHeadProb=0 ;\r\n    previousCoin.aggHeadCount=0;\r\n   }else{\r\n    previousCoin=coinList.get(i-2);\r\n   }\r\n\r\n    if (coin.head==1){\r\n        coin.aggHeadCount=previousCoin.aggHeadCount+1;}\r\n    else{\r\n        coin.aggHeadCount=previousCoin.aggHeadCount;\r\n    }\r\n\r\n   coin.aggHeadProb=(coin.aggHeadCount+0.0)/i;\r\n   System.out.println(coin);\r\n}",
      "metadata": {
        "language": "java"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "id": "6046233b-9f32-4229-8ff5-0cb0288645bb",
      "cell_type": "code",
      "source": "import tech.tablesaw.api.IntColumn;\r\nimport tech.tablesaw.api.DoubleColumn;\r\nimport tech.tablesaw.api.Table;\r\nimport tech.tablesaw.plotly.Plot;\r\nimport tech.tablesaw.plotly.api.LinePlot;\r\nimport tech.tablesaw.plotly.components.Figure;\r\nimport tech.tablesaw.plotly.components.Layout;\r\nimport tech.tablesaw.plotly.traces.ScatterTrace;\r\n\r\n// 1. Create a Tablesaw Table and add columns\r\nTable table = Table.create(\"Monte Carlo Coin Toss Convergence\");\r\nIntColumn counterCol = IntColumn.create(\"Trial\");\r\nDoubleColumn probCol = DoubleColumn.create(\"Aggregated Probability\");\r\n\r\n// 2. Populate the table from your coinList\r\nfor (CoinData coin : coinList) {\r\n    counterCol.append(coin.counter);\r\n    probCol.append(coin.aggHeadProb);\r\n}\r\ntable.addColumns(counterCol, probCol);",
      "metadata": {
        "language": "java"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "id": "7cd4d0f3-92f2-4969-9f44-d719a441d64c",
      "cell_type": "markdown",
      "source": "",
      "metadata": {
        "language": "markdown",
        "id": "7cd4d0f3-92f2-4969-9f44-d719a441d64c"
      }
    },
    {
      "id": "f2fc1809-3f8f-4d56-aaed-6558fbc626d1",
      "cell_type": "code",
      "source": "// 3. Create a trend plot (Probability vs. Trial Number)\r\n// LinePlot is the simplest way to show the trend line\r\nFigure figure = LinePlot.create(\r\n    \"Probability Convergence to 0.5\",\r\n    table,\r\n    \"Trial\",\r\n    \"Aggregated Probability\"\r\n);\r\n\r\n\r\n",
      "metadata": {
        "language": "java"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "id": "bc758e1c-5500-4fef-9dfb-ac271e13134e",
      "cell_type": "code",
      "source": "// 4. Display the plot\r\nimport java.io.File;\r\nimport java.nio.file.Paths;\r\n\r\n// 1. 打印当前真实的工作目录,确认文件到底去哪了\r\nSystem.out.println(\"Current Working Directory: \" + new File(\".\").getAbsolutePath());\r\n\r\n// 2. 强制使用绝对路径生成 HTML\r\n// 请将下面的路径修改为你电脑上存在的某个确定目录,例如 \"D:/test/coin_plot.html\" 或 \"/Users/name/Desktop/plot.html\"\r\nString absolutePath = Paths.get(\".\").toAbsolutePath().normalize().toString() + File.separator + \"coin_convergence.html\";\r\nSystem.out.println(\"Target file path: \" + absolutePath);\r\n\r\n// 3. 使用指定路径保存, 并使用浏览器打开输出的html图像文件\r\nPlot.show(figure, new File(absolutePath));",
      "metadata": {
        "language": "java"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}

抛硬币概率逼近效果图

图片

资料

https://github.com/jtablesaw/tablesaw
https://jtablesaw.github.io/tablesaw/
https://dflib.org/
https://jmetal.readthedocs.io/
https://haifengl.github.io/overview.html
https://tribuo.org/learn/4.3/docs/
https://tribuo.org/learn/4.3/tutorials/irises-tribuo-v4.html

使用 Jupyter 搭建 java notebook 环境

https://github.com/jupyter-java
https://github.com/jupyter-java/awesome-jupyter-java
https://www.javaspring.net/blog/java-jupyter-notebook/
https://www.javathinking.com/blog/using-jupyter-notebook-for-java/
https://www.javaspring.net/blog/java-jupyter-notebook/
https://readmedium.com/java-jupyter-plotly-e1bbaa7f2be8
https://github.com/jtablesaw/tablesaw/tree/master/jsplot/src/test/java/tech/tablesaw/examples
https://medium.com/oracledevs/machine-learning-in-java-with-the-tribuo-library-and-oracle-ai-database-26ai-unleashing-jupyter-ef4af5d8c5a4