Skip to content
CMO & CTO
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

  • Digital Experience
    • Experience Strategy
    • Experience-Driven Commerce
    • Multi-Channel Experience
    • Personalization & Targeting
    • SEO & Performance
    • User Journey & Behavior
  • Marketing Technologies
    • Analytics & Measurement
    • Content Management Systems
    • Customer Data Platforms
    • Digital Asset Management
    • Marketing Automation
    • MarTech Stack & Strategy
    • Technology Buying & ROI
  • Software Engineering
    • Software Engineering
    • Software Architecture
    • General Software
    • Development Practices
    • Productivity & Workflow
    • Code
    • Engineering Management
    • Business of Software
    • Code
    • Digital Transformation
    • Systems Thinking
    • Technical Implementation
  • About
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

Streams in the Real World: Pipeline Patterns

Posted on November 27, 2016 By Luis Fernandez

Streams in the Real World: Pipeline Patterns is a look at Java 8 from a practitioner point of view. We will keep it grounded. No magic tricks. Just patterns you can use on Monday.

Problem framing

We have had lambdas and streams for a while now, and many teams still fall back to loops for everyday work. The usual fear is that streams look fancy but hide cost, or that they fit toy problems and fall apart in production. The truth is closer to this. Streams are great when you treat them as pipelines. Think of a series of small steps that move data from raw shape to decision. When you do that, your code reads like a story and your bugs show up sooner.

Here are three real cases where a stream pipeline shines. No theory. Just the flow and the choices.

Three case walkthrough

Case 1: Cleaning a CSV feed for billing

Input arrives as lines from a daily file. Some rows are corrupt, some fields are empty, and some customers send duplicate entries. The pipeline is simple. Start with a stream of lines. Map to a record model while collecting parse errors to a side sink such as a logger or a metric. Filter out invalid records. De duplicate by a natural key like order id. Enrich with a price table. Group by customer. Then collect to a report object with totals, counts, and a list of skipped reasons.

The pay off is clarity. Each step does one job. Parse then validate then enrich then group then collect. Because streams are lazy, no work happens until the final collect. That keeps early steps cheap when the file is big.

Case 2: Log triage for a support team

Support asks for a daily summary of errors by service and top messages. Files.lines gives a stream of log entries. Filter only error level. Map to a small pair like service and message. Group by service and then summarize counts. For messages, apply a second level grouping to get the top five per service. Finish with a collector that returns a tiny DTO ready to serialize to JSON for the dashboard.

The key move here is nested grouping with a downstream collector for top N. In loop form this often turns into three maps and a lot of branching. The pipeline reads straight through and is far easier to reason about.

Case 3: Product catalog dedupe and rank

Merchants upload similar products. We want one row per SKU with the best photo and the lowest price. Start with the stream of items from all feeds. Filter out missing SKU or price. Group by SKU. For each group pick the item with the best quality score, break ties by lower price, and collect only the winning item. Sort the winners by demand score and take the first thousand.

This pipeline shows two edges people skip. Custom selection per group and final slicing with a limit after a sort. The flow stays small and readable while doing non trivial work.

Objections and replies

  • Loops are faster. Sometimes. Measure. For most business data sizes the difference is small. When you stick to simple maps filters and collectors the JIT does solid work. If it is hot code, keep it simple and benchmark with JMH before you decide.
  • Parallel stream will fix performance. Not a silver bullet. It helps when work per element is heavy and independent and memory fits. It hurts when you touch IO or shared state. Try it behind a flag and watch CPU and GC.
  • Streams are hard to debug. Use small pure steps with names. Extract lambdas to methods with a verb. Log at boundaries. Keep side effects at the ends of the pipeline, not in the middle.
  • Checked exceptions make it messy. Wrap at the edges. Convert to a result type or handle once near the source. Do not leak try catch into every map step.
  • Collectors look scary. Learn three and you are set. To list, to map with a merge rule, and grouping with a downstream finisher. You can build almost anything with those.

Action oriented close

  • Pick one pipeline in your codebase and rewrite it with streams. Keep every step tiny and name each method with a clear verb.
  • Move side effects to the start or the end. Parsing and writing are fine. The middle should be pure data shaping.
  • Adopt a small collector kit. toList, toMap with a merge strategy, and groupingBy with a finisher like counting or mapping to another collector.
  • Write a micro benchmark for that path. Compare loop vs stream with real data sizes. Keep the winner and add a short note in the code so the next person knows why.
  • Create a team rule for parallel streams. Allow it only for CPU heavy stateless work and only with a test that shows a real gain.

Streams reward a pipeline mindset. Keep steps honest, own your data shape, and measure the hot spots. Do that and your code reads cleaner while you ship faster without surprises.

Development Practices Software Engineering

Post navigation

Previous post
Next post
  • Digital Experience (94)
    • Experience Strategy (19)
    • Experience-Driven Commerce (5)
    • Multi-Channel Experience (9)
    • Personalization & Targeting (21)
    • SEO & Performance (10)
  • Marketing Technologies (92)
    • Analytics & Measurement (14)
    • Content Management Systems (45)
    • Customer Data Platforms (4)
    • Digital Asset Management (8)
    • Marketing Automation (6)
    • MarTech Stack & Strategy (10)
    • Technology Buying & ROI (3)
  • Software Engineering (310)
    • Business of Software (20)
    • Code (30)
    • Development Practices (52)
    • Digital Transformation (21)
    • Engineering Management (25)
    • General Software (82)
    • Productivity & Workflow (30)
    • Software Architecture (85)
    • Technical Implementation (23)
  • 2025 (12)
  • 2024 (8)
  • 2023 (18)
  • 2022 (13)
  • 2021 (3)
  • 2020 (8)
  • 2019 (8)
  • 2018 (23)
  • 2017 (17)
  • 2016 (40)
  • 2015 (37)
  • 2014 (25)
  • 2013 (28)
  • 2012 (24)
  • 2011 (30)
  • 2010 (42)
  • 2009 (25)
  • 2008 (13)
  • 2007 (33)
  • 2006 (26)

Ab Testing Adobe Adobe Analytics Adobe Target AEM agile-methodologies Analytics architecture-patterns CDP CMS coding-practices content-marketing Content Supply Chain Conversion Optimization Core Web Vitals customer-education Customer Data Platform Customer Experience Customer Journey DAM Data Layer Data Unification documentation DXP Individualization java Martech metrics mobile-development Mobile First Multichannel Omnichannel Personalization product-strategy project-management Responsive Design Search Engine Optimization Segmentation seo spring Targeting Tracking user-experience User Journey web-development

©2025 CMO & CTO | WordPress Theme by SuperbThemes