0% found this document useful (0 votes)
12 views12 pages

Extras in java

Uploaded by

mnoxyz9876
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views12 pages

Extras in java

Uploaded by

mnoxyz9876
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

ArrayList in Java:

Java ArrayList is a part of the Java collections framework and it is a class of java.util package. It
provides us with dynamic arrays in Java. Though, it may be slower than standard arrays but can be helpful
in programs where lots of manipulation in the array is needed. This class is found in java.util package. The
main advantage of ArrayList in Java is, that if we declare an array then we need to mention the size, but in
ArrayList, it is not needed to mention the size of ArrayList. If you want to mention the size then you can do
it.

Important Features of ArrayList in Java:


• ArrayList inherits AbstractList class and implements the List interface.
• ArrayList is initialized by size. However, the size is increased automatically if the collection grows
or shrinks if the objects are removed from the collection.
• Java ArrayList allows us to randomly access the list.
• ArrayList cannot be used for primitive types, like int, char, etc. We need a wrapper class for such
cases.
• ArrayList in Java can be seen as a vector in C++.
• ArrayList is not Synchronized. Its equivalent synchronized class in Java is Vector.

Let’s understand the Java ArrayList in depth. Look at the below image:

In the above illustration, AbstractList, CopyOnWriteArrayList, and AbstractSequentialList are the classes
that implement the list interface. A separate functionality is implemented in each of the mentioned
classes. They are:

AbstractList: This class is used to implement an unmodifiable list, for which one needs to only extend this
AbstractList Class and implement only the get() and the size() methods.

CopyOnWriteArrayList: This class implements the list interface. It is an enhanced version of ArrayList in
which all the modifications(add, set, remove, etc.) are implemented by making a fresh copy of the list.
AbstractSequentialList: This class implements the Collection interface and the AbstractCollection class.
This class is used to implement an unmodifiable list, for which one needs to only extend this AbstractList
Class and implement only the get() and the size() methods.

Constructors in ArrayList in Java:


In order to Create an ArrayList, we need to create an object of the ArrayList class. The ArrayList
class consists of various constructors which allow the possible creation of the array list. The following are
the constructors available in this class:

1. ArrayList(): This constructor is used to build an empty array list. If we wish to create an empty ArrayList
with the name arr, then, it can be created as:

ArrayList arr = new ArrayList();

2. ArrayList(Collection c): This constructor is used to build an array list initialized with the elements from
the collection c. Suppose, we wish to create an ArrayList arr which contains the elements present in the
collection c, then, it can be created as:

ArrayList arr = new ArrayList(c);

3. ArrayList(int capacity): This constructor is used to build an array list with the initial capacity being
specified. Suppose we wish to create an ArrayList with the initial size being N, then, it can be created as:

ArrayList arr = new ArrayList(N);

Java ArrayList Methods:


Method Description
add(int index, Object This method is used to insert a specific element at a specific position
element) index in a list.
add(Object o) This method is used to append a specific element to the end of a list.
addAll(Collection C) This method is used to append all the elements from a specific
collection to the end of the mentioned list, in such an order that the
values are returned by the specified collection’s iterator.
addAll(int index, Collection C) Used to insert all of the elements starting at the specified position
from a specific collection into the mentioned list.
clear() This method is used to remove all the elements from any list.
clone() This method is used to return a shallow copy of an ArrayList in Java.
contains? (Object o) Returns true if this list contains the specified element.
ensureCapacity?(int Increases the capacity of this ArrayList instance, if necessary, to
minCapacity) ensure that it can hold at least the number of elements specified by
the minimum capacity argument.
forEach?(Consumer<? super Performs the given action for each element of the Iterable until all
E> action) elements have been processed or the action throws an exception.
get?(int index) Returns the element at the specified position in this list.
indexOf(Object O) The index the first occurrence of a specific element is either returned
or -1 in case the element is not in the list.
isEmpty?() Returns true if this list contains no elements.
lastIndexOf(Object O) The index of the last occurrence of a specific element is either
returned or -1 in case the element is not in the list.
listIterator?() Returns a list iterator over the elements in this list (in proper
sequence).
listIterator?(int index) Returns a list iterator over the elements in this list (in proper
sequence), starting at the specified position in the list.
remove?(int index) Removes the element at the specified position in this list.
Removes the first occurrence of the specified element from this list, if it is
remove? (Object o)
present.
Removes from this list all of its elements that are contained in the specified
removeAll?(Collection c)
collection.
removeIf?(Predicate filter) Removes all of the elements of this collection that satisfy the given redicate.
removeRange?(int fromIndex, Removes from this list all of the elements whose index is between
int toIndex) fromIndex, inclusive, and toIndex, exclusive.
Retains only the elements in this list that are contained in the specified
retainAll?(Collection<?> c)
collection.
Replaces the element at the specified position in this list with the specified
set?(int index, E element)
element.
size?() Returns the number of elements in this list.
spliterator?() Creates a late-binding and fail-fast Spliterator over the elements in this list.
subList?(int fromIndex, int Returns a view of the portion of this list between the specified fromIndex,
toIndex) inclusive, and toIndex, exclusive.
This method is used to return an array containing all of the elements in the
toArray()
list in the correct order.
It is also used to return an array containing all of the elements in this list in
toArray(Object[] O)
the correct order same as the previous method.
This method is used to trim the capacity of the instance of the ArrayList to
trimToSize()
the list’s current size.

