Beginner Java Study Guide: From Basics to Problem-Solving

1. Data Types

Fundamental Data Types

Java distinguishes between primitive types and reference types. The eight primitive types are: byte, short, int, long, float, double, boolean, and char.

1// Java primitives
2int age = 25;
3double salary = 50000.50;
4boolean isActive = true;
5char grade = 'A';
6long largeNumber = 1000000000L;

Type Conversion

Java requires explicit casting for narrowing conversions and automatic promotion for widening conversions.

1// Java type conversion
2double d = 10.5;
3int i = (int) d;  // explicit cast, result is 10
4int x = 5;
5double y = x;     // automatic promotion

2. Control Structures

Conditional Statements

Java uses if, else if, else, and the ternary operator ? :.

 1// Java conditionals
 2int score = 85;
 3if (score >= 90) {
 4    System.out.println("A");
 5} else if (score >= 80) {
 6    System.out.println("B");
 7} else {
 8    System.out.println("C");
 9}
10
11// Ternary operator
12String grade = (score >= 90) ? "A" : "B";

Loops

Java supports for, while, do-while, and enhanced for loops.

 1// Java loops
 2for (int i = 0; i < 5; i++) {
 3    System.out.println(i);
 4}
 5
 6// Enhanced for loop (for-each)
 7int[] numbers = {1, 2, 3, 4, 5};
 8for (int num : numbers) {
 9    System.out.println(num);
10}
11
12int j = 0;
13while (j < 5) {
14    System.out.println(j);
15    j++;
16}

3. Arrays and Lists

Declaration and Initialization

Java arrays are fixed-size and strongly typed.

 1// Java arrays
 2int[] numbers = new int[5];              // creates array of size 5, initialized to 0
 3int[] numbers2 = {1, 2, 3, 4, 5};       // array literal
 4String[] names = new String[3];         // initialized to null
 5names[0] = "Alice";
 6
 7// ArrayList for dynamic sizing
 8ArrayList<Integer> dynamicList = new ArrayList<>();
 9dynamicList.add(10);
10dynamicList.add(20);
11int value = dynamicList.get(0);         // 10
12dynamicList.remove(0);

Accessing Elements

Java uses index notation and methods for ArrayList.

1int[] arr = {10, 20, 30};
2int first = arr[0];      // 10
3arr[1] = 25;             // modify element
4
5ArrayList<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
6String second = list.get(1);  // "b"
7list.set(1, "x");             // modify element

4. String Manipulation

String Creation and Basics

Java strings are immutable and part of the String class. Use StringBuilder for multiple concatenations.

 1// Java strings
 2String s1 = "Hello";
 3String s2 = "World";
 4String combined = s1 + " " + s2;        // "Hello World"
 5
 6// Using StringBuilder for efficiency
 7StringBuilder sb = new StringBuilder();
 8sb.append("Hello");
 9sb.append(" ");
10sb.append("World");
11String result = sb.toString();          // "Hello World"

Common String Methods

 1String text = "Hello World";
 2int length = text.length();             // 11
 3char c = text.charAt(0);                // 'H'
 4String upper = text.toUpperCase();      // "HELLO WORLD"
 5String lower = text.toLowerCase();      // "hello world"
 6boolean contains = text.contains("World");  // true
 7int index = text.indexOf("World");      // 6
 8String substring = text.substring(0, 5); // "Hello"
 9String[] parts = text.split(" ");       // ["Hello", "World"]
10String trimmed = text.trim();           // remove leading/trailing whitespace
11boolean equals = text.equals("Hello World");  // true
12boolean equalsIgnoreCase = text.equalsIgnoreCase("hello world");  // true

Useful Techniques

Character checking and conversion:

1// Java
2char c = 'a';
3boolean isLetter = Character.isLetter(c);      // true
4boolean isDigit = Character.isDigit(c);        // false
5boolean isUpperCase = Character.isUpperCase(c); // false
6char upper = Character.toUpperCase(c);         // 'A'

5. Integer Arrays and Utilities

Array Operations

Java provides utility methods through the Arrays class.

 1import java.util.Arrays;
 2
 3int[] numbers = {5, 2, 8, 1, 9};
 4
 5// Sorting
 6Arrays.sort(numbers);                   // [1, 2, 5, 8, 9]
 7
 8// Searching (requires sorted array)
 9int index = Arrays.binarySearch(numbers, 5);  // returns index
