Python for Java Developers: From Streams to Tensors

A field guide for mainstream developers who need to be productive in Python’s data, ML and AI ecosystem — fast.


About This Series

You already know how to program. You know what a hash map costs, why immutability matters, how a thread pool behaves under load, and why equals() and hashCode() must agree. What you don’t have is Python intuition: the reflexes that make a Python developer reach for a comprehension instead of a loop, a NumPy vector instead of a comprehension, and a DataFrame instead of a hand-rolled aggregation.

This series is built for exactly that gap. It skips “what is a variable” and spends its time on the things that are different for someone coming from Java, C#, Kotlin or Go — and on the libraries that dominate data science, machine learning and AI work.

It is not a web-development series. You won’t build a REST API with FastAPI or Django here. Every example points toward data: transactions, features, vectors, models.


Meet Arjun

Arjun Rao has spent fifteen years writing Java. He is the principal engineer at Ledgerline, a mid-sized payments company, and the person everybody calls when a Kafka consumer group goes sideways at 2 a.m. He thinks in Spring beans, Streams and strongly typed DTOs.

Then the board approves Project Sentinel: a machine-learning platform to catch fraudulent transactions in real time. The data science team, led by Priya Nair, works entirely in Python. Arjun is asked to “bridge the two worlds” — to understand their code well enough to productionise it, review it, and eventually write it.

He has six weeks.

Each part of this series is one step of that journey. Arjun hits a real problem, his Java instincts lead him somewhere slightly wrong, and Priya (or a failing test) sets him straight.


Prerequisites

SkillLevel Expected
Java, C#, Kotlin or similarProficient — you ship production code
OOP, generics, collectionsComfortable
SQLComfortable with JOIN and GROUP BY
Linear algebra / statisticsHelpful, not required — we explain what we use
PythonNone assumed

Tools you will use:

ToolPurposeJava analogue
Python 3.12+The interpreter (examples tested on 3.13)JDK
uvPython versions, virtual envs, dependenciesSDKMAN + Maven/Gradle
VS Code or PyCharmEditor / IDEIntelliJ IDEA
Jupyter (optional)Interactive notebooksJShell, on steroids

Quick setup, which Part 1 explains in detail:

Terminal window
# Install uv (macOS / Linux). Windows: see the uv docs.
curl -LsSf https://astral.sh/uv/install.sh | sh
# Create a project with its own interpreter and virtual environment
uv init sentinel && cd sentinel
uv add numpy pandas scikit-learn matplotlib pydantic torch
# Run any example from the series
uv run python example.py

Series Table of Contents

Act I — Rewiring the Java Brain (Parts 1–3)

Part 1: “The Culture Shock” — Names, Objects and the Runtime Arjun’s first code review goes badly. We cover how Python actually executes code, why variables are names bound to objects, mutability, is vs ==, truthiness, integer behaviour, the module system, and setting up a project properly with uv.

Part 2: “Collections Without Ceremony” — Lists, Dicts, Sets and Comprehensions The Streams API, translated. Lists, tuples, dicts and sets; slicing and unpacking; comprehensions as the idiomatic map/filter/collect; and the collections module (Counter, defaultdict, deque).

Part 3: “Functions Are Values” — Arguments, Closures and Decorators No more single-method interfaces. Positional, keyword, *args, **kwargs; the mutable-default trap; closures and scope (LEGB); and decorators — Python’s answer to Spring AOP — for timing, retries and caching.

Act II — Writing Python Like a Pythonista (Parts 4–6)

Part 4: “Objects Without the Ceremony” — Classes, Dunders, Dataclasses and Protocols Arjun writes his first TransactionDTO with getters and setters and gets gently mocked. Properties, the data model (__repr__, __eq__, __hash__, __len__, __getitem__), @dataclass, enums, and duck typing formalised with Protocol.

Part 5: “The Lazy River” — Iterators, Generators and Context Managers A 40 GB transaction export won’t fit in memory. Iterator protocol, generators and yield, generator pipelines, itertools, exceptions and EAFP, and with statements as try-with-resources.

Part 6: “Types Strike Back” — Type Hints, Pydantic and Modern Tooling Arjun misses his compiler. Type hints, generics, TypedDict, mypy, runtime validation with Pydantic, project layout, pyproject.toml, ruff and pytest — the Maven-and-JUnit equivalents.

Act III — The Data Science Stack (Parts 7–10)

Part 7: “Thinking in Arrays” — NumPy, Vectorisation and Broadcasting Why the for loop is the enemy. ndarray, dtypes, vectorised operations, broadcasting rules, boolean masks, axes, views vs copies, random generators, and cosine similarity from scratch.

Part 8: “DataFrames for SQL Minds” — pandas in Practice pandas explained through SQL. Selection with loc/iloc, filtering, groupby as GROUP BY, merge as JOIN, time series, missing data, Copy-on-Write, and feature engineering for fraud detection.

Part 9: “The First Model” — scikit-learn, Pipelines and Honest Metrics Sentinel’s first fraud model. Train/test splits, Pipeline and ColumnTransformer, logistic regression and random forests, why accuracy lies on imbalanced data, cross-validation, data leakage, and persisting models.

Part 10: “Into the Deep End” — PyTorch, Concurrency and the AI Toolkit Tensors, autograd and a training loop written by hand. Then the production questions a Java architect asks: the GIL, multiprocessing, asyncio for fanning out LLM calls, embeddings and semantic search, and how Python models reach JVM services.


How Each Part Is Structured

Story Opening — the problem Arjun faces at Ledgerline. Java → Python map — a quick table of what you know and what replaces it. Concept sections — runnable examples with heavy comments for the simple things, and a dedicated Deep Dive for the ideas that genuinely require a mental-model shift. Tips, Tricks & Gotchas — the shortcuts experienced Pythonistas use and the traps that catch Java developers specifically. Key Takeaways and a Story Closing that sets up the next part.

Conventions used in code

Every Python code block is self-contained and runnable — copy it into a file and run it. Expected output appears as a trailing comment marked with an arrow:

total = sum([10, 20, 30])
print(total) # -> 60

When a block demonstrates an error on purpose, it catches the exception and prints it so the script still runs to the end.


This is Part 0 of a 10-part series: “Python for Java Developers: From Streams to Tensors.”