{"id":15068713,"url":"https://github.com/ashfaqbs/java-stream-lambdas","last_synced_at":"2026-01-02T18:06:07.342Z","repository":{"id":214628980,"uuid":"736866321","full_name":"Ashfaqbs/Java-Stream-Lambdas","owner":"Ashfaqbs","description":"Java Stream and Lambda Code Sample ","archived":false,"fork":false,"pushed_at":"2025-01-04T01:24:26.000Z","size":160,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-22T21:32:36.822Z","etag":null,"topics":["java8","lambda","stream"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ashfaqbs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-29T05:27:45.000Z","updated_at":"2025-01-04T01:24:29.000Z","dependencies_parsed_at":"2023-12-29T14:24:40.743Z","dependency_job_id":"84f008e1-7f1c-414e-baf6-cffcc17689df","html_url":"https://github.com/Ashfaqbs/Java-Stream-Lambdas","commit_stats":null,"previous_names":["ashfaqbs/java-stream-lambdas"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ashfaqbs%2FJava-Stream-Lambdas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ashfaqbs%2FJava-Stream-Lambdas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ashfaqbs%2FJava-Stream-Lambdas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ashfaqbs%2FJava-Stream-Lambdas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ashfaqbs","download_url":"https://codeload.github.com/Ashfaqbs/Java-Stream-Lambdas/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243849009,"owners_count":20357689,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java8","lambda","stream"],"created_at":"2024-09-25T01:38:57.818Z","updated_at":"2026-01-02T18:06:07.294Z","avatar_url":"https://github.com/Ashfaqbs.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Java-Stream-Lambdas\n\n## A **Functional Interface** in Java 8 is an interface that has exactly **one abstract method**. It can have multiple default or static methods, but it must have exactly one abstract method, which makes it eligible to be used with **lambda expressions** and **method references**.\n\n### Breakdown of Functional Interfaces:\n\n- **Single Abstract Method (SAM)**: The key characteristic of a functional interface is that it only contains **one abstract method**. This is the \"contract\" that a lambda expression or a method reference will implement.\n  \n- **`@FunctionalInterface` Annotation** (optional but recommended): This annotation is used to indicate that the interface is intended to be a functional interface. It’s not required, but it helps catch errors at compile time if the interface does not conform to the rules of a functional interface (i.e., having more than one abstract method).\n  \n  Example:\n  ```java\n  @FunctionalInterface\n  public interface MyFunction {\n      void execute();  // Single abstract method\n  }\n  ```\n\n### Examples of Built-in Java 8 Functional Interfaces:\n\n1. **Runnable**:\n   - The `Runnable` interface has a single abstract method, `run()`.\n   - It can be used in a lambda expression as follows:\n     ```java\n     Runnable myRunnable = () -\u003e System.out.println(\"Running in a thread!\");\n     ```\n\n2. **Predicate**:\n   - `Predicate\u003cT\u003e` represents a boolean-valued function of one argument. Its abstract method is `boolean test(T t)`.\n   - Example of using `Predicate` with a lambda:\n     ```java\n     Predicate\u003cString\u003e isEmpty = str -\u003e str.isEmpty();\n     System.out.println(isEmpty.test(\"\"));  // true\n     ```\n\n3. **Function**:\n   - `Function\u003cT, R\u003e` is a function that accepts one argument of type T and returns a result of type R. Its abstract method is `R apply(T t)`.\n   - Example of using `Function` with a lambda:\n     ```java\n     Function\u003cInteger, String\u003e convertToString = num -\u003e \"Number \" + num;\n     System.out.println(convertToString.apply(5));  // Output: Number 5\n     ```\n\n4. **Consumer**:\n   - `Consumer\u003cT\u003e` represents an operation that accepts a single input argument and returns no result. Its abstract method is `void accept(T t)`.\n   - Example:\n     ```java\n     Consumer\u003cString\u003e printMessage = message -\u003e System.out.println(message);\n     printMessage.accept(\"Hello, World!\");  // Output: Hello, World!\n     ```\n\n5. **Supplier**:\n   - `Supplier\u003cT\u003e` represents a function that takes no arguments and returns a value of type T. Its abstract method is `T get()`.\n   - Example:\n     ```java\n     Supplier\u003cDouble\u003e randomValue = () -\u003e Math.random();\n     System.out.println(randomValue.get());  // Output: Some random value between 0 and 1\n     ```\n\n### Key Points:\n- **Functional interfaces** are meant to represent a single unit of work that can be expressed in a concise form via lambda expressions.\n- The **`@FunctionalInterface` annotation** ensures the interface has exactly one abstract method (but doesn't force it).\n- They can be used wherever a lambda expression or method reference is required.\n\n### Why are Functional Interfaces important in Java 8?\nThey are central to **functional programming** in Java, especially with features like **Streams**, **lambda expressions**, and **method references**. By using functional interfaces, we can pass behavior around as data, enabling more concise and expressive code.\n\n---\n\n### Why Do We Use Functional Interfaces?\n\nThese functional interfaces let us write cleaner, more modular code. Instead of writing whole classes for one task, we can just use a lambda expression with these functional interfaces. This makes Java more like a \"do it in one line\" kind of language, which is faster and looks cleaner.\n\nSo, in short:\n- Functional interfaces make it easy to pass actions as parameters.\n- They work great with lambdas to make code simpler and cleaner.\n\n\n\n\n ### Several key concepts related to Java Streams that make them efficient and functional:\n\n---\n\n### **1. Loop Fusion**\nThis concept refers to the **optimization of multiple operations in a stream pipeline**. Instead of performing each operation separately for all elements, Streams combine operations to iterate through the data only once, saving time and resources.\n\n#### Example:\n```java\nList\u003cInteger\u003e numbers = Arrays.asList(1, 2, 3, 4, 5);\n\nint result = numbers.stream()\n        .filter(n -\u003e n % 2 == 0) // Keep only even numbers\n        .map(n -\u003e n * 2)         // Double each number\n        .reduce(0, Integer::sum); // Sum them up\n\nSystem.out.println(\"Result: \" + result);\n```\n\n#### **How it works (Fusion):**\n1. Instead of filtering, mapping, and reducing in separate passes, the stream processes each element through all operations in one go.\n2. This reduces memory usage and improves performance.\n\n---\n\n### **2. Short-Circuiting Operations**\nThese operations terminate the stream pipeline early, without processing all elements, if the result is already determined.\n\n#### **Types of Short-Circuiting:**\n1. **Terminal Operations**: Stop processing when a result is found.\n   - Example: `findFirst()`, `findAny()`, `anyMatch()`, `allMatch()`, `noneMatch()`.\n   \n   ```java\n   boolean hasEven = numbers.stream()\n           .anyMatch(n -\u003e n % 2 == 0); // Stops as soon as it finds one even number\n   System.out.println(\"Has Even? \" + hasEven);\n   ```\n\n2. **Limit Operations**: Restrict the number of elements processed.\n   - Example: `limit(n)`, `takeWhile(predicate)`, `dropWhile(predicate)`.\n   \n   ```java\n   List\u003cInteger\u003e limited = numbers.stream()\n           .limit(3) // Only take the first 3 elements\n           .collect(Collectors.toList());\n   System.out.println(\"Limited: \" + limited);\n   ```\n\n---\n\n### **3. Laziness**\nStreams are **lazy**, meaning intermediate operations (like `filter`, `map`) are **not executed until a terminal operation** (like `collect`, `reduce`) is invoked.\n\n#### Example:\n```java\nStream\u003cInteger\u003e stream = numbers.stream()\n        .filter(n -\u003e {\n            System.out.println(\"Filtering: \" + n);\n            return n % 2 == 0;\n        });\n\nSystem.out.println(\"No terminal operation yet!\");\n\n// Terminal operation triggers execution\nstream.collect(Collectors.toList());\n```\n\n#### Output:\n```\nNo terminal operation yet!\nFiltering: 2\nFiltering: 4\n```\n\n---\n\n### **4. Non-Reusability**\nStreams can be **consumed only once**. Once a terminal operation is executed, the stream pipeline is closed, and you cannot reuse it.\n\n#### Example:\n```java\nStream\u003cInteger\u003e stream = numbers.stream();\nstream.filter(n -\u003e n % 2 == 0).collect(Collectors.toList());\n\n// This will throw an exception\nstream.filter(n -\u003e n \u003e 2).collect(Collectors.toList());\n```\n\n#### Output:\n```\nException: IllegalStateException: stream has already been operated upon or closed\n```\n\n---\n\n### **5. Stateless vs. Stateful Operations**\n1. **Stateless Operations**: Don't rely on previously processed elements.\n   - Examples: `filter`, `map`, `flatMap`.\n   \n   ```java\n   numbers.stream()\n           .filter(n -\u003e n \u003e 2) // Stateless\n           .forEach(System.out::println);\n   ```\n\n2. **Stateful Operations**: Depend on the entire data set or previous elements.\n   - Examples: `distinct`, `sorted`, `limit`.\n\n   ```java\n   numbers.stream()\n           .distinct() // Requires checking all elements for uniqueness\n           .forEach(System.out::println);\n   ```\n\n---\n\n### **6. Memory Efficiency**\nStreams do not hold elements in memory unless required (e.g., for `sorted`, `distinct`). They process elements **one-by-one** in pipelines, making them memory-efficient.\n\n#### Example:\nProcessing a very large dataset:\n```java\nStream\u003cInteger\u003e infiniteStream = Stream.iterate(1, n -\u003e n + 1)\n        .limit(1_000_000); // Stream only processes up to the limit\n```\n\n---\n\n### **7. Parallel Streams**\nStreams can be executed in parallel for better performance on multi-core systems. However, parallelism may introduce overhead and should be used judiciously.\n\n#### Example:\n```java\nint sum = numbers.parallelStream()\n        .filter(n -\u003e n % 2 == 0)\n        .mapToInt(Integer::intValue)\n        .sum();\n\nSystem.out.println(\"Sum: \" + sum);\n```\n\n---\n\n### **8. Stream Pipeline Architecture**\n- **Source**: Data source (e.g., List, Set, Array).\n- **Intermediate Operations**: Lazily transform the stream (e.g., `filter`, `map`).\n- **Terminal Operation**: Executes the pipeline and produces a result (e.g., `collect`, `reduce`).\n\n---\n\n\n## IntStream Operations\n\n- IntStream is a specialized stream for handling sequences of primitive `int` values. Below are some common operations we can perform with IntStream:\n\n### Creating an IntStream\n\n```\nimport java.util.stream.IntStream;\n\npublic class IntStreamExample {\n    public static void main(String[] args) {\n        IntStream intStream = IntStream.of(1, 2, 3, 4, 5);\n        \n        // Print all elements\n        intStream.forEach(System.out::println);\n\n\n\n int sum = IntStream.of(1, 2, 3, 4, 5)\n                           .sum();\n        System.out.println(\"Sum: \" + sum);\n\n\n double average = IntStream.of(1, 2, 3, 4, 5)\n                                  .average()\n                                  .orElse(0.0);\n        System.out.println(\"Average: \" + average);\n\n\n\n   IntStream stream = IntStream.of(1, 2, 3, 4, 5);\n\n        int max = stream.max().orElseThrow();\n        int min = IntStream.of(1, 2, 3, 4, 5).min().orElseThrow();\n        \n        System.out.println(\"Max: \" + max);\n        System.out.println(\"Min: \" + min);\n\n\n  int sum = IntStream.of(1, 2, 3, 4, 5)\n                           .reduce(0, Integer::sum);\n        System.out.println(\"Sum: \" + sum);\n\n\n    }\n}\n\n\n\n\n\n```\n## Stream\u003cString\u003e Operations\n\n\n### Stream\u003cString\u003e handles sequences of String values and provides various operations for transformation and aggregation.\n- Creating a String Stream\n\n\n\n```\npublic class StringStreamExample {\n    public static void main(String[] args) {\n        Stream\u003cString\u003e stringStream = Stream.of(\"apple\", \"banana\", \"cherry\");\n        \n        // Print all elements\n        stringStream.forEach(System.out::println);\n\n\n List\u003cString\u003e fruits = Arrays.asList(\"apple\", \"banana\", \"cherry\");\n        \n        String result = fruits.stream()\n                              .collect(Collectors.joining(\", \"));\n        System.out.println(\"Joined: \" + result);\n\n  List\u003cString\u003e fruits = Arrays.asList(\"apple\", \"banana\", \"cherry\");\n        \n        List\u003cString\u003e uppercaseFruits = fruits.stream()\n                                             .map(String::toUpperCase)\n                                             .collect(Collectors.toList());\n        System.out.println(\"Uppercase: \" + uppercaseFruits);\n\n\n\n\n\nList\u003cString\u003e fruits = Arrays.asList(\"apple\", \"banana\", \"cherry\");\n        \n        List\u003cString\u003e longFruits = fruits.stream()\n                                        .filter(fruit -\u003e fruit.length() \u003e 5)\n                                        .collect(Collectors.toList());\n        System.out.println(\"Long Fruits: \" + longFruits);\n\n\n\n\n\nList\u003cString\u003e fruits = Arrays.asList(\"apple\", \"banana\", \"cherry\");\n        \n        long count = fruits.stream().count();\n        System.out.println(\"Count: \" + count);\n\n\n\n List\u003cString\u003e fruits = Arrays.asList(\"apple\", \"banana\", \"cherry\");\n        \n        Optional\u003cString\u003e firstFruit = fruits.stream().findFirst();\n        System.out.println(\"First: \" + firstFruit.orElse(\"None\"));\n\n\n List\u003cList\u003cString\u003e\u003e listOfLists = Arrays.asList(\n            Arrays.asList(\"apple\", \"banana\"),\n            Arrays.asList(\"cherry\", \"date\")\n        );\n        \n        List\u003cString\u003e flatList = listOfLists.stream()\n                                           .flatMap(List::stream)\n                                           .collect(Collectors.toList());\n        System.out.println(\"Flat List: \" + flatList);\n\n\n\n\n    }\n}\n\n\n\n\n\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashfaqbs%2Fjava-stream-lambdas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fashfaqbs%2Fjava-stream-lambdas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashfaqbs%2Fjava-stream-lambdas/lists"}