10
11// Creating and copying
12int[] copy = Arrays.copyOf(numbers, numbers.length);
13int[] subarray = Arrays.copyOfRange(numbers, 1, 3);  // indices 1-2
14
15// Checking equality
16int[] arr1 = {1, 2, 3};
17int[] arr2 = {1, 2, 3};
18boolean equal = Arrays.equals(arr1, arr2);    // true
19
20// Converting to string
21String str = Arrays.toString(numbers);       // "[1, 2, 5, 8, 9]"
22
23// Filling array
24Arrays.fill(numbers, 0);                // all elements set to 0

6. Working with Arrays of Objects, Counting Occurrences and Commonalities

Counting Occurrences

 1// Counting occurrences in array
 2int[] numbers = {1, 2, 2, 3, 2, 4, 1};
 3int count = 0;
 4int target = 2;
 5for (int num : numbers) {
 6    if (num == target) count++;
 7}
 8System.out.println(count);              // 3
 9
10// Using HashMap for frequency count
11import java.util.HashMap;
12HashMap<Integer, Integer> frequency = new HashMap<>();
13for (int num : numbers) {
14    frequency.put(num, frequency.getOrDefault(num, 0) + 1);
15}
16// frequency: {1=2, 2=3, 3=1, 4=1}
17
18// Using Apache Commons or streams (more advanced)
19long count2 = Arrays.stream(numbers).filter(n -> n == 2).count();

Finding Common Elements

 1// Finding common elements between two arrays
 2int[] arr1 = {1, 2, 3, 4, 5};
 3int[] arr2 = {3, 4, 5, 6, 7};
 4
 5HashSet<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
 6ArrayList<Integer> common = new ArrayList<>();
 7for (int num : arr2) {
 8    if (set1.contains(num)) {
 9        common.add(num);
10    }
11}
12// common: [3, 4, 5]
13
14// Using streams (Java 8+)
15Set<Integer> intersection = Arrays.stream(arr1)
16    .filter(x -> Arrays.stream(arr2).anyMatch(y -> y == x))
17    .collect(Collectors.toSet());

Working with Arrays of Objects

 1// Define a simple class
 2class Student {
 3    String name;
 4    int score;
 5    
 6    public Student(String name, int score) {
 7        this.name = name;
 8        this.score = score;
 9    }
10}
11
12// Array of objects
13Student[] students = new Student[3];
14students[0] = new Student("Alice", 95);
15students[1] = new Student("Bob", 87);
16students[2] = new Student("Charlie", 92);
17
18// Accessing object properties
19String firstName = students[0].name;
20int firstScore = students[0].score;
21
22// Filtering and processing
23ArrayList<Student> highScores = new ArrayList<>();
24for (Student student : students) {
25    if (student.score >= 90) {
26        highScores.add(student);
27    }
28}
29
30// Using streams (Java 8+)
31List<Student> filtered = Arrays.stream(students)
32    .filter(s -> s.score >= 90)
33    .collect(Collectors.toList());

7. Tips for Solving HackerRank Coding Questions

Read the Problem Carefully

Before writing any code, spend time understanding what the problem is asking. Pay attention to constraints, input formats, and expected output. Reread the problem statement if you’re unsure about edge cases.

Start with a Clear Plan

Outline your approach in pseudocode or comments before implementing. Ask yourself: What data structures do I need? What’s the algorithm? Are there any edge cases?

1// Pseudocode example
2// Read array size
3// Read array elements
4// Find max element
5// Print max element

Handle Edge Cases

Consider boundary conditions: empty arrays, single elements, all identical elements, negative numbers, zeros, and maximum constraints.

1// Bad: doesn't handle empty array
2int max = arr[0];
3for (int i = 1; i < arr.length; i++) {
4    if (arr[i] > max) max = arr[i];
5}
6
7// Better: document the assumption
8// Assumes arr is not empty
9int max = arr[0];

Test with Sample Input/Output

After writing code, trace through the given examples manually to ensure correctness before submitting.

1// If example shows input "1 2 3" should output "6"
2// Test your code step by step with this input

Use Appropriate Data Structures

Different problems benefit from different data structures. Choose wisely to avoid unnecessary complexity.

  • Lists/Arrays: Sequential data, indexed access needed
  • HashMap/Dictionary: Frequency counting, lookups, grouping by key
  • Set: Checking membership, finding unique elements
  • Stack: LIFO problems, nested structures
  • Queue: FIFO problems, level-by-level processing
  • PriorityQueue: K-largest/smallest, sorting requirements
1// Choosing HashMap for character frequency
2String text = "hello";
3HashMap<Character, Integer> freq = new HashMap<>();
4for (char c : text.toCharArray()) {
5    freq.put(c, freq.getOrDefault(c, 0) + 1);
6}

Optimize Time Complexity