Note: You can also create a generic ArrayList:


// Creating generic integer ArrayList

ArrayList<Integer> arrli = new ArrayList<Integer>();

Some Key Points of ArrayList in Java:


• ArrayList is Underlined data Structure Resizable Array or Growable Array.
• ArrayList Duplicates Are Allowed.
• Insertion Order is Preserved.
• Heterogeneous objects are allowed.
• Null insertion is possible.

Complexity of Java ArrayList:


Operation Time Complexity Space Complexity
Inserting Element in ArrayList O(1) O(N)
Removing Element from ArrayList O(N) O(1)
Traversing Elements in ArrayList O(N) O(N)

ArrayList in Java is a class in the Java Collections framework that implements the List interface.
Here are the advantages and disadvantages of using ArrayList in Java.

Advantages of Java ArrayList:


• Dynamic size: ArrayList can dynamically grow and shrink in size, making it easy to add or remove
elements as needed.
• Easy to use: ArrayList is simple to use, making it a popular choice for many Java developers.
• Fast access: ArrayList provides fast access to elements, as it is implemented as an array under
the hood.
• Ordered collection: ArrayList preserves the order of elements, allowing you to access elements
in the order they were added.
• Supports null values: ArrayList can store null values, making it useful in cases where the absence
of a value needs to be represented.

Disadvantages of Java ArrayList:


• Slower than arrays: ArrayList is slower than arrays for certain operations, such as inserting
elements in the middle of the list.
• Increased memory usage: ArrayList requires more memory than arrays, as it needs to maintain
its dynamic size and handle resizing.
• Not thread-safe: ArrayList is not thread-safe, meaning that multiple threads may access and
modify the list concurrently, leading to potential race conditions and data corruption.
• Performance degradation: ArrayList’s performance may degrade as the number of elements in
the list increases, especially for operations such as searching for elements or inserting elements
in the middle of the list.

Conclusion:
• ArrayList is the part of Collections framework. It inherits the AbstractList class and implements
the List interface.
• ArrayList is the implementation of a dynamic array.
• ArrayList can be initialized used using different constructor types like without parameters,
passing collection as a parameter, and passing integer as a parameter.
• Operations can be performed in ArrayList as follows Adding, removing, iterating, and sorting.

* Bytecode in Java:
Bytecode in Java is a highly optimized set of instructions for the Java Virtual Machine (JVM) that
reads and interprets to run the java program. A bytecode is a binary program code that can only run on
JVM. In other words, it is a machine language (code) for JVM in the form of .class file, but it is not
machine specific because it is not a native code. In simple words, it is not machine language (machine
instructions) for any specific hardware processor. Byte code acts as an intermediate language that is
platform (machine) independent. It is generated by Java interpreter that can be directly run by a real
machine.

* Characteristics of Java Bytecode:

Java bytecode has two most important characteristics that are as follows:
1.Byte code is independent of processor, i.e., Java program can be executed on any
processor architecture.
2.It does not depend on operating systems such as Windows, Linux, and Mac OS.

* How does Bytecode work in Java?


