Functional Java — AI pipelines ke liye streams aur lambdas
Functional Java sirf utna jitna AI kaam mein lagta hai: document pipeline ke liye streams, missing metadata ke liye Optional, aur parallel model calls ke liye CompletableFuture.
Is page par
Functional Java yahan theory ke liye nahi hai. Document ingestion, embedding pipeline aur ek saath kai model calls — ye teenon kaam apne aap streams aur futures ki shakal mein aate hain. Isliye yahan poora functional programming nahi padhaya ja raha, sirf wo hissa jo aap AI code mein sach mein likhenge.
Key Takeaways
- Stream us kaam ke liye hai jo "load karo → filter karo → transform karo → collect karo" jaisa dikhta ho.
- Optional model ke aadhe-adhoore metadata ko safely handle karne ka tareeka hai.
- CompletableFuture tab lijiye jab kai model calls ek doosre par depend karti hon.
- Har jagah functional style thopna galti hai — jahan loop saaf hai, wahan loop hi likhiye.
Lambda ko ek baar aur seedha samajh lijiye
Lambda ka matlab bas itna hai: "function ko ek value ki tarah paas karna". Pehle iske liye poori anonymous class likhni padti thi:
documents.sort(new Comparator<Document>() {
@Override
public int compare(Document a, Document b) {
return a.title().compareTo(b.title());
}
});Ab wahi baat:
documents.sort(Comparator.comparing(Document::title));Document::title ko method reference kehte hain — matlab "har document par title() chala do". Jab
lambda ka poora kaam hi ek existing method ko call karna ho, tab method reference lambda se saaf
padha jaata hai.
Stream — ingestion pipeline ki natural shakal
RAG ke liye documents taiyaar karne ka kaam hamesha ek jaisa hota hai: files padho, khaali waale hatao, chunks mein todo, aur ek list banao. Loop mein ye kaam teen nested blocks mein bikhar jaata hai. Stream mein wo bilkul waise hi likha jaata hai jaise aap bolte:
List<TextSegment> segments = documents.stream()
.filter(doc -> doc.text() != null && !doc.text().isBlank())
.map(splitter::split)
.flatMap(List::stream)
.toList();Line by line padhiye: khaali documents hata do, har document ko chunks mein todo, sabhi chunk-lists ko ek hi flat list bana do, aur list le lo.
flatMap par ek second rukiye, kyunki yahi wo jagah hai jahan log atakte hain. map ke baad aapke
paas List<List<TextSegment>> tha — har document ke liye ek alag list. flatMap un sab ko kholkar
ek hi list bana deta hai. Ingestion pipeline mein ye step lagbhag hamesha aata hai.
Grouping bhi aksar chahiye hoti hai — jaise source ke hisaab se documents ginna:
Map<String, Long> perSource = documents.stream()
.collect(Collectors.groupingBy(Document::source, Collectors.counting()));Optional — "shayad hai, shayad nahi"
Model response ka metadata bharosemand nahi hota. Kabhi token usage aata hai, kabhi nahi. Seedha
.getTokens() maar denge to ek din production mein null milega.
int tokens = Optional.ofNullable(response.metadata())
.map(Metadata::usage)
.map(Usage::totalTokens)
.orElse(0);Beech ka koi bhi step null nikla to chain wahin ruk jaati hai aur 0 mil jaata hai. Koi
if (x != null) ki seedhi nahi.
Do choti baatein jo Optional ko galat use hone se bachati hain:
Optionalko method return karne ke liye use kijiye, field ya method parameter ke liye nahi..get()mat lagaiye. Hamesha.orElse(...),.orElseGet(...)ya.orElseThrow(...)lijiye — warnaOptionalsirf naya naam hai NullPointerException ka.
CompletableFuture — jab calls ek doosre par depend karti hain
Do independent model calls ek saath bhejni hain? Sabse aasaan tareeka:
CompletableFuture<String> summary =
CompletableFuture.supplyAsync(() -> chat.prompt().user(summarize).call().content());
CompletableFuture<String> keywords =
CompletableFuture.supplyAsync(() -> chat.prompt().user(extract).call().content());
String result = summary.thenCombine(keywords, (s, k) -> s + "\n\nKeywords: " + k).join();thenCombine ka matlab hai "dono ka intezaar karo, phir dono ke result se ye banao". Agar ek call ka
result doosri call mein chahiye, to thenCompose lagta hai:
CompletableFuture<String> answer =
CompletableFuture.supplyAsync(() -> retriever.findContext(question))
.thenCompose(context -> CompletableFuture.supplyAsync(
() -> chat.prompt().system(context).user(question).call().content()));Aur AI calls fail hoti hain — rate limit, timeout, provider down. Isliye fallback aur timeout hamesha lagaiye:
String safe = answer
.orTimeout(20, TimeUnit.SECONDS)
.exceptionally(ex -> "Abhi jawab nahi mil paaya, thodi der baad try kijiye.")
.join();Kab functional style mat likhiye
Ye utna hi zaroori hai jitna upar wala sab kuch:
- Beech mein se nikalna ho (
break) — loop lijiye. - Index chahiye ho — loop lijiye.
- Har element par checked exception fenkne wala kaam ho — stream mein wo bahut ganda dikhta hai.
- Nested lambda teen level gehri ho gayi ho — code review mein koi nahi padhega. Todiye.
Rule simple hai: functional style tab hi jeetti hai jab wo intent saaf kare. Jahan wo intent chhupa rahi ho, wahan wo galat choice hai — chahe kitni bhi modern lage.
Aage kya
Ab aapke paas wo saara functional toolkit hai jo document pipeline aur concurrent model calls mein lagta hai. Isse aage streaming aati hai — jahan jawab ek saath nahi, token-by-token aata hai — aur wahan Project Reactor ki baari hai.
Frequently Asked Questions
Document processing ke liye stream lein ya simple for-loop?
Parallel model calls ke liye CompletableFuture use karein ya virtual threads?
AI code mein Optional ki zaroorat kyun padti hai?
Milte-julte tutorials
- Java 17 se 21 tak — AI developers ke liye kya naya haiJava 17 se 21 ke sirf wo features jo AI kaam mein roz use hote hain — records, text blocks, pattern matching, sealed classes aur virtual threads — Hinglish mein, code English mein.
- Reactive programming aur Project Reactor — streaming ke liyeProject Reactor AI developers ke liye: Mono, Flux, back-pressure aur WebFlux — aur wo ek jagah jahan ye sach mein sahi tool hai, yaani LLM tokens ko browser tak stream karna.
- Microservices architecture — AI service kahan baithegiAI systems ke liye microservices patterns: API gateway, model calls ke around circuit breaker, agent workflows ke liye saga pattern, aur AI service ki sahi jagah — Hinglish mein.
- Docker aur Kubernetes — Java AI app ko deploy karnaSpring Boot AI application ko container mein daalna aur Kubernetes par chalana: layered JAR wala production Dockerfile, API key ke liye Secret, health probes aur resource limits.