❗ Even Java record Don’t Make Maps Immutable It’s a common misconception that Java record automatically provides immutability for the fields. Actually, Java record doesn't make mutable objects (like Map, List, Set) immutable. 💡 Example: A Record with a Map @Builder public record Summary(Map<String, Address> addressMap) { } Then try this: var summary = Summary.builder() .addressMap(existingMap) .build(); var map = summary.addressMap(); map.put("newAddress", Address.builder().street("main").build()); // ❗ This works! ✔ No exception is thrown addressMap() simply returns the internal Map reference. Since Map is mutable, external code can still change the record’s internal state. This means: Records prevent reassignment, but they do not prevent mutation of contained objects. 🔒 How to Make the Map Truly Immutable To ensure callers can’t mutate your internal Map, you must explicitly defensively copy it. You can do this using the compact constructor as shown in the example, which runs after the canonical constructor is generated: @Builder public record Summary(Map<String, Address> addressMap) { public Summary { // Defensive copy to ensure immutability addressMap = (addressMap == null) ? Map.of() : Map.copyOf(addressMap); } } ✔ Why this works Map.copyOf(...) creates a new, unmodifiable map. Any attempt to modify the returned map will throw UnsupportedOperationException. Your record no longer exposes internal mutable state. var summary = Summary.builder() .addressMap(existingMap) .build(); summary.addressMap().put("x", someAddress); // → UnsupportedOperationException 📝 Summary Records do not make mutable fields immutable. final only protects references, not the objects they reference. If a record contains a Map, List, or Set, callers can mutate it unless you: Wrap it with Map.copyOf / List.copyOf / Set.copyOf The compact constructor is the cleanest way to enforce immutability in records. #Java #MyWorkExperience
Java Records Don't Make Maps Immutable
More Relevant Posts
-
🚀 Java Series – Day 22 📌 Collection Framework in Java (List, Set, Map) 🔹 What is it? The Collection Framework in Java is a set of classes and interfaces used to store and manipulate groups of objects efficiently. It provides ready-made data structures to simplify development. Main parts: • List • Set • Map 🔹 Why do we use it? It helps manage large amounts of data easily with built-in methods like sorting, searching, and iteration. For example: In an e-commerce app, we can store: • Product list → List • Unique categories → Set • Product ID & details → Map 🔹 List vs Set vs Map: • List - Ordered collection - Allows duplicates - Example: ArrayList, LinkedList • Set - Unordered collection - No duplicates allowed - Example: HashSet, TreeSet • Map - Stores key-value pairs - Keys are unique - Example: HashMap, TreeMap 🔹 Example: import java.util.*; public class Main { public static void main(String[] args) { // List List<String> list = new ArrayList<>(); list.add("Apple"); list.add("Apple"); // duplicates allowed // Set Set<String> set = new HashSet<>(); set.add("Apple"); set.add("Apple"); // ignored // Map Map<Integer, String> map = new HashMap<>(); map.put(1, "Apple"); map.put(2, "Banana"); System.out.println(list); System.out.println(set); System.out.println(map); } } 💡 Key Takeaway: Use List for ordered data, Set for unique data, and Map for key-value pairs. What do you think about this? 👇 #Java #Collections #JavaDeveloper #Programming #BackendDevelopment
To view or add a comment, sign in
-
-
☄️🎊Day 67 of 90 – Java Backend Development 🎆 🧨 In Java, immutability means that once a String object is created, its value cannot be changed. If you try to "modify" a string—for example, by appending text—Java actually creates a brand-new string object in memory rather than altering the original one. This design choice wasn't accidental; it’s a foundational pillar of how Java handles memory, security, and performance. 👉 Core Reasons for Immutability 👉 1. The String Constant Pool Java uses a special memory area called the String Pool. When you create a string literal, the JVM checks if that value already exists in the pool. If it does, it returns a reference to the existing object instead of creating a new one. If strings were mutable, changing the value of one variable would secretly change the value for every other variable pointing to that same literal, leading to unpredictable bugs. 👉 2. Security Strings are used heavily in sensitive areas of Java programming, such as: Database URLs and credentials. Network connections. File paths. Class loading. If a string were mutable, an untrusted piece of code could receive a reference to a file path, verify it has permission, and then sneakily change the path before the file is actually opened. Immutability ensures that once a value is validated, it stays that way. 👉 3. Thread Safety Because a String cannot change, it is inherently thread-safe. You can share a single string across multiple threads without worrying about synchronization or data corruption. This significantly simplifies concurrent programming in Java. 👉 4. Caching HashCodes In Java, strings are frequently used as keys in HashMap or elements in HashSet. The hashCode() of a string is calculated and cached the first time it's called. Since the string is immutable, the hash code will never change. This makes lookups in collections incredibly fast, as the JVM doesn't have to re-calculate the hash every time the string is accessed. #String #Immutability #HashCodes
To view or add a comment, sign in
-
-
❗ Java Bug: Why final List or final Map Is Not Immutable in Java Recently, I ran into immunity issue in Java, which I've never paid attention before. It’s a common misconception that marking a field final automatically makes it “safe” or “immutable.” Unfortunately, this is not true when the field holds a mutable object such as a List or Map. Let’s look at this Java class: @Getter @Builder public class Plan { private final List<String> toDoList; } At first glance, this looks immutable: the field is final, and there is no setter. But watch what happens: List<String> initialToDoList = new ArrayList<>(Arrays.asList("Buy groceries", "Read a book", "Exercise")); var plan = Plan.builder().toDoList(initialToDoList).build(); List<String> firstList = plan.getToDoList(); firstList.size()==3; firstList .add("Learn Java"); //No Exception Obtain list again AFTER adding the item: List<String> secondList = plan.getToDoList(); Now firstList.size()==4 and secondList.size()==4 firstList contains the newly added item 'Learn Java' secondList contains the newly added item 'Learn Java' ❇️ Conclusion: Summary object looks immutable from the outside, but its internal state can be changed at any time. That’s not immutability—that’s an illusion of immutability. I feel it's a Java Bug. If it's final, why not just make it immutable no matter if it's a collection or not 😂. #Java
To view or add a comment, sign in
-
What is a Java Class? Think of a class like a blueprint for a house. The blueprint itself is not a house—it is just a set of instructions that tells you how to build a house. Similarly, a class in Java is a blueprint that defines the structure and behavior of objects. It specifies what attributes an object should have and what actions it can perform. When you write a class, you are essentially saying, “Here is a template. Anyone who wants to create an object of this type should follow these rules.” The class does not exist in memory until you create an object from it. The object is the actual house built from the blueprint. The class is just the plan.
To view or add a comment, sign in
-
Core Java (Deep Concepts): 1️⃣ What happens internally in HashMap when two keys generate the same hash? Collision occurs. HashMap stores entries in buckets indexed by hash(key). Before Java 8: linked list. Java 8+: red-black tree if list grows beyond 8. equals() is checked for key match. 2️⃣ How does ConcurrentHashMap achieve thread safety? Fine-grained locking or CAS for writes. Reads mostly lock-free. Allows concurrent read/write without locking the entire map. 3️⃣ Difference between Synchronized Collections and Concurrent Collections: Synchronized: coarse-grained, single-thread access, e.g., Collections.synchronizedList. Concurrent: fine-grained, multiple threads can access, e.g., ConcurrentHashMap. 4️⃣ Volatile vs Synchronization: Volatile: ensures visibility only, no mutual exclusion. Synchronization: ensures visibility + mutual exclusion. 5️⃣ Explain Java Memory Model (JMM): Defines thread interactions via memory. Key concepts: main memory vs CPU cache, happens-before relationship, visibility with volatile, atomicity with synchronized. 6️⃣ Difference between Future and CompletableFuture: Future: waits for the result, limited. CompletableFuture: async, chaining, handles exceptions, supports multiple futures. 7️⃣ Parallel Streams: Executes operations in parallel via ForkJoinPool. Avoid when shared mutable state exists, small datasets, or ordering matters. 8️⃣ ClassLoader in Java: Loads class bytecode into JVM. Types: Bootstrap, Extension, System/Application, Custom. 9️⃣ Sealed Classes Allows developers to restrict which classes can extend or implement a class or interface, improving domain modeling and security. 🔟 What is a record in Java? A record is a special type of class used to model immutable data objects with very little boilerplate code. It automatically generates: constructor getters equals() hashCode() toString()
To view or add a comment, sign in
-
Top 5 Causes of Memory Leaks in Java 🚀 Memory leaks in Java may not cause immediate crashes, but they can significantly degrade performance over time. These leaks occur when objects are no longer needed but are still referenced, preventing Garbage Collection from cleaning them up. The top causes of memory leaks in Java include: 1. Unused objects still referenced – Objects remain in memory due to active references. 2. Static collections – Data continues to grow because static variables persist for the entire application lifecycle. 3. Incorrect equals() and hashCode() – This can lead to duplicate entries in collections like HashMap. 4. Unclosed resources – Resources such as database connections, streams, or sessions are not properly closed. 5. Non-static inner classes – These classes hold implicit references to outer class objects. Understanding these causes can help developers write more efficient Java applications.
To view or add a comment, sign in
-
-
I've been playing with Java applications recently, and the first thing you deal with is memory. Java (via the Xmx parameter) grabs all its allocated memory at startup, even though the JVM doesn't actually *need* it all right away. From the OS's point of view, it's fully consumed immediately. Kind of annoying. Most other runtimes do the opposite: use memory as needed, give it back when you don't. Golang, PHP, and others work this way. And to be clear, this is a runtime thing, not a language thing. Common Lisp is a great example; its most popular runtime uses memory on demand, but there's a Common Lisp runtime on the JVM that behaves like... well, Java. Databases do something similar too. PostgreSQL, MySQL, Redis; they all have this concept of reserved memory. It's not quite the same (it's about max memory for caches that ramp up over time), but the pattern rhymes. The thing I actually appreciate about Java's approach: you fail fast. If you don't have enough memory, you know at boot, not 3 hours into production when traffic spikes. Databases and on-demand runtimes give you that nasty surprise later. Now, the trade-off. If you're running 5-10 apps on the same host and assuming not all of them peak at the same time, Java's "grab everything now" model is wasteful. But we're increasingly moving toward isolated environments; containers, single-process setups, reserved resources. In that world, claiming all your memory upfront actually fits pretty well. ...until you zoom out and remember that container still runs on a host with other containers. And you're back to the same trade-off. I'm honestly torn. Both models have real advantages, and I don't think there's a clean winner.
To view or add a comment, sign in
-
🚀 Day 4/100 — If-Else & Switch in Java 🚦 Conditions are the brain of a program. They help your program make decisions based on different situations. In Java, the most common decision-making statements are if, else if, else, and switch. 🔹 If-Else Statement Used when a program needs to execute code based on a condition. Example: int age = 20; if(age >= 18){ System.out.println("Eligible to vote"); }else{ System.out.println("Not eligible to vote"); } ✔ If the condition is true, the first block runs. ✔ If it's false, the else block runs. 🔹 Else If Ladder Used when there are multiple conditions. ⚠️ Important: Java checks conditions top to bottom, and once one condition becomes true, the rest are skipped. Example: int marks = 85; if(marks >= 90){ System.out.println("Grade A"); } else if(marks >= 75){ System.out.println("Grade B"); } else if(marks >= 60){ System.out.println("Grade C"); } else{ System.out.println("Grade D"); } 🔹 Switch Statement Used when comparing one variable with multiple values. Example: int day = 3; switch(day){ case 1: System.out.println("Monday"); break; case 2: System.out.println("Tuesday"); break; case 3: System.out.println("Wednesday"); break; default: System.out.println("Invalid day"); } ⚠️ Important: If you forget break, Java will execute all cases after that one (called fall-through). Example without break: int num = 1; switch(num){ case 1: System.out.println("One"); case 2: System.out.println("Two"); case 3: System.out.println("Three"); } Output: One Two Three 🔴 Mini Example — Pass or Fail int marks = 40; if(marks >= 35){ System.out.println("Pass"); }else{ System.out.println("Fail"); } 🎯 Challenge: Build a Grade Calculator using if-else. Example logic: 90+ → Grade A 75–89 → Grade B 60–74 → Grade C Below 60 → Grade D Drop your solution in the comments 👇 #Java #CoreJava #100DaysOfCode #JavaLearning #ProgrammingJourney
To view or add a comment, sign in
-
-
💻 Getting Started with File Input/Output in Java When we first learn Java, most of our programs interact through the console using: System.in (input) System.out (output) But real-world programs often need to read from and write to files 📂 — here’s a simple breakdown of how that works. 📖 Reading from a File To read data from a file, we use the Scanner class along with the File class. First, create a file reference: File file = new File("input.txt"); Scanner sc = new Scanner(file); Now you can read data using methods like: next() nextInt() nextDouble() Example: while (sc.hasNextDouble()) { double value = sc.nextDouble(); // process value } ✍️ Writing to a File To write data, we use the PrintWriter class: PrintWriter out = new PrintWriter("output.txt"); out.println("Hello, people!"); ✔️ If the file exists → it gets overwritten ✔️ If it doesn’t exist → a new file is created ⚠️ Don’t Forget to Close! sc.close(); out.close(); Closing is important because: 👉 If you don’t close the writer, some data may never actually get written to the file. 🤔 Why pass File to Scanner but not PrintWriter? If you do: Scanner sc = new Scanner("input.txt"); It reads the string "input.txt", not the file contents. So for reading, you must pass a File object. For writing, PrintWriter can directly take the file path. 🔍 Understanding next() next() reads tokens, not lines. A token = any sequence of characters separated by whitespace (spaces, tabs, newlines). 🔧 Custom Delimiters You can control how input is split using useDelimiter() with regular expressions: sc.useDelimiter("[0-9]+"); 👉 This ignores digits and returns only non-digit sequences. 🔤 Reading Character by Character By default, Scanner reads word-by-word. To read one character at a time: sc.useDelimiter(""); while (sc.hasNext()) { char ch = sc.next().charAt(0); // process ch } Remember!!! Methods like nextInt() and nextDouble(): Skip whitespace before reading ❗ Do NOT consume the newline after the value 📚 Inspired by concepts from Cay Horstmann
To view or add a comment, sign in
More from this author
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development