=> When we write a java program, the source code (in the form of .java file) is compiled by
Java compiler and converted into byte code in the form of a .class file. This compiled byte code is
platform-independent code that can be run on any different computer machine on which JVM
interpreter is installed. In simple words, write once, compile and run anywhere (WOCRA). These
bytecodes are not machine instructions. Therefore, in the second stage, JVM interpreter takes
the compiled byte code and converts it into machine code that can be directly executed by any
computer system that is running java program source code. Resources required to execute byte
code are made available by the JVM that calls the microprocessor to allocate the required
resources. Thus, we can say that JVM plays an important role in the execution of java program.
Hence, Java is both a compiled and an interpreted language that helps to move java programs
easily from one computer system to another computer system. Any changes and
upgrades of operating systems, processors, and system resources do not affect the java program.
This is the reason why Java has become one of the most popular programming languages in the
world that
interconnects different kinds of systems worldwide on the internet.

* Advantages of Java Bytecode:


Java Bytecode has mainly two advantages that are as follows:
1. Byte code makes the java program portable across the different hardware (processors) and
operating
system platforms. The only requirement is that Java Virtual Machine must be installed on
them.
2. The second advantage is that it increases security of code because of control of JVM over the
execution of byte code file.

* Difference between Bytecode vs Machine code:


The main difference between the byte code and machine code is that byte code can be
run only on JVM whereas machine code is a set of instructions in machine language that can be
directly run by the CPU.

* Difference between .java and .class:

Java source code file (with a .java extension) are compiled into bytecode (with a .class
extension), which is then interpreted and executed by a Java processor called JVM.

Key points:
1. A bytecode in Java is a set of byte-long instructions that Java compiler produces and Java
interpreter
(JVM) executes.
2. When Java compiler compiles .java file, it generates a series of bytecode (machine
independent code) and stores them in a .class file.
3. JVM then interprets and executes the byte code stored in the .class file and converts them
into machine code.
4. The byte code remains the same on different platforms such as Windows, Linux, and Mac OS.

* Editions of Java Platforms:


The Java platform comes in three editions based upon device type. They are as follows:

1. Java SE (Standard Edition): This edition is used to develop client-side applications. It is used
to
develop applications for desktop, communication, and user interface.

2. Java EE (Enterprise Edition): This edition is used to develop server-side applications such as
Java
servlets, JavaServer Pages (JSP), and JavaServer Faces (JSF). In other words, it is used to
develop
web-based, messaging, distributed, and enterprise applications.

3. Java ME (Micro Edition): This edition is used to develop applications for mobile devices,
such as cell
phones. It is also used to develop Personnel Digital Assistants, Setup Box, and printers
applications.

* What is Bytecode Verifier?


=> The bytecode verifier verifies that byte codes are valid or not without breaching any of Java’s
security rules.
It gives special attention to checking the type of all the variables and expressions in the code.
Bytecode
verifier ensures that there is no unauthorized access to memory. Once the code is successfully
verified,
it is transferred to Java Virtual Machine (JVM) for interpretation.

* What is .jar file:


JAR files in Java-> A JAR (Java Archive) is a package file format typically used to aggregate many
Java class files and associated metadata and resources (text, images, etc.) into one file to
distribute application software or libraries on the Java platform. In simple words, a JAR file is a
file that contains a compressed version of .class files, audio files, image files, or directories. We
can imagine a .jar file as a zipped file(.zip) that is created by using WinZip software. Even, WinZip
software can be used to extract the contents of a .jar, so you can use them for tasks such as
lossless data compression, archiving, decompression, and archive unpacking.

* Why java is platform independent:


In the case of Java, it is the magic of Bytecode that makes it platform-independent.
Platform-independent means the Java code that has been compiled generates compiled code or
the byte code, and this byte code can run on all of the operating systems provided they have
JVM installed in it.
- Step-by-Step Execution of Java Program->
* Whenever a program is written in JAVA, the javac compiles it.
* The result of the JAVA compiler is the .class file or the bytecode and not the machine’s
native code
(unlike the C compiler).
* The bytecode generated is a non-executable code and needs an interpreter to execute on a
machine. This interpreter is the JVM and thus the Bytecode is executed by the JVM.
* And finally, the program runs to give the desired output.

* what we deliver to client upon developing a code:


The one can develop an application based on JAVA, consisting of all required JAVA
classes (.java files). Which will be then converted to the .class files making it accessible to all
other OS System. After that we convert or combine all this .class files to a single .jar file making it
simpler to use by the client. So, after developing a JAVA based application we deliver .jar file to
our customer.

