1)calculate the average salary of male employees using Java Streams.
Employee is having empName,gender,salary.
Then save employee data into a CSV file in the format John,Male,50000.
We have to create Employee
POJO class.- Then we have use s
tream
withfilter
andmapToDouble
followed byaverage()
.
var
and List.of()
(Java 10+).John,Male,50000
, you can use Files.write
with a simple stream in JavaNotes:
-
filter
: to select only male employees. -
mapToDouble
: to extract salary. -
average()
: returnsOptionalDouble
. -
orElse(0.0)
: handles the case when no male employees are present.
2)Spring Boot REST Controller for full CRUD operations (getAllEmployees
, saveEmployee
, updateEmployee
, deleteEmployee
) using MS SQL Server and Spring Data JPA
Employee.java
– Entity Class
✅ 2. EmployeeRepository.java
✅ 3. EmployeeService.java
✅ 4. EmployeeController.java
3)Spring Boot REST Controller for full CRUD operations (getAllEmployees
, saveEmployee
, updateEmployee
, deleteEmployee
) using Mongo DB
✅ 1. Employee.java
– MongoDB Document
✅ 2. EmployeeRepository.java
3)EmployeeService.java & 4)
EmployeeController.java & 5)EmployeeServiceTest.java same as above-------------------------------------
package collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
class Hashkeyvalue {
// Scenario 1:
public static void main(String[] args) { Map<Integer, String> h = Map.of(10, "swamy", 20, "narayan", 30, "raj"); System.out.println(h); h.forEach((key, value) -> System.out.println(key + "....." + value)); }
// Scenario 2:
public static void main(String[] args) {
Map<Integer, String> h = new HashMap<>();
h.put(10, "swamy");
h.put(20, "narayan");
h.put(30, "raj");
System.out.println(h);
// Scenario 2
Set<Map.Entry<Integer, String>> s = h.entrySet();
Iterator<Map.Entry<Integer, String>> itr = s.iterator();
while (itr.hasNext()) {
Map.Entry<Integer, String> m1 = itr.next();
System.out.println(m1.getKey() + "....." + m1.getValue());
}
// Scenario 3, we concise the code like below
for (Map.Entry<Integer, String> entry : h.entrySet()) {
System.out.println(entry.getKey() + "....." + entry.getValue());
}
}
}
4) What is output? Why? explain correct version
Collectors.toList()
should be used with .collect(...)
, not directly after .skip(...)
..collect(...)
) is called, the stream is consumed and cannot be used again.✅ Explanation:
-
alist.stream()
: A new stream must be created each time because Java streams are single-use. -
.sorted().skip(4)
: Sorts the list and skips the first 4 elements. -
.collect(Collectors.toList())
: Collects the resulting stream into aList
.
5) What is the output for below?
String s1 ="abc";
String s2;//Some api call returning some value
if(s2==s1)
System.out.println("s1 and s2 are true");
s2.equals(s1);
❗ Issues:
-
s2
is declared but never initialized:-
This will result in a compilation error: "variable s2 might not have been initialized."
-
-
Using
==
to compare strings:-
==
compares object references, not actual content. Use.equals()
for content comparison.
-
-
Potential
NullPointerException
:-
If
s2
isnull
, thens2.equals(s1)
will throw a runtime error.
-
✅ Corrected Code:
✅ Safer Practice
๐ Null-safe string comparison:
This avoids NullPointerException
if s2
is null
, since the literal string "abc"
is definitely not null.
๐งช Summary: String Comparison in Java
Expression | What It Does |
---|---|
s1 == s2 | Compares references (same memory address) |
s1.equals(s2) | Compares string contents |
"abc".equals(s2) | Null-safe content comparison |
7)stream()
Internal Mechanism in Java
๐ง What is .stream()
?
stream()
is a default method in the java.util.Collection
interface that allows a collection (like List
, Set
, etc.) to produce a sequential Stream
:
So when you call:
Internally, the above line actually invokes:
๐ Step-by-Step Internal Flow of stream()
✅ Step 1: stream()
in Collection Interface
Defined in java.util.Collection
:
Here:
-
spliterator()
is a method from theIterable
interface. -
false
means we want a sequential stream (not parallel).
✅ Step 2: spliterator()
Method
Every collection provides its own implementation of spliterator()
.
For example:
A Spliterator
is like a modern iterator with additional capabilities:
-
Can split the collection into parts (useful for parallel processing).
-
Supports characteristics like
SIZED
,ORDERED
, etc.
✅ Step 3: StreamSupport.stream(...)
From java.util.stream.StreamSupport
:
๐ธ What is happening here?
-
The
stream()
method constructs a pipeline starting with theHead
stage. -
ReferencePipeline.Head<T>
is the starting point of the stream processing pipeline.
⚙️ ReferencePipeline.Head (Source Stage)
๐ Code Snippet:
It represents:
-
The source of elements (from
Spliterator
). -
The starting node in the stream pipeline.
-
Whether the stream is parallel or not.
๐ What Happens Next?
After .stream()
is called:
-
The stream pipeline is constructed (intermediate operations like
filter
,map
wrap the pipeline). -
But no operation is executed yet!
Only when a terminal operation like .collect()
, .forEach()
, .reduce()
is called does the pipeline trigger execution.
๐ Internal Stream Pipeline Architecture
Visual Representation:
๐งฉ Key Classes in Internals
Class | Description |
---|---|
Collection.stream() | Entry point from collections |
Iterable.spliterator() | Produces a Spliterator |
StreamSupport.stream() | Builds pipeline head |
ReferencePipeline.Head | First stage of the stream |
AbstractPipeline | Base for intermediate/terminal operations |
Spliterator | Source traverser/splitter |
Sink | Accepts and processes elements in pipeline stages |
✅ Summary
Component | Description |
---|---|
.stream() | Default method in Collection , delegates to StreamSupport.stream(...) |
spliterator() | Obtains an efficient traverser/splitter from the collection |
StreamSupport.stream() | Constructs pipeline head (ReferencePipeline.Head ) |
ReferencePipeline | Represents lazy stages of the stream |
Terminal operation | Triggers actual traversal and processing |
๐ง Bonus: Parallel Streams
If you call .parallelStream()
instead of .stream()
:
The true
tells the pipeline to:
-
Enable parallel execution.
-
Use
ForkJoinPool.commonPool()
for multi-threaded processing.
8) How many ways calls garbage collector
๐ 1. Using System.gc()
-
Suggests that the JVM perform garbage collection.
-
It calls
Runtime.getRuntime().gc()
internally. -
Not guaranteed — JVM may ignore it.
๐ 2. Using Runtime.getRuntime().gc()
-
Similar to
System.gc()
, but called explicitly through theRuntime
object. -
Also just a request to the JVM.
๐ 3. Calling System.runFinalization()
-
Suggests that the JVM run finalizers on objects pending finalization.
-
Often used with
System.gc()
.
Example:
⚠️ Deprecated or discouraged in many cases because of unpredictable behavior.
๐ 4. Using finalize()
Method (Deprecated)
-
JVM might call this before reclaiming the object.
-
Deprecated in Java 9+, and removed in Java 18+.
-
Should not be used in new code.
๐ 5. Nullifying References (Encouraging GC)
-
By removing strong references to an object, it becomes eligible for GC.
-
Actual collection depends on JVM.
๐ 6. Using PhantomReference
, SoftReference
, or WeakReference
These are classes in java.lang.ref
package used to:
Reference Type | Behavior |
---|---|
SoftReference | Cleared at low memory |
WeakReference | Cleared at next GC cycle |
PhantomReference | Enqueued after object finalized |
-
Helps track or influence GC for caching and cleanup purposes.
๐ซ What You Cannot Do:
-
You cannot force GC to run at a specific time.
-
You cannot control the exact object removal timing.
-
JVM vendors have different GC implementations and optimizations.
๐ Summary Table
Way | Method | Guaranteed? |
---|---|---|
1 | System.gc() | ❌ No |
2 | Runtime.getRuntime().gc() | ❌ No |
3 | System.runFinalization() | ❌ No |
4 | finalize() | ❌ No (Deprecated) |
5 | Nullifying reference | ❌ No |
6 | Reference types (WeakReference , etc.) | ❌ No |
๐งช Bonus: JVM Options to Control GC Behavior
You can use JVM flags to influence GC algorithms and behavior:
ArrayList
Operations in Java✅ Time Complexity of ArrayList
in Java — Detailed Breakdown
ArrayList
is part of the Java Collections Framework and is backed by a dynamic array. This means it offers fast access but can be slower for some insert/remove operations compared to linked structures.
๐ ArrayList Time Complexity Table
Operation | Time Complexity | Explanation |
---|---|---|
add(E e) (at end) | O(1) (Amortized) |
Fast unless resizing is needed |
add(int index, E element) | O(n) |
Worst-case: shifting elements to the right |
get(int index) | O(1) |
Direct access via index |
set(int index, E element) | O(1) |
Replaces element at index |
remove(int index) | O(n) |
Elements are shifted left |
remove(Object o) | O(n) |
May require scanning and shifting |
contains(Object o) | O(n) |
Linear search |
indexOf(Object o) | O(n) |
Linear search |
clear() | O(n) |
Nulls all elements for GC |
size() | O(1) |
Just returns internal size variable |
iterator() / listIterator() | O(1) |
Lightweight creation |
ensureCapacity(int minCap) | O(n) (copying) |
Resizes internal array |
trimToSize() | O(n) (copying) |
Shrinks internal array |
๐ง Key Notes
✅ Amortized O(1) for add(E e)
-
Internally, if array capacity is full, it resizes (usually by 1.5x).
-
Resize involves copying all elements to a new array → O(n)
-
But since it doesn't happen every time, the average over time is O(1).
๐ remove(int index)
-
Removing shifts elements to the left.
-
Hence, O(n) in the worst case (if removing from beginning).
✅ Best Use Cases for ArrayList
Scenario | Recommended? | Reason |
---|---|---|
Frequent random access | ✅ Yes | Fast get() and set() |
Frequent additions at end | ✅ Yes | Amortized O(1) |
Frequent insertion/removal at middle/start | ❌ No | Costly shifting (O(n) ) |
๐ Internals Recap (How ArrayList Works)
-
Uses a backing array:
Object[] elementData
. -
Tracks current number of elements:
int size
. -
Resizes itself using:
public static void main(String[] args) {
Map<Integer, String> h = Map.of(10, "swamy", 20, "narayan", 15, "raj");
h.values().forEach(System.out::println);
}
//Scenario 2:
Map<Integer, String> h = Map.of(10, "swamy", 20, "narayan", 15, "raj");
h.keySet().forEach(System.out::println);
}
import java.util.TreeSet;
class ReverseAlpha {
Set t = new TreeSet(new MyComparator1());
t.add("chiru");
t.add("venky");
t.add("nagaruna");
t.add("balaiah");
t.add("saikumar");
t.add("suman");
System.out.println(t);
}
}
class MyComparator1 implements Comparator {
public int compare(Object obj1, Object obj2) {
String s1 = (String) obj1;
String s2 = (String) obj2;
return s2.compareTo(s1);
}
}
int i;
HashCodeDemo(int i) {
this.i = i;
}
@Override
return i;
}
@Override
return i + "";
}
public static void main(String arg[]) {
HashCodeDemo h1 = new HashCodeDemo(100);
HashCodeDemo h2 = new HashCodeDemo(110);
System.out.println(h1); // 100
System.out.println(h2); // 110
}
}
import java.util.Collections;
class ArrayListDemo {
public static void main(String[] args) {
List<Integer> a =
new ArrayList<>(List.of(10, 6, 8, 4, 2, 5, 1, 3, 7, 9, 82, 42));
Collections.sort(a);
System.out.println(a);
a.subList(4, 10).forEach(System.out::println);
}
public static void main(String arg[]) {
ArrayList a = new ArrayList();
a.add(10);
a.add(6);
a.add(8);
a.add(4);
a.add(2);
a.add(5);
a.add(1);
a.add(3);
a.add(7);
a.add(9);
a.add(82);
a.add(42);
Collections.sort(a);
System.out.println(a);
for (int i = 4; i <= 9; i++) {
System.out.println(a.get(i));
}
}
}