Start with a working solution, then optimize if needed. Be aware of nested loops and unnecessary operations.

 1// O(n²) solution - works but slow for large arrays
 2for (int i = 0; i < arr.length; i++) {
 3    for (int j = i + 1; j < arr.length; j++) {
 4        if (arr[i] + arr[j] == target) {
 5            // found pair
 6        }
 7    }
 8}
 9
10// O(n) solution - better
11HashSet<Integer> seen = new HashSet<>();
12for (int num : arr) {
13    if (seen.contains(target - num)) {
14        // found pair
15    }
16    seen.add(num);
17}

Common Patterns and Techniques

Pattern 1: Two-pointer technique - useful for sorted arrays or string manipulation.

 1// Finding pair with given sum in sorted array
 2public static boolean findPair(int[] arr, int target) {
 3    int left = 0, right = arr.length - 1;
 4    while (left < right) {
 5        int sum = arr[left] + arr[right];
 6        if (sum == target) return true;
 7        else if (sum < target) left++;
 8        else right--;
 9    }
10    return false;
11}

Pattern 2: Sliding window - for contiguous subarray problems.

 1// Maximum sum of subarray of size k
 2public static int maxSum(int[] arr, int k) {
 3    int currentSum = 0;
 4    for (int i = 0; i < k; i++) {
 5        currentSum += arr[i];
 6    }
 7    int maxSum = currentSum;
 8
 9    for (int i = k; i < arr.length; i++) {
10        currentSum = currentSum - arr[i - k] + arr[i];
11        maxSum = Math.max(maxSum, currentSum);
12    }
13    return maxSum;
14}

Pattern 3: Prefix sum - for range queries.

 1// Calculate prefix sums
 2int[] arr = {1, 2, 3, 4, 5};
 3int[] prefix = new int[arr.length];
 4prefix[0] = arr[0];
 5for (int i = 1; i < arr.length; i++) {
 6    prefix[i] = prefix[i - 1] + arr[i];
 7}
 8// prefix: [1, 3, 6, 10, 15]
 9
10// Query sum from index i to j
11int sum = prefix[j] - (i > 0 ? prefix[i - 1] : 0);

Input/Output Handling

Pay attention to how input is formatted and how output should be presented.

 1import java.util.Scanner;
 2
 3Scanner sc = new Scanner(System.in);
 4int n = sc.nextInt();           // read single integer
 5String line = sc.nextLine();    // read entire line
 6int[] arr = new int[n];
 7for (int i = 0; i < n; i++) {
 8    arr[i] = sc.nextInt();
 9}
10sc.close();

Debugging Tips

Use print statements or a debugger to trace variable values. Check intermediate results, not just the final answer.

1// Add debug output
2System.out.println("DEBUG: arr = " + Arrays.toString(arr));
3System.out.println("DEBUG: result = " + result);

Practice Progressions

Start with Easy problems to master fundamentals, then progress to Medium and Hard. Focus on:

  1. String manipulation: Reverse strings, check palindromes, count characters
  2. Array operations: Sorting, searching, finding max/min, counting occurrences
  3. Frequency problems: Count duplicates, find mode, identify unique elements
  4. Math problems: GCD, prime numbers, number properties
  5. Two-pointer problems: Merge arrays, find pairs, remove duplicates
  6. Dynamic programming: Build understanding gradually with simple problems first

Submit Early and Often

Don’t overthink edge cases before submitting. Get your solution working, submit it, and then optimize if it fails test cases. HackerRank’s feedback can guide you to missing edge cases.

Learn from Solutions

After solving or if stuck, read accepted solutions to see different approaches. Understanding multiple solutions deepens your problem-solving skills and introduces you to new techniques.


Quick Reference: Java vs Python Comparison

TaskJavaPython
PrintSystem.out.println(x);print(x)
Arrayint[] arr = {1,2,3};arr = [1, 2, 3]
ListArrayList<Integer> list = new ArrayList<>();list = []
HashMapHashMap<K,V> map = new HashMap<>();dict = {} or from collections import defaultdict
Loopfor(int i=0; i<n; i++)for i in range(n):
String iteratefor(char c : s.toCharArray())for c in s:
Convert to intInteger.parseInt(s)int(s)
MaxMath.max(a, b)max(a, b)
SortArrays.sort(arr);arr.sort() or sorted(arr)

Final Reminders

Practice consistently. Each problem you solve builds pattern recognition. Focus on understanding the solution, not just getting it right. Pseudocode and comments help clarify your thinking. When stuck, break the problem into smaller pieces. Most importantly, learn from every attempt—both successes and failures improve your problem-solving skills.