* Why not to deliver source code: https://devops.com/handing-your-softwares-source-code-to-


someone-else-when-why-and-how/

* The JVM Architecture:


Every Java developer knows that bytecode will be executed by the JRE (Java Runtime
Environment). But many don't know the fact that JRE is the implementation of Java Virtual Machine
(JVM), which analyzes the bytecode, interprets the code, and executes it. It is very important, as a
developer, that we know the architecture of the JVM, as it enables us to write code more efficiently.

* How Does the JVM Work?


=> The JVM is divided into three main subsystems:
1. ClassLoader Subsystem
2. Runtime Data Area
3. Execution Engine

1. ClassLoader Subsystem:

Java's dynamic class loading functionality is handled by the ClassLoader subsystem. It loads,
links. and
initializes the class file when it refers to a class for the first time at runtime, not compile time.
1.1 Loading -> Classes will be loaded by this component. BootStrap ClassLoader, Extension
ClassLoader, and
Application ClassLoader are the three ClassLoaders that will help in achieving it.
1.2 Linking -> Verify – Bytecode verifier will verify whether the generated bytecode is proper or not if
verification fails we will get the verification error.
Prepare – For all static variables memory will be allocated and assigned with default values.
Resolve – All symbolic memory references are replaced with the original references from Method
Area.
1.3 Initialization -> This is the final phase of ClassLoading; here, all static variables will be assigned
with the original values, and the static block will be executed.

2. Runtime Data Area:


The Runtime Data Area is divided into five major components:
1. Method Area – All the class-level data will be stored here, including static variables. There is only
one
method area per JVM, and it is a shared resource.
2. Heap Area – All the Objects and their corresponding instance variables and arrays will be stored
here.
There is also one Heap Area per JVM. Since the Method and Heap areas share memory for multiple
threads,
the data stored is not thread-safe.
3. Stack Area – For every thread, a separate runtime stack will be created. For every method call, one
entry
will be made in the stack memory which is called Stack Frame. All local variables will be created in
the
stack memory. The stack area is thread-safe since it is not a shared resource. The Stack Frame is
divided
into three subentities:
3.1 Local Variable Array – Related to the method how many local variables are involved and the
corresponding values will be stored here.
3.2 Operand stack – If any intermediate operation is required to perform, operand stack acts as
runtime
workspace to perform the operation.
3.3 Frame data – All symbols corresponding to the method is stored here. In the case of any
exception, the
catch block information will be maintained in the frame data.
4. PC Registers – Each thread will have separate PC Registers, to hold the address of current executing
instruction once the instruction is executed the PC register will be updated with the next instruction.
5. Native Method stacks – Native Method Stack holds native method information. For every thread, a
separate
native method stack will be created.
3. Execution Engine:
The bytecode, which is assigned to the Runtime Data Area, will be executed by the Execution Engine.
The
Execution Engine reads the bytecode and executes it piece by piece.
*Interpreter – The interpreter interprets the bytecode faster but executes slowly. The disadvantage of
the
interpreter is that when one method is called multiple times, every time a new interpretation is
required.
*JIT Compiler – The JIT Compiler neutralizes the disadvantage of the interpreter. The Execution Engine
will be
using the help of the interpreter in converting byte code, but when it finds repeated code it uses the
JIT
compiler, which compiles the entire bytecode and changes it to native code. This native code will be
used
directly for repeated method calls, which improve the performance of the system.
**Intermediate Code Generator – Produces intermediate code
**Code Optimizer – Responsible for optimizing the intermediate code generated above
**Target Code Generator – Responsible for Generating Machine Code or Native Code
**Profiler – A special component, responsible for finding hotspots, i.e. whether the method is called
multiple times or not.
*Garbage Collector: Collects and removes unreferenced objects. Garbage Collection can be triggered
by calling
System.gc(), but the execution is not guaranteed. Garbage collection of the JVM collects the objects
that
are created.

* Java Native Interface (JNI):


JNI will be interacting with the Native Method Libraries and provides the Native Libraries
required for the Execution Engine. Native Method Libraries: This is a collection of the Native Libraries,
which is required for the Execution Engine.
Anonymous Inner Class in Java:
Nested Classes in Java is prerequisite required before adhering forward to grasp about anonymous
Inner class. It is an inner class without a name and for which only a single object is created. An anonymous
inner class can be useful when making an instance of an object with certain “extras” such as overriding
methods of a class or interface, without having to actually subclass a class.

