Java Advanced
Note
The following content is based on Java JDK 8. Changes in higher versions are possible.
Faster Input and Output
Scanner and System.out.print work well initially, but they become inefficient when handling larger inputs. Therefore, we need methods to improve I/O speed.
Using Kattio + StringTokenizer for Input
One of the most common methods is using Kattio.java from Kattis to improve I/O efficiency.1 This method wraps StringTokenizer and PrintWriter in a class for convenience. When solving problems (if allowed by the contest/organizer), this template can be used directly.
Below is the I/O template that should be included in the code. Since the original Kattio from Kattis includes some less commonly used features, the template below has been adjusted (the original Kattio uses the MIT license).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
The code below briefly demonstrates the usage of Kattio:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Using StreamTokenizer for Input
In some cases, using StringTokenizer may cause MLE (Memory Limit Exceeded). In such situations, we need to use StreamTokenizer for input.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Analysis and Comparison Between Kattio + StringTokenizer and StreamTokenizer Methods
StreamTokenizeruses less memory compared toStringTokenizer. When a Java standard solution MLE, you can tryStreamTokenizer. However,StreamTokenizerloses precision and may cause issues when reading certain data.- The source code of
StreamTokenizerhas aTypethat determines the type based on input content. If the input is a string starting with a number, like123oi, it will forcibly treat it as adoubletype. Thus, reading aStringtype as adoublewill throw an exception. StreamTokenizerloses precision when reading numbers larger than1e14.
- The source code of
- When using
PrintWriter, ensure toclose()the output stream at the end of the program or useflush()to clear the buffer when output is needed. Otherwise, content will not be written to the console/file. Kattioinherits from thePrintWriterclass, so its objects have the functionality ofPrintWriter. Therefore, it can directly callPrintWriterfunctions for output, while modifyingStringTokenizeras its member variable. The second method,Main, uses bothStreamTokenizerandPrintWriteras member variables, resulting in slight differences in usage.
In summary, in most cases, StringTokenizer is superior to StreamTokenizer. In extreme MLE situations, you can try StreamTokenizer. However, StreamTokenizer cannot handle data beyond the int range.
BigInteger and Number Theory
BigInteger is a high-precision calculation class provided by Java, which can conveniently solve high-precision problems.
Initialization
Common ways to create BigInteger are as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Basic Operations
In the following, this represents the current BigInteger:
| Function Name | Function |
|---|---|
abs() |
Returns the absolute value of this |
negate() |
Returns the opposite of this |
add(BigInteger val) |
Returns the sum of this and val |
subtract(BigInteger val) |
Returns the difference between this and val |
multiply(BigInteger val) |
Returns the product of this and val |
divide(BigInteger val) |
Returns the quotient of this divided by val |
remainder(BigInteger val) |
Returns the remainder of this divided by val |
mod(BigInteger val) |
Returns the value of this modulo val |
pow(int val) |
Returns this raised to the power of val |
and(BigInteger val) |
Returns the bitwise AND of this and val |
or(BigInteger val) |
Returns the bitwise OR of this and val |
not() |
Returns the bitwise NOT of this |
xor(BigInteger val) |
Returns the bitwise XOR of this and val |
shiftLeft(int n) |
Returns this shifted left by n bits |
shiftRight(int n) |
Returns this shifted right by n bits |
max(BigInteger val) |
Returns the larger of this and val |
min(BigInteger val) |
Returns the smaller of this and val |
bitCount() |
Returns the number of 1s in the binary representation of this, excluding the sign bit |
bitLength() |
Returns the length of the binary representation of this, excluding the sign bit |
getLowestSetBit() |
Returns the position of the rightmost set bit in this |
compareTo(BigInteger val) |
Compares the values of this and val |
toString() |
Returns the decimal string representation of this |
toString(int radix) |
Returns the string representation of this in base radix |
Usage examples:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | |
Mathematical Operations
In the following, this represents the current BigInteger:
| Function Name | Function |
|---|---|
gcd(BigInteger val) |
Returns the greatest common divisor of the absolute values of this and val |
isProbablePrime(int val) |
Returns a boolean indicating whether this is prime |
nextProbablePrime() |
Returns the first prime greater than this |
modPow(BigInteger b, BigInteger p) |
Returns the value of this raised to the power b modulo p |
modInverse(BigInteger p) |
Returns the multiplicative inverse of this modulo p |
Usage examples:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | |
For Miller–Rabin related knowledge, refer to Miller–Rabin primality test.
Primitive Data Types and Wrapper Classes
Introduction
Since primitive types lack object-oriented features, Java provides corresponding wrapper classes for the eight primitive types to allow them to participate in object-oriented development. These are Byte, Double, Float, Integer, Long, Short, Character, and Boolean. The correspondence is as follows:
| Primitive Data Type | Wrapper Class |
|---|---|
byte |
Byte |
short |
Short |
boolean |
Boolean |
char |
Character |
int |
Integer |
long |
Long |
float |
Float |
double |
Double |
Differences
Here, int and Integer are used as examples:
Integeris the wrapper class forint, whileintis a primitive data type in Java.Integermust be instantiated before use, whileintdoes not.Integeractually corresponds to a reference; whennewanInteger, an object is created, whileintdirectly stores data.- The default value of
Integerisnull, and it can acceptnullandinttype data. The default value ofintis 0, and it cannot acceptnulltype data. - Using
==to determine equality between twoIntegervariables may lead to incorrect results;equals()must be used. Forint,==can be used directly.
Boxing and Unboxing
Here, int and Integer are used as examples:
Integer is essentially an object, and int is a primitive type. Direct assignment between the two types is not possible. When conversion is needed, the primitive type should be converted to the wrapper type, which is called boxing. The reverse is called unboxing.
1 2 3 4 5 6 | |
Java 5 introduced automatic boxing and unboxing:
1 2 | |
Note
Although JDK added automatic boxing and unboxing, please choose the appropriate type when declaring variables because the wrapper type Integer can accept null, while the primitive type int cannot accept null. Therefore, unboxing a wrapper type with a null value will throw an exception. The following code demonstrates this behavior.
1 2 3 4 5 | |
Inheritance
Creating new designs based on existing designs is inheritance in object-oriented programming. In inheritance, new classes are not created out of thin air but are defined based on an existing class. Through inheritance, the new class automatically acquires all members of the base class, including member variables and methods, including members of all access attributes, whether public or private. Obviously, defining new classes through inheritance is much simpler, faster, and more convenient than writing a new class from scratch. Inheritance is an important means of supporting code reuse.
In Java, the keyword for inheritance is extends, and Java only supports single inheritance but can implement multiple interfaces.
In Java, all classes are subclasses of the Object class.
A subclass inherits from a parent class, and all parent class members, including variables and methods, become members of the subclass, except for constructors. Constructors are unique to the parent class because their names are the class names, so parent class constructors do not exist in the subclass. Apart from that, the subclass inherits all members of the parent class.
Each member has different access attributes. The subclass inherits all members of the parent class, but different access attributes cause the subclass to use these members differently: some parent class members directly become part of the subclass's external interface, while others are deeply hidden, even the subclass itself cannot directly access them.
The following table lists the access attributes of parent class members with different access attributes in the subclass:
| Parent Member Access Attribute | Meaning in Parent Class | Meaning in Subclass |
|---|---|---|
public |
Open to all classes | Open to all classes |
protected |
Accessible only by other classes in the same package, itself, and subclasses | Accessible only by other classes in the same package, itself, and subclasses |
Default (default) |
Accessible only by other classes in the same package | If the subclass is in the same package as the parent class, accessible only by other classes in the same package; otherwise, equivalent to private, not accessible |
private |
Accessible only by itself | Not accessible |
Polymorphism
In Java, when assigning an object to a variable, the object's type must match the variable's type. However, due to the concept of inheritance in Java, it can be redefined as a variable can hold its declared type or any subtype of that type.
If a type implements an interface, it can also be called a subtype of that interface.
Object-type variables in Java are polymorphic variables. The term "polymorphism" (literally meaning many forms) refers to a variable being able to hold objects of different types (i.e., its declared type or any subtype).
Polymorphic variables:
- Java object variables are polymorphic; they can hold more than one type of object.
- They can hold objects of the declared type or objects of subclasses of the declared type.
- Upcasting occurs when an object of a subclass is assigned to a variable of a parent class.
Generics
Generics refer to not setting the specific type of properties or method parameters in a class definition, but defining the type when using (or creating an object). Generics are essentially parameterized types, meaning the data type being operated on is specified as a parameter.
Generics provide a compile-time type safety detection mechanism, which allows illegal types to be detected at compile time.
Interfaces
Introduction
An interface in Java is an abstract type, a collection of abstract methods, usually declared with interface. A class implements an interface to inherit the abstract methods of the interface.
An interface is not a class. The way to write an interface is similar to a class, but they are different concepts. A class describes the properties and methods of an object. An interface contains the methods that a class must implement.
Unless the class implementing the interface is abstract, the class must define all methods in the interface.
An interface cannot be instantiated but can be implemented. A class that implements an interface must implement all methods described in the interface; otherwise, it must be declared as an abstract class. Additionally, in Java, an interface type can be used to declare a variable, which can become a null pointer or be bound to an object that implements this interface.
Differences from Classes
- Interfaces cannot be used to instantiate objects.
- Interfaces do not have constructors.
- All methods in an interface must be abstract methods. After Java 8, non-abstract methods can be used in interfaces with the
defaultkeyword. - Interfaces cannot contain member variables, except for static and final variables.
- Interfaces are not inherited by classes but are implemented by classes.
- Interfaces support multiple inheritance; classes do not support multiple inheritance.
Declaration
1 2 3 4 | |
Implementation
1 | |
Lambda Expressions
Introduction
Lambda expressions, also known as closures, are the most important new feature in Java 8.
Lambda expressions allow functions to be passed as parameters to methods (functions as parameters passed into methods).
Using lambda expressions can make code more concise and compact.
Syntax
- Optional type declaration: No need to declare parameter types; the compiler can uniformly infer parameter values.
- Optional parameter parentheses: A single parameter does not require parentheses, but multiple parameters do.
- Optional curly braces: If the body contains a single statement, curly braces are not needed.
- Optional return keyword: If the body has a single expression returning a value, the compiler automatically returns the value; curly braces need to specify that the expression returns a value.
Lambda expressions are declared as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Taking a custom comparator for sorting a string array by length as an example, lambda expressions can be applied as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
You can also use multiple statements in a lambda expression, as in the following example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Here, -> is a derivation symbol, indicating that the preceding parentheses receive parameters and derive the return value (essentially passing a method).
Functional Interfaces
- It is an interface that conforms to Java interface definitions.
- An interface that contains only one abstract method.
- Since there is only one unimplemented method, lambda expressions can automatically fill it in.
Functional interfaces are used as follows:
Output strings with length a multiple of 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
Implement addition, subtraction, multiplication, and division
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
Collection
Collection is an interface in Java implemented by multiple generic container interfaces. Here, Collection refers to data structures that store objects.
In Java, the element type of a Collection must be an object type, not a primitive data type.
The following usage is based on the polymorphic nature in Java, appearing in the form of implementing interfaces.
Common interfaces include List, Queue, Set, and Map.
Container Definition
When defining generic container classes, the data type must be specified at definition time. If the data type is not specified and data is arbitrarily added as Object type, it may compile in Java 8 but with many warning risks.
For example, the following definition is safe; the container only accepts Integer type.
1 | |
The following definition will produce warnings.
1 2 3 4 5 6 | |
Therefore, if there is no special requirement, the second behavior is not recommended, as the compiler cannot help check whether the stored data is safe. When retrieving data with list.get(index), the data type cannot be determined (the retrieved data type is Object), and it must be manually cast back to the original type, which may easily cause incorrect casting exceptions.
If the type is specified, such as List<Integer>, the compiler will check the data type being added, allowing only integer data. When declaring collection variables, only wrapper types like List<Integer> or custom Class can be used, not primitive types like List<int>.
List
ArrayList
ArrayList is an array that can dynamically grow as needed, with a default initial length of 10. If the current length is exceeded, it expands by \(\dfrac{3}{2}\).
Initialization
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
LinkedList
LinkedList is a doubly linked list.
Initialization
1 2 3 4 5 6 7 8 9 10 11 12 | |
Common Methods
In the following, this represents the current List<Integer>:
| Function Name | Function |
|---|---|
size() |
Returns the length of this |
add(Integer val) |
Inserts val at the end of this |
add(int idx, Integer e) |
Inserts element e at position idx in this |
get(int idx) |
Returns the value at position idx in this, throws an exception if out of bounds |
set(int idx, Integer e) |
Modifies the value at position idx in this to e |
Usage examples and differences:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | |
Traversal
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | |
Note
Do not delete elements from a List during for or foreach traversal; otherwise, an exception will be thrown.
The reason is simple: list.size() changes, but the number of iterations already completed in the loop does not change accordingly. The data originally expected at the next index becomes the data at the current index due to the deletion operation. When the next loop runs, the operation will be on the data originally expected at the next-next index, ultimately causing the operated data to not meet expectations.
Queue
LinkedList
LinkedList can be used to implement a regular queue, with the underlying structure being a linked list simulating a queue.
Initialization
1 | |
LinkedList implements both the List interface and the Deque interface, and Deque inherits from Queue, so LinkedList can implement both List and Queue.
ArrayDeque
ArrayDeque can be used to implement a regular queue, with the underlying structure being an array simulating a queue.
Initialization
1 | |
ArrayDeque implements the Deque interface, and Deque inherits from Queue, so ArrayDeque can implement Queue.
Differences Between LinkedList and ArrayDeque in Implementing Queue Interface
- Data Structure: In terms of data structure, both
ArrayDequeandLinkedListimplement the Java Deque double-ended queue interface. However,ArrayDequedoes not implement the Java List interface, so it does not have behavior based on index positions. - Thread Safety: Neither
ArrayDequenorLinkedListconsider thread synchronization and do not guarantee thread safety. - Underlying Implementation: In terms of underlying implementation,
ArrayDequeis based on a dynamic array, whileLinkedListis based on a doubly linked list. - Traversal Speed:
ArrayDequeis a contiguous memory space, and based on the principle of locality, it can better hit CPU cache lines, whileLinkedListis discrete memory space, which is not friendly to cache lines. - Operation Speed: Both
ArrayDequeandLinkedListhave \(O(1)\) time complexity for stack and queue behaviors.ArrayDeque's push and enqueue operations may trigger expansion, but from an amortized analysis perspective, it is still \(O(1)\) time complexity. - Extra Memory Consumption:
ArrayDequehas idle space outside the head and tail pointers of the array, whileLinkedListadds predecessor and successor pointers to nodes.
PriorityQueue
PriorityQueue is a priority queue, defaulting to a min-heap.
Initialization
1 2 | |
Common Methods
In the following, the queue is defined as Queue<Integer>.
| Function Name | Function |
|---|---|
size() |
Returns the current queue length |
add(Integer val) |
Inserts val into the queue; if insertion violates capacity limits, throws an exception |
offer(Integer val) |
Inserts val into the queue; if insertion violates capacity limits, insertion fails but does not throw an exception |
isEmpty() |
Determines if the queue is empty; returns true if empty |
peek() |
Returns the head element; returns null if the queue is empty |
poll() |
Returns and removes the head element; returns null if the queue is empty |
Usage examples and differences:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | |
Traversal
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Deque
Deque is a double-ended queue in Java, commonly used for queue operations and stack operations.
Main Functions
In the following, the queue is defined as Deque<Integer>.
| Function Name | Function |
|---|---|
addFirst(Integer val) |
Inserts val at the head; if insertion violates capacity limits, throws an exception |
offerFirst(Integer val) |
Inserts val at the head; if insertion violates capacity limits, insertion fails but does not throw an exception |
removeFirst() |
Returns and removes the head element; throws an exception if the queue is empty |
pollFirst() |
Returns and removes the head element; returns null if the queue is empty |
peekFirst() |
Returns the head element; returns null if the queue is empty |
push(Integer val) |
Inserts val at the head, equivalent to addFirst |
pop() |
Returns and removes the head element, equivalent to removeFirst |
remove() |
Removes the head element, equivalent to removeFirst |
poll() |
Removes the head element, equivalent to pollFirst |
addLast(Integer val) |
Inserts val at the tail; if insertion violates capacity limits, throws an exception |
offerLast(Integer val) |
Inserts val at the tail; if insertion violates capacity limits, insertion fails but does not throw an exception |
removeLast() |
Returns and removes the tail element; throws an exception if the queue is empty |
pollLast() |
Returns and removes the tail element; returns null if the queue is empty |
peekLast() |
Returns the tail element; returns null if the queue is empty |
add(Integer val) |
Inserts val at the tail, equivalent to addLast |
offer(Integer val) |
Inserts val at the tail, equivalent to offerLast |
Stack Operations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
Double-ended Queue Operations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
Set
Set is a data structure that keeps elements in a container unique.
HashSet
A Set that inserts elements at random positions.
Initialization
1 | |
LinkedHashSet
A Set that maintains insertion order.
Initialization
1 | |
TreeSet
A Set that keeps elements in order, default ascending.
Initialization
1 2 | |
More Usage of TreeSet
These methods are newly created and implemented by TreeSet. We cannot call the following methods using the Set interface, so we create them as follows:
1 2 | |
In the following table, this represents the current TreeSet<Integer>.
| Function Name | Function |
|---|---|
first() |
Returns the first element in this; returns null if none |
last() |
Returns the last element in this; returns null if none |
floor(Integer val) |
Returns the first element in this less than or equal to val; returns null if none |
ceiling(Integer val) |
Returns the first element in this greater than or equal to val; returns null if none |
higher(Integer val) |
Returns the first element in this greater than val; returns null if none |
lower(Integer val) |
Returns the first element in this less than val; returns null if none |
pollFirst() |
Returns and removes the first element in this; returns null if none |
pollLast() |
Returns and removes the last element in this; returns null if none |
Code example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
Set Common Methods
| Function Name | Function |
|---|---|
size() |
Returns the current set size |
add(Integer val) |
Inserts val into the set |
contains(Integer val) |
Determines if the set contains element val |
addAll(Collection e) |
Adds all elements from container e into the current set |
retainAll(Collection e) |
Deletes elements from the current set that do not appear in container e, i.e., finds the intersection of the current set and e |
removeAll(Collection e) |
Deletes elements from the current set that appear in container e, i.e., finds the difference between the current set and e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | |
Traversal
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
Map
Map is a data structure that maintains key-value pairs <Key, Value>, where Key is unique.
HashMap
A Map that inserts elements at random positions.
Initialization
1 | |
LinkedHashMap
A Map that maintains insertion order.
Initialization
1 | |
TreeMap
A Map that keeps keys in order, default ascending.
Initialization
1 2 | |
Common Methods
In the following, this represents the current Map<Integer, Integer>:
| Function Name | Function |
|---|---|
put(Integer key, Integer value) |
Inserts <key, value> into this |
size() |
Returns the size of this |
containsKey(Integer key) |
Determines if this contains an element with key key |
get(Integer key) |
Returns the value corresponding to the element with key key in this |
keySet() |
Returns all keys in this as a set |
Usage examples:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
Traversal
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Of course, the key and value types can also be changed. For example, Map can also be defined as:
1 | |
Arrays
Arrays is a utility class in java.util for array operations. Methods are static and can be called directly using the class name.
Arrays.sort()
Arrays.sort() is a method for sorting arrays. The main overloaded methods are as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | |
Meanings of the numbered overloaded methods:
- Sorts array
ain ascending order by default. - Sorts a specified range of array
ain ascending order by default, sorting interval is left-closed right-open[firstIdx, lastIdx). - Sorts array
ain a custom manner; second parameter-first parameter is descending, first parameter-second parameter is ascending. When using a custom comparator, the array element type must be an object type. - Sorts a specified range of array
ain a custom manner, sorting interval is left-closed right-open[firstIdx, lastIdx). When using a custom comparator, the array element type must be an object type. - Same as 3, optimized code length with Lambda expression.
- Same as 4, optimized code length with Lambda expression.
Arrays.sort() Underlying Function
- When the parameter array element type of
Arrays.sortis a primitive data type (byte,short,char,int,long,double,float), it defaults toDualPivotQuicksort(dual-pivot quicksort), with worst-case complexity up to \(O(n^2)\). - When the parameter array element type of
Arrays.sortis a non-primitive data type, it defaults tolegacyMergeSortandTimSort(merge sort), with complexity \(O(n\log n)\).
This can be verified with the following code:
Codeforces 1646B - Quality vs Quantity
There are \(n\) integers, you need to divide them into two groups. Is it possible for one group to have a smaller length than the other while having a greater sum?
Example Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | |
Arrays.binarySearch()
Arrays.binarySearch() is a method for binary search on a continuous interval of an array. The prerequisite is that the array must be sorted, with time complexity \(O(\log_n)\). The main overloaded methods are as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Source code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
Meanings of the numbered overloaded methods:
- Performs a binary search for
keyin array a. If found, returns its index. If not found, returns a negative number. - Performs a binary search for
keyin array a, searching interval is left-closed right-open[firstIdx,lastIdx). If found, returns its index. If not found, returns a negative number.
Arrays.fill()
Arrays.fill() method assigns the same value to consecutive positions in an array. It accepts parameters: array, fromIndex, toIndex, and the value to fill. After execution, all elements in the left-closed right-open interval [firstIdx,lastIdx) will have the filled value.
Collections
Collections is a utility class in java.util for collection operations. Methods are static and can be called directly using the class name.
Collections.sort()
Collections.sort() underlying principle is to convert all elements into an array and call Arrays.sort(). After sorting, it assigns back to the original collection. Since element types in Java Collection are all object types, it always uses merge sort.
This method cannot sort a specified interval of a collection.
Underlying source code:
1 2 3 4 5 6 7 8 9 | |
Collections.binarySearch()
Collections.binarySearch() performs binary search on a specified interval in a collection, with the same functionality as Arrays.binarySearch().
1 | |
This method cannot search a specified interval.
Collections.swap()
Collections.swap() swaps elements at two specified positions in a collection.
1 | |
Miscellaneous
Numerical Comparison Issues
In Java, if it's purely a numeric type, -0.0 = 0.0. If it's an object type, then -0.0 != 0.0. This can cause trouble when trying to count slopes with a Set. The provided solution is to add 0.0 to all slopes before adding them to the Set.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | |
References
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:OI-wiki
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用