🛑 #Stop blindly using ArrayList<T>() and understand why ConcurrentModificationException is your friend. As Java developers, we use the Collection Framework daily. But we rarely stop to consider how it actually works under the hood—and that affects performance. Choosing the right structure—like ArrayList versus LinkedList—impacts your application’s speed and memory usage. This diagram visualizes how Java manages that data internally. Let’s break it down using real code: 1. ArrayList and the Cost of Dynamic Resizing ArrayList is excellent for random access, but it has to manage an underlying array. When it reaches capacity, Java must create a new, larger array and copy all the data over—an O(n) operation. The diagram shows: ArrayList -> Check Capacity -> Dynamic Resize -> MEMORY (Heap) How it looks in Java: import java.util.ArrayList; import java.lang.reflect.Field; public class ArrayListResizingDemo { public static void main(String[] args) throws Exception { // We initialize with a specific size. ArrayList<String> list = new ArrayList<>(5); System.out.println("1. New ArrayList created with capacity 5."); checkInternalCapacity(list); // Fill it up. The internal array size (5) matches the element count (5). System.out.println("\n2. Filling up capacity..."); for (int i = 0; i < 5; i++) { list.add("Element " + (i + 1)); } checkInternalCapacity(list); // The next addition triggers "Dynamic Resize." System.out.println("\n3. Adding the 6th element (triggers dynamic resize)..."); list.add("Element 6"); // The underlying array has now grown (~50%). checkInternalCapacity(list); } /** Helper function (uses Reflection, not for production!). */ private static void checkInternalCapacity(ArrayList<?> list) throws Exception { Field dataField = ArrayList.class.getDeclaredField("elementData"); dataField.setAccessible(true); Object[] internalArray = (Object[]) dataField.get(list); System.out.println(" --> Current internal array size: " + internalArray.length); System.out.println(" --> Number of actual elements stored: " + list.size()); } } #java #springboot
ConcurrentModificationException and ArrayList Performance
More Relevant Posts
-
🔹 What is Idempotency? An operation is idempotent if calling it multiple times gives the same result as calling it once. Example: First request → Order created ✅ Duplicate request → No new order ❌ (returns same response) 🔹 Common Approach in Spring Boot ✅ Use Idempotency Key (Best Practice) Client sends a unique key in header: Idempotency-Key: abc123 Server stores and checks it. 🔹 Example Implementation (Spring Boot) 1. Entity to store request Java @Entity public class IdempotencyRecord { @Id private String idempotencyKey; private String response; private int statusCode; // getters & setters } 2. Repository Java public interface IdempotencyRepository extends JpaRepository<IdempotencyRecord, String> { } 3. Service Logic Java @Service public class PaymentService { @Autowired private IdempotencyRepository repository; public ResponseEntity<String> processPayment(String key, String request) { Optional<IdempotencyRecord> existing = repository.findById(key); // ✅ If already processed, return stored response if (existing.isPresent()) { IdempotencyRecord record = existing.get(); return ResponseEntity.status(record.getStatusCode()) .body(record.getResponse()); } // ✅ Process actual logic String response = "Payment Successful for request: " + request; // Save result IdempotencyRecord record = new IdempotencyRecord(); record.setIdempotencyKey(key); record.setResponse(response); record.setStatusCode(200); repository.save(record); return ResponseEntity.ok(response); } } 4. Controller Java @RestController @RequestMapping("/payments") public class PaymentController { @Autowired private PaymentService service; @PostMapping public ResponseEntity<String> makePayment( @RequestHeader("Idempotency-Key") String key, @RequestBody String request) { return service.processPayment(key, request); } } 🔹 How It Prevents Duplicate Scenario Result First request with key abc123 Process & save Second request with same key Return saved response (no duplicate) 🔹 Important Points ✔ Use unique key per request (UUID recommended) ✔ Store response + status ✔ Add expiry (TTL) for old keys ✔ Use database unique constraint to avoid race conditions ✔ Combine with @Transactional for safety 🔹 Advanced (Production Ready) Use Redis for faster lookup Add locking to avoid parallel duplicate execution Store full request hash for validation
To view or add a comment, sign in
-
-
Here are some tricky Java fundamental questions 🔹 Primitive Data Types & Variables Why is Java called a statically typed language? How is it different from a strongly typed language? Why can variable names start only with $, _, or letters? Why not digits or symbols like @? 🔹 Type Promotion & Casting What is type promotion in Java? Why does this fail? byte a = 10; byte b = 20; byte c = a + b; 👉 Why is byte + byte automatically converted to int? Why does this work? int x = 10; long y = x; But this doesn’t: long x = 10; int y = x; What are the limitations of downcasting? When does data loss happen? 🔹 Static Concepts When are static variables initialized in Java? When does a static block execute? Can it run multiple times? 🔹 Floating Point (Most misunderstood topic) How are float and double stored in memory? Why don’t we use float much in real-world applications? Why does this happen? float a = 0.1f; float b = 0.2f; System.out.println(a + b); Why does 0.7f print as 0.699999... internally? What does System.out.printf("%.2f", 0.7f); actually do? Does double completely fix floating-point precision issues? 🔹 BigDecimal & Precision How does BigDecimal handle precision differently from float/double? Why is this bad? new BigDecimal(0.1) and why is this correct? new BigDecimal("0.1") If BigDecimal is perfect, why don’t we use it everywhere? 🔹 BigInteger & Overflow When do we use BigInteger instead of long? What happens when a number exceeds long range? 🔹 Bonus Core Concepts What happens when primitives overflow? Where are primitives stored: stack or heap? What is the default value of primitive variables vs local variables? Is Java truly pass-by-value even for primitives? 🔥 Critical Understanding Question 👉 Why does Java convert byte + byte into int automatically? Because in Java, any arithmetic on byte/short/char is internally promoted to int for performance and safety, so operations are done at a CPU-efficient level and then must be explicitly narrowed back if needed. #Java #JavaBasics #Programming #CodingInterview #SoftwareEngineering #Developers #ComputerScience #FloatingPoint #BigDecimal #CoreJava
To view or add a comment, sign in
-
I spent my first 2 years writing Java the hard way. Verbose. Fragile. Full of boilerplate I didn't need. Then I discovered these 5 features — and I've never looked back. If you're a Java developer, save this post. 🔖 --- 1. Optional — stop pretending null doesn't exist How many NullPointerExceptions have you chased at midnight? I lost count. Then I started using Optional properly. Before: String city = user.getAddress().getCity(); // NPE waiting to happen After: Optional.ofNullable(user) .map(User::getAddress) .map(Address::getCity) .orElse("Unknown"); Clean. Safe. Readable. No more defensive if-null pyramids. --- 2. Stream API — ditch the for-loops I used to write 15-line loops to filter and transform lists. Streams cut that to 2 lines — and made the intent crystal clear. Before: List<String> result = new ArrayList<>(); for (User u : users) { if (u.isActive()) result.add(u.getName()); } After: List<String> result = users.stream() .filter(User::isActive) .map(User::getName) .collect(toList()); Once you think in streams, you can't go back. --- 3. Records — goodbye boilerplate data classes How many times have you written a POJO with getters, setters, equals, hashCode, and toString? Java Records (Java 16+) killed all of that in one line. Before (~50 lines): public class User { private String name; private String email; // getters, setters, equals, hashCode, toString... 😩 } After (1 line): public record User(String name, String email) {} Your DTOs and value objects will thank you. --- 4. var — let the compiler do the obvious work I was skeptical at first. Felt "un-Java-like." But for local variables, var makes code dramatically less noisy. Before: HashMap<String, List<Order>> map = new HashMap<String, List<Order>>(); After: var map = new HashMap<String, List<Order>>(); Still strongly typed. Just less noise. Use it for local scope — not method signatures. --- 5. CompletableFuture — async without the headache Threading used to terrify me. CompletableFuture changed that. Chain async tasks, handle errors, combine results — all without callback hell. CompletableFuture.supplyAsync(() -> fetchUser(id)) .thenApply(user -> enrichWithOrders(user)) .thenAccept(result -> sendResponse(result)) .exceptionally(ex -> handleError(ex)); Readable async Java. Yes, it's possible. --- I wasted months writing verbose, fragile code because nobody told me these existed. Now you have no excuse. 😄 Which of these changed your code the most? Drop a number (1–5) in the comments 👇 — I read every one. #Java #SoftwareEngineering #FullStackDeveloper #CleanCode #SpringBoot #CodingTips
To view or add a comment, sign in
-
🛡️ Shipped a major upgrade to AI-MR-Reviewer — a GitHub App that reviews your Java pull requests the moment you open them. Inline comments on the diff. Three severity levels. Zero configuration. Built for teams who want fast feedback without setting up SonarQube. What lands in this release: 19 hand-tuned Java rules. 🔴 HIGH RISK — 9 rules - Empty catch blocks (silent exception swallowing) - printStackTrace() in production code - Broad catches — Exception / Throwable / RuntimeException - SQL injection in createQuery / prepareStatement (concat + String.format) - Hardcoded credentials (password / apiKey / authToken) - Thread.sleep() in non-test code - Resource leaks — FileReader / Socket without try-with-resources - String compared with == instead of .equals() - Raw generics — new ArrayList() without the diamond operator 🟡 MID RISK — 5 rules - System.out / System.err in production - Magic strings in local assignments - PascalCase class / interface / enum naming - Methods with more than 5 parameters (god-method signal) - new Date() — prefer java.time (Instant, LocalDateTime) 🔵 LOW RISK — 5 rules - Numbered method names (toResponse2, handler3) - Wildcard imports (import java.util.*) - Missing Javadoc on public API surfaces (Service / Controller / Facade) - Unresolved TODO / FIXME / HACK comments - Files left behind as "ClassName copy.java" Every rule is tuned for a low false-positive rate. JPA/Spring annotation attributes are whitelisted, so @Table(name = "user") will never show up as a "magic string". Common numeric suffixes — sha256, base64, int32, ipv4 — are excluded from the numbered-method rule. Under the hood: TypeScript · Node.js · Octokit · Express · Docker. Deployed on Hostinger. Reviews land within seconds of opening the PR. Next up: the same treatment for Python and PHP, plus a semantic layer on top of the regex foundation — equals()/hashCode() pairing, Optional misuse detection, and blocking calls inside reactive chains. If your team reviews Java PRs every day, this saves an hour per dev per week. DMs open. #Java #SpringBoot #CodeReview #DeveloperTools #StaticAnalysis #OpenSource #DevEx
To view or add a comment, sign in
-
-
Today’s session was a deep dive into the Java Collections Framework, with a strong focus on the evolution from traditional Arrays to the more flexible and powerful ArrayList. Below is a structured summary of the key concepts explored: 🔹 Limitations of Arrays: 1)Fixed Size 2)Arrays have a predefined capacity, making them unsuitable for scenarios involving dynamic or growing datasets. 3)Homogeneous Data Storage 4)Arrays typically store elements of a single data type, limiting flexibility when managing diverse data. 5)Contiguous Memory Requirement 6)Arrays require a continuous block of memory. For large datasets (e.g., 1 crore elements), this can lead to memory allocation issues or system performance degradation. )Performance Bottlenecks: Operations like duplicate detection using nested loops result in O(n²) time complexity, which does not scale well for large inputs. 🔹 Java Collections Framework Overview: -Introduction: Launched in 1997 with JDK 1.2 to provide efficient, reusable data structures. -Architects: Designed primarily by Joshua Bloch, with contributions from Neil Gafter. -Purpose: Offers a standardized set of interfaces and classes to store, manipulate, and process data without reinventing core logic. -Evolution: Java transitioned from Sun Microsystems to Oracle starting with JDK 7, which now maintains the platform. 🔹 ArrayList: Internal Working & Behavior: -Underlying Structure: A dynamically resizable array. -Default Initial Capacity: 10 elements. -Resizing Formula: -New Capacity = (Current Capacity × 1.5) + 1 -Resizing Cost: A costly operation involving memory reallocation and copying elements to a new array. Key Characteristics: -Heterogeneous Storage: Can store different types of objects. -Insertion Order Preserved -Allows Duplicates and Null Values -Object-Only Storage: Primitive types are automatically converted to wrapper objects via autoboxing. 🔹 Technical Hierarchy & Usage: Class Hierarchy: ArrayList → AbstractList → List → SequencedCollection → Collection → Iterable Element Access: -Use size() instead of .length -Use get(index) instead of [] Traversal Techniques: -Traditional for loop: Ideal for index-based access (e.g., reverse iteration) -Enhanced for-each loop: Clean and efficient for sequential traversal. Example: ArrayList<Integer> numbers = new ArrayList<>(); numbers.add(10); numbers.add(20); numbers.add(30); for (Integer num : numbers) { System.out.println(num); } -Iterator: Cursor-based traversal inherited from Iterable. Mastering these fundamentals is a crucial step toward building high-performance Java applications and excelling in technical interviews 🚀💻. #JAVA #PROGRAMMIG #TapAcademy #HarshithT
To view or add a comment, sign in
-
Day 18 —#100DaysJava today Java connected to a database for the first time. That felt real. ☕ For 17 days I have been writing Java code that runs and stops. Data lives for one second and disappears. Today I learned JDBC — and now data can actually be saved, fetched, updated, and deleted. Permanently. This is where Java starts feeling like a real backend language. --- What is JDBC? JDBC stands for Java Database Connectivity. It is the bridge between your Java code and a database like MySQL or PostgreSQL. Without JDBC — Java cannot talk to a database. With JDBC — Java can run SQL queries directly from your code. --- How it works — 5 simple steps every Java developer should know: Step 1 — Load the driver Tell Java which database you are connecting to. Class.forName("com.mysql.cj.jdbc.Driver"); Step 2 — Create a connection Give the database URL, username, and password. Connection con = DriverManager.getConnection(url, user, password); Step 3 — Create a statement Prepare the SQL query you want to run. Statement st = con.createStatement(); Step 4 — Execute the query Run SELECT, INSERT, UPDATE, or DELETE. ResultSet rs = st.executeQuery("SELECT * FROM users"); Step 5 — Close the connection Always close after use. Never leave it open. con.close(); --- The thing that surprised me — PreparedStatement vs Statement. Statement is simple but dangerous. If you put user input directly into a SQL query, a hacker can inject malicious SQL and destroy your database. This is called SQL Injection. PreparedStatement is safe. You use placeholders — ? — and Java handles the input safely. Every real application uses PreparedStatement. Never Statement with user input. PreparedStatement ps = con.prepareStatement("SELECT * FROM users WHERE id = ?"); ps.setInt(1, userId); --- Also learned today — CRUD operations: CREATE → INSERT INTO READ → SELECT UPDATE → UPDATE SET DELETE → DELETE FROM These four operations are the foundation of every backend application ever built. --- What clicked today — every app I have ever used stores data somewhere. Instagram saves your photos. Zomato saves your orders. Swiggy saves your address. JDBC is the layer that makes that possible in Java. 17 days in. The journey is getting more real every single day. 💪 Day 1 ................................................... Day 18 To any backend developer reading this — what was your first database connection moment like? Did it feel as satisfying as it did for me today? 🙏 #Java #JDBC #Database #MySQL #BackendDevelopment #100DaysOfJava #JavaDeveloper #LearningInPublic #100DaysOfCode #SQL #WebDevelopment #Programming
To view or add a comment, sign in
-
🔹 Adding Employee in a #Set & Why equals() and hashCode() Matter 1️⃣ Why #equals() and #hashCode() Are Important * Set in Java does not allow duplicate elements. * Java determines duplicates using hashCode() and equals() methods. * If you don’t override them in your custom class (e.g., Employee), all objects are considered different, even if their data is same. ✅ Key Rule: * hashCode() → Determines the bucket/location in HashSet/HashMap. * equals() → Checks actual content equality. * Without overriding, your Set<Employee> may allow duplicates unexpectedly. 2️⃣ Employee Class (With equals & hashCode) import java.util.*; class Employee { private int id; private String name; public Employee(int id, String name) { this.id = id; this.name = name; } // Generate equals() & hashCode() using id (unique identifier) @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Employee)) return false; Employee employee = (Employee) o; return id == employee.id; } @Override public int hashCode() { return Objects.hash(id); } @Override public String toString() { return "Employee{id=" + id + ", name='" + name + "'}"; } } 🔹 Key Idea * hashCode() → Determines which bucket an object goes into in hash-based collections (like HashSet, HashMap). * equals() → Checks actual equality between objects in the same bucket. Think of it as a two-step check: first hashCode() (fast), then equals() (exact match) What happens internally: * Java calls hashCode() of the new object → finds the bucket. * If the bucket is empty → object added directly. * If the bucket has objects → Java calls equals() with each object in the bucket to check for duplicates. * If equals() returns true → object is not added. * If equals() returns false → object is added to the bucket. #JavaDeveloper #CoreJava #Java8 #JavaProgramming #OpenToWork #TechLearning #SpringBoot #SpringFramework #BackendDeveloper #Microservices #RESTAPI #JavaBackend #LearnJava
To view or add a comment, sign in
-
Day 19 —#100DaysJava today I built my first real Java project. Not a tutorial. Not a copy-paste. A working backend system I built myself. ☕ It is a Login and Registration System using JDBC, DAO pattern, and MySQL. Users can register. Users can login. Data is stored in a real database. That is a real backend application. --- Here is everything I used to build it — and what each piece does: JDBC — the bridge between Java and MySQL. Without this, Java cannot talk to a database at all. PreparedStatement — the safe way to run SQL queries. Prevents SQL Injection attacks. Every real company uses this. Never use plain Statement with user input. DAO Pattern — stands for Data Access Object. This separates your database logic from your business logic. Your main code does not need to know HOW data is saved — just that it is saved. Clean, organized, professional. Transactions — if two database operations need to happen together, transactions make sure either BOTH succeed or NEITHER happens. This is how bank transfers work. Either money leaves account A AND enters account B — or nothing happens at all. Batch Processing — instead of running 100 INSERT queries one by one, batch them and run all 100 in one go. Much faster. This matters in production systems handling real traffic. Connection Pooling — instead of creating a new database connection for every request, reuse existing connections. HikariCP is the industry standard for this. Every Spring Boot application uses it under the hood. --- Project structure I followed: model — User.java (the data object) dao — UserDAO interface + UserDAOImpl (database logic) util — DBConnection (reusable connection) Main — runs the program This is the same structure used in real enterprise Java projects. --- What I learned beyond the code: Storing plain passwords is dangerous. Never do it. BCrypt hashing is the industry standard — that is my next step. Always close your database connection. Use try-with-resources so it closes automatically even if something crashes. 100% coverage does not mean bug-free. Testing edge cases — null email, wrong password, duplicate registration — is what separates good developers from average ones. --- 19 days ago I did not know what a variable was in Java. Today I built a backend system with a real database, real security concepts, and real architecture patterns. The only thing that got me here — showing up every single day. Day 1 .......................... Day 19 To any developer reading this — what was the first real project you built? Drop it below. I would love to know. 🙏 #Java #JDBC #MySQL #DAOPattern #BackendDevelopment #100DaysOfJava #JavaDeveloper #LearningInPublic #100DaysOfCode #Database #CleanCode #SoftwareEngineering #ProjectBuilding
To view or add a comment, sign in
-
🚨 Java Records are NOT what most developers think they are When I first heard about records in Java, I assumed: “Oh… just another way to write POJOs faster.” That’s only scratching the surface — and honestly, a bit misleading. Let’s clear this up. 💡 The real confusion: What does “record” even mean? In everyday thinking, a record feels like: “Something I can create, update, and modify” But in system design, a record actually means: A fixed snapshot of data at a point in time Think about: Bank transactions Audit logs API responses These are not meant to be edited. They are meant to be: ✔ Created ✔ Read ✔ Transferred ✔ Compared 👉 That’s the mindset Java records are built on. 🔥 The biggest mindset shift Most developers think: “Object = something I can modify anytime.” But with records: Object = frozen snapshot of data That’s a fundamental design shift. ⚠️ Why not just use mutable classes? Because mutation introduces problems: Hidden side effects Thread-safety issues Debugging headaches (“Who changed this?”) Records eliminate these by design. 🧠 What problem do records actually solve? Not just reducing boilerplate. They solve: Data correctness + predictability Once created, a record: ✔ Cannot be partially modified ✔ Cannot be accidentally corrupted ✔ Behaves consistently across threads 🔷 Example Traditional class: public class User { private Long id; private String name; public void setName(String name) { this.name = name; } } Record: public record User(Long id, String name) {} This isn’t just shorter — it’s safer by design. 🚀 Where records shine Records are perfect for: DTOs API responses Read models Projections Why? Because these are all: data snapshots moving between layers ❗ Important: Records are NOT for updates In modern architecture: Updates belong to → Entities / Domain layer Records belong to → Query / Read side This aligns with patterns like: 👉 CQRS (Command Query Responsibility Segregation) 🧩 Final takeaway Java didn’t just reduce boilerplate… It introduced a new way to think about data. Records are not “better POJOs.” They are: Immutable, value-based data carriers designed for correctness and clarity. If you're still treating records like mutable objects… You're missing the whole point. #Java #JavaRecords #SpringBoot #BackendDevelopment #SystemDesign #Programming #SoftwareEngineering #CleanCode #Concurrency #JavaDeveloper
To view or add a comment, sign in
-
🔥 “Java records are stupid.” — Let’s unpack that (properly) I recently came across a hot take: “Java records are pointless. We needed mutable data classes and value classes for performance — records solve neither properly.” At first glance, that frustration feels valid. But it’s actually mixing two completely different problems. 🧠 The confusion: 2 problems, 1 expectation Problem 1️⃣ Too much boilerplate for simple data classes Problem 2️⃣ Performance overhead of object identity (heap, GC, etc.) ❌ Expectation One feature should solve both ✅ Reality Java solved them separately 🟢 What Java Records actually solve Records are about: Correctness, not convenience They guarantee: immutable state consistent equals() / hashCode() no accidental mutation clear “this is just data” semantics Example public record User(String name, int age) {} This is not just shorter syntax. 👉 It’s a contract: state cannot change Equality is value-based safe in concurrency predictable in collections 🔵 What records are NOT solving Records are NOT: high-performance value types memory-optimized objects replacements for all POJOs That problem is being addressed by: 👉 Project Valhalla ⚠️ The “mutable record” argument (simplified) A common suggestion: “Records should have been mutable with setters—like Lombok @Data but built into Java.” Sounds reasonable… until you look deeper 👇 🧠 If records were mutable… what would they actually be? class User { String name; int age; } vs record User(String name, int age) {} If records allowed setters: user.setName("newName"); 👉 Then there’s no real difference between a class and a record. So the feature becomes: ➡️ Just syntax sugar ➡️ Not a meaningful language improvement ⚠️ The real issue: mutation breaks guarantees User user = new User("Tharun", 25); map.put(user, "data"); user.setName("NewName"); 👉 Now the object changes after being used as a key. Result: Hash-based collections can break Data becomes inconsistent Bugs become very hard to trace 🔒 Why immutability matters By making records immutable, Java guarantees: Once created → state never changes equals() and hashCode() stay valid Safe to use in collections No hidden side effects 💡 The key design decision Java didn’t want: “Just a shorter class” It wanted: “A reliable, predictable data carrier” That’s why records are: immutable value-based constructor-driven 🧠 The real takeaway Records didn’t fail. They just solved a different problem than you expected. 🔥 One-line perspective shift Records are about making illegal states unrepresentable — not making objects faster. 🎯 Final thought If you expect records to improve performance, you’ll be disappointed. If you use them to enforce correctness and immutability → they’re incredibly powerful. #Java #JavaRecords #SoftwareEngineering #BackendDevelopment #CleanCode #SystemDesign #Programming #Developers #TechDiscussion #JavaValhalla
To view or add a comment, sign in
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