Skip to content
Laviyx Learn

Try

Advanced Java Practice

Practise Java exceptions, file handling, generics, lambdas, streams, Optional and concurrency.

Advanced8 problemsUpdated

Review first: Exceptions, File Handling, Generics, Lambdas and Functional Interfaces, Streams API, Threads and Concurrency, Modern Java Features

  1. 1.Handle bad input

    Advanced

    For each of "42", "abc" and " 7 ", try Integer.parseInt and print the number or invalid. Then fix the third input by stripping spaces.

    Show hint

    parseInt throws NumberFormatException for text that is not exactly a number, including surrounding spaces.

    Show solution
    Java
    public class Main {
        public static void main(String[] args) {
            for (String text : new String[] {"42", "abc", " 7 "}) {
                try {
                    System.out.println(Integer.parseInt(text));
                } catch (NumberFormatException e) {
                    System.out.println("invalid: [" + text + "]");
                }
            }
            System.out.println(Integer.parseInt(" 7 ".strip()));
        }
    }
    Output
    42
    invalid: [abc]
    invalid: [ 7 ]
    7
  2. 2.A custom exception

    Advanced

    Create InsufficientFundsException extends RuntimeException. Write static double withdraw(double balance, double amount) that throws it when the amount is too large. Withdraw 200 and then 800 from 500, catching the error.

    Show hint

    Pass a message to super(...) in the exception's constructor.

    Show solution
    Java
    class InsufficientFundsException extends RuntimeException {
        InsufficientFundsException(String message) {
            super(message);
        }
    }
    
    public class Main {
        static double withdraw(double balance, double amount) {
            if (amount > balance) {
                throw new InsufficientFundsException("cannot withdraw " + amount + " from " + balance);
            }
            return balance - amount;
        }
    
        public static void main(String[] args) {
            for (double amount : new double[] {200, 800}) {
                try {
                    System.out.println("New balance: " + withdraw(500, amount));
                } catch (InsufficientFundsException e) {
                    System.out.println("Error: " + e.getMessage());
                }
            }
        }
    }
    Output
    New balance: 300.0
    Error: cannot withdraw 800.0 from 500.0
  3. 3.Write and read a file

    Advanced

    Write the lines Asha 92, Ravi 85 and Meera 78 to scores.txt with Files.write, read them back with Files.readAllLines, and print the top scorer and the average.

    Show hint

    Split each line on a space and parse the second part.

    Show solution
    Java
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.util.List;
    
    public class Main {
        public static void main(String[] args) throws IOException {
            Path file = Path.of("scores.txt");
            Files.write(file, List.of("Asha 92", "Ravi 85", "Meera 78"));
    
            String best = "";
            int bestScore = -1;
            int total = 0;
            List<String> lines = Files.readAllLines(file);
            for (String line : lines) {
                String[] parts = line.split(" ");
                int score = Integer.parseInt(parts[1]);
                total += score;
                if (score > bestScore) {
                    bestScore = score;
                    best = parts[0];
                }
            }
            System.out.println(best + " " + (double) total / lines.size());
        }
    }
    Output
    Asha 85.0
  4. 4.A generic method

    Advanced

    Write static <T extends Comparable<T>> T largest(List<T> items) and use it with a list of integers and a list of strings.

    Show hint

    The bound lets you call compareTo on items of type T.

    Show solution
    Java
    import java.util.List;
    
    public class Main {
        static <T extends Comparable<T>> T largest(List<T> items) {
            T best = items.get(0);
            for (T item : items) {
                if (item.compareTo(best) > 0) best = item;
            }
            return best;
        }
    
        public static void main(String[] args) {
            System.out.println(largest(List.of(3, 9, 4)));
            System.out.println(largest(List.of("pear", "apple", "plum")));
        }
    }
    Output
    9
    plum
  5. 5.Pass behaviour with lambdas

    Advanced

    Write static List<Integer> filter(List<Integer> items, Predicate<Integer> test), and use it to keep numbers above 10 and even numbers from List.of(5, 12, 7, 20, 3, 15, 8).

    Show hint

    Call test.test(item) for each element.

    Show solution
    Java
    import java.util.ArrayList;
    import java.util.List;
    import java.util.function.Predicate;
    
    public class Main {
        static List<Integer> filter(List<Integer> items, Predicate<Integer> test) {
            List<Integer> result = new ArrayList<>();
            for (int item : items) {
                if (test.test(item)) result.add(item);
            }
            return result;
        }
    
        public static void main(String[] args) {
            List<Integer> nums = List.of(5, 12, 7, 20, 3, 15, 8);
            System.out.println(filter(nums, n -> n > 10));
            System.out.println(filter(nums, n -> n % 2 == 0));
        }
    }
    Output
    [12, 20, 15]
    [12, 20, 8]
  6. 6.A report with streams

    Advanced

    Given sales records Sale(region, amount): North 1200, South 800, North 450, East 990, South 300, use streams to print the total per region (sorted), the overall total, and the regions with a total above 1000.

    Show hint

    Collectors.groupingBy(Sale::region, TreeMap::new, Collectors.summingInt(Sale::amount)).

    Show solution
    Java
    import java.util.List;
    import java.util.Map;
    import java.util.TreeMap;
    import java.util.stream.Collectors;
    
    record Sale(String region, int amount) {}
    
    public class Main {
        public static void main(String[] args) {
            List<Sale> sales = List.of(new Sale("North", 1200), new Sale("South", 800),
                    new Sale("North", 450), new Sale("East", 990), new Sale("South", 300));
    
            Map<String, Integer> totals = sales.stream()
                    .collect(Collectors.groupingBy(Sale::region, TreeMap::new,
                            Collectors.summingInt(Sale::amount)));
            System.out.println(totals);
    
            System.out.println(sales.stream().mapToInt(Sale::amount).sum());
    
            List<String> big = totals.entrySet().stream()
                    .filter(e -> e.getValue() > 1000)
                    .map(Map.Entry::getKey)
                    .toList();
            System.out.println(big);
        }
    }
    Output
    {East=990, North=1650, South=1100}
    3740
    [North, South]
  7. 7.Return an Optional

    Advanced

    Write static Optional<Integer> findAge(Map<String, Integer> ages, String name). Print Asha's age with ifPresent, and John's age with orElse(-1).

    Show hint

    Optional.ofNullable(ages.get(name)) turns a possibly null value into an Optional.

    Show solution
    Java
    import java.util.Map;
    import java.util.Optional;
    
    public class Main {
        static Optional<Integer> findAge(Map<String, Integer> ages, String name) {
            return Optional.ofNullable(ages.get(name));
        }
    
        public static void main(String[] args) {
            Map<String, Integer> ages = Map.of("Asha", 21, "Ravi", 25);
            findAge(ages, "Asha").ifPresent(age -> System.out.println("Asha is " + age));
            System.out.println(findAge(ages, "John").orElse(-1));
        }
    }
    Output
    Asha is 21
    -1
  8. 8.Split work across threads

    Advanced

    Using an ExecutorService with 4 threads, sum the numbers 1 to 1,000,000 as 4 separate tasks (each a quarter of the range) and print the total.

    Show hint

    Submit Callable<Long> tasks with lambdas, then add up each Future's get().

    Show solution
    Java
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    public class Main {
        static long sumRange(long from, long to) {
            long sum = 0;
            for (long i = from; i <= to; i++) sum += i;
            return sum;
        }
    
        public static void main(String[] args) throws Exception {
            try (ExecutorService pool = Executors.newFixedThreadPool(4)) {
                List<Future<Long>> parts = new ArrayList<>();
                for (int p = 0; p < 4; p++) {
                    long from = p * 250_000L + 1;
                    long to = (p + 1) * 250_000L;
                    parts.add(pool.submit(() -> sumRange(from, to)));
                }
                long total = 0;
                for (Future<Long> f : parts) total += f.get();
                System.out.println(total);
            }
        }
    }
    Output
    500000500000

    Each task sums its own range and returns its own result, so no shared variable or lock is needed. The answer matches the formula n(n+1)/2 for n = 1,000,000.