Tip: Anonymous inner classes are useful in writing implementation classes for listener interfaces in
graphics programming.

The syntax of an anonymous class expression is like the invocation of a constructor, except that
there is a class definition contained in a block of code.

Syntax:

// Test can be interface,abstract/concrete class


Test t = new Test()
{
// data members and methods
public void test_method()
{
........
........
}
};

Now let us do discuss the difference between regular class(normal classes) and Anonymous Inner class

• A normal class can implement any number of interfaces but the anonymous inner class can
implement only one interface at a time.
• A regular class can extend a class and implement any number of interfaces simultaneously. But
anonymous Inner class can extend a class or can implement an interface but not both at a time.
• For regular/normal class, we can write any number of constructors but we can’t write any
constructor for anonymous Inner class because the anonymous class does not have any name
and while defining constructor class name and constructor name must be same.

Accessing Local Variables of the Enclosing Scope, and Declaring and Accessing Members of the
Anonymous Class

Like local classes, anonymous classes can capture variables; they have the same access to local variables
of the enclosing scope:

• An anonymous class has access to the members of its enclosing class.


• An anonymous class cannot access local variables in its enclosing scope that are not declared as
final or effectively final.
• Like a nested class, a declaration of a type (such as a variable) in anonymous class shadows any
other declarations in the enclosing scope that have the same name.
Anonymous classes also have the same restrictions as local classes with respect to their members:

• We cannot declare static initializers or member interfaces in an anonymous class.


• An anonymous class can have static members provided that they are constant variables.

Note: We can declare the following in anonymous classes as follows:

• Fields
• Extra methods (even if they do not implement any methods of the supertype)
• Instance initializers
• Local classes

Ways:

Anonymous inner classes are generic created via below listed two ways as follows:

• Class (may be abstract or concrete)


• Interface

Types of Anonymous Inner Class

Based on declaration and behavior, there are 3 types of anonymous Inner classes:

• Anonymous Inner class that extends a class


• Anonymous Inner class that implements an interface
• Anonymous Inner class that defines inside method/constructor argument

Type 1: Anonymous Inner class that extends a class

We can have an anonymous inner class that extends a class. For example, we know that we can
create a thread by extending a Thread class. Suppose we need an immediate thread but we don’t want
to create a class that extends Thread class all the time. With the help of this type of Anonymous Inner
class, we can define a ready thread.

Type 2: Anonymous Inner class that implements an interface

We can also have an anonymous inner class that implements an interface. For example, we also
know that by implementing Runnable interface we can create a Thread. Here we use an anonymous
Inner class that implements an interface.

Type 3: Anonymous Inner class that defines inside method/constructor argument

Anonymous inner classes in method/constructor arguments are often used in graphical user
interface (GUI) applications. To get you familiar with syntax lets have a look at the following program
that creates a thread using this type of Anonymous Inner class

Red-Black Tree:
A Red-Black Tree is a self-balancing binary search tree that maintains a balance between the
heights of its left and right subtrees. This ensures that search, insertion, and deletion operations take O(log
n) time in the worst case. Red-Black Trees are widely used in various applications where efficient data
structures are required.

- How does a Red-Black Tree maintain its balance?

Red-Black Trees maintain their balance by enforcing specific rules on the colors of nodes (RED or
BLACK) and the relationships between them. These rules ensure that the tree remains balanced and that
the height difference between the left and right subtrees is at most 1.

- What are the advantages of using a Red-Black Tree?

• Balanced: Red-Black Trees are self-balancing, ensuring efficient search, insertion, and deletion
operations.
• Efficient: They offer O(log n) time complexity for most operations.
• Simple to implement: The rules for maintaining Red-Black Tree properties are relatively
straightforward.
• Widely used: They are a popular choice for implementing various data structures and algorithms.

- What are the disadvantages of using a Red-Black Tree?

• Compared to simpler balanced trees like AVL trees, Red-Black Trees have more complex insertion
and deletion rules.
• Maintaining the Red-Black Tree properties adds a small overhead to every insertion and deletion
operation.
• For applications with frequent insertions and deletions, other balanced tree structures might be
more suitable.
- What are some common applications of Red-Black Trees?

• Implementing maps and sets


• Priority queues
• File systems
• In-memory databases
• Graphics and game development (collision detection, pathfinding)

You might also like