/*******************************************************************************
* Companion code for the book "Introduction to Software Design with Java",
* 2nd edition by Martin P. Robillard.
*
* Copyright (C) 2022 by Martin P. Robillard
*
* This code is licensed under a Creative Commons
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
*
* See http://creativecommons.org/licenses/by-nc-nd/4.0/
*
*******************************************************************************/
package e2.chapter9;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Code samples for Sections 9.1-9.2 and 9.6. The code samples for Section 9.3 are in
* their corresponding classes.
*/
public class Samples
{
public static void main(String[] args) {
samples1(); // Section 9.1
samples2(); // Section 9.2
samples3(); // Section 9.6
}
/**
* For Section 9.1
*/
private static void samples1() {
List<Card> cards = new Deck().getCards();
// Calling 'sort' with an object of an anonymous class
Collections.sort(cards, new Comparator<Card>() {
public int compare(Card pCard1, Card pCard2) {
return pCard1.getRank().compareTo(pCard2.getRank());
}
});
printAll(cards);
// Calling 'sort' with a method reference
Collections.sort(cards, Card::compareByRank);
printAll(cards);
}
/**
* For Section 9.2
*/
@SuppressWarnings("unused")
private static void samples2() {
// Defining a function object of type Filter, which is an application-defined functional interface
Filter blackCards1 = new Filter() {
public boolean accept(Card pCard) {
return pCard.getSuit().getColor() == Suit.Color.BLACK;
}
};
// Defining a function object whose type is a library functional interface
Predicate<Card> blackCards2 = new Predicate<Card>() {
public boolean test(Card pCard) {
return pCard.getSuit().getColor() == Suit.Color.BLACK;
}
};
// Defining a predicate using a lambda expression (expression syntax with parameter type specified)
Predicate<Card> blackCards3 = (Card card) -> card.getSuit().getColor() == Suit.Color.BLACK;
// Defining a predicate using a lambda expression (block syntax with parameter type specified)
Predicate<Card> blackCards4 =
(Card card) -> { return card.getSuit().getColor() == Suit.Color.BLACK; };
// Defining a predicate using a lambda expression (expression syntax with parameter type not specified)
Predicate<Card> blackCards5 = (card) -> card.getSuit().getColor() == Suit.Color.BLACK;
// Defining a predicate using a lambda expression (expression syntax with parameter type not specified
// and no parentheses around the parameter
Predicate<Card> blackCards6 = card -> card.getSuit().getColor() == Suit.Color.BLACK;
// Sample use of the filter:
int total = 0;
for( Card card : new Deck().getCards() ) {
if( blackCards6.test(card) ) {
total++;
}
}
System.out.println(total);
// Example use of removeIf with a lambda that implements the filter
ArrayList<Card> cards = new ArrayList<>(new Deck().getCards());
cards.removeIf(card -> card.getSuit().getColor() == Suit.Color.BLACK );
printAll(cards);
// Using a lambda expression that delegates to an implementation method
cards = new ArrayList<>(new Deck().getCards());
cards.removeIf(card -> card.hasBlackSuit() );
printAll(cards);
// Using a reference to an instance method of an arbitrary object of a particular type
cards = new ArrayList<>(new Deck().getCards());
cards.removeIf(Card::hasBlackSuit);
printAll(cards);
// Using a reference to a static method
cards = new ArrayList<>(new Deck().getCards());
cards.removeIf(CardUtils::hasBlackSuit);
printAll(cards);
// Using a reference to an instance method of a particular object
Deck deck = new Deck();
cards = new ArrayList<>(new Deck().getCards());
cards.removeIf(deck::topSameColorAs);
printAll(cards);
}
/**
* For Section 9.6
*/
@SuppressWarnings("unused")
public static void samples3() {
// Data as a stream
Stream<Card> cards = new Deck().stream();
long total = cards.count();
System.out.println(total);
Stream<Card> sortedCards = new Deck().stream().sorted();
sortedCards.forEach(System.out::println);
Stream<Card> sortedCards2 = new Deck().stream().sorted().limit(10);
sortedCards2.forEach(System.out::println);
Stream<Card> cards2 = Stream.concat(new Deck().stream(), new Deck().stream());
System.out.println(cards2.count());
Stream<Card> withDuplicates = Stream.concat(new Deck().stream(), new Deck().stream());
Stream<Card> withoutDuplicates = withDuplicates.distinct();
// Applying Higher-Order Functions to Streams
new Deck().stream().forEach(card -> System.out.println(card)); // or
new Deck().stream().forEach(System.out::println);
boolean allClubs = new Deck().stream()
.allMatch(card -> card.getSuit() == Suit.CLUBS );
// Filtering streams
long numberOfFaceCards = new Deck().stream()
.filter(card -> card.getRank().ordinal() >= Rank.JACK.ordinal()).count();
long numberOfFaceCards2 = new Deck().stream()
.filter(Card::isFaceCard)
.count();
long result = new Deck().stream()
.filter(card -> card.getRank().ordinal() >= Rank.JACK.ordinal()
&& card.getSuit()==Suit.CLUBS).count();
long result2 = new Deck().stream()
.filter(Card::isFaceCard)
.filter(card -> card.getSuit() == Suit.CLUBS)
.count();
// Mapping data elements
new Deck().stream().map(card -> card.getSuit().getColor() );
long result3 = new Deck().stream()
.map(card -> card.getSuit().getColor() )
.filter( color -> color == e2.chapter9.Suit.Color.BLACK )
.count();
new Deck().stream()
.map(card -> Math.min(10, card.getRank().ordinal() + 1));
int total2 = new Deck().stream()
.mapToInt(card -> Math.min(10, card.getRank().ordinal() + 1))
.sum();
int total3 = new Deck().stream()
.map(Card::getRank)
.mapToInt(Rank::ordinal)
.map(ordinal -> Math.min(10, ordinal + 1))
.sum();
// Flat-mapping
List<Deck> listOfDecks = Arrays.asList(new Deck(), new Deck());
listOfDecks.stream()
.flatMap(deck -> deck.getCards().stream())
.forEach(System.out::println);
// Reducing Streams
// Not ideal
List<Card> result4 = new ArrayList<>();
new Deck().stream()
.filter(Card::isFaceCard)
.forEach(card -> result4.add(card));
// Better
List<Card> result5 = new Deck().stream()
.filter(Card::isFaceCard)
.collect(Collectors.toList());
}
private static void printAll(List<Card> pCards) {
for( Card card : pCards) {
System.out.println(card);
}
}
}
c.compare(e1, e2)
must not throw a ClassCastException
for any elements e1
and e2
in the list).
c.compare(e1, e2)
must not throw a ClassCastException
for any elements e1
and e2
in the list).
This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.
The specified list must be modifiable, but need not be resizable.
List.sort(Comparator)
method using the specified list and comparator.T
- the class of the objects in the listlist
- the list to be sorted.c
- the comparator to determine the order of the list. A
null
value indicates that the elements' natural
ordering should be used.ClassCastException
- if the list contains elements that are not
mutually comparable using the specified comparator.UnsupportedOperationException
- if the specified list's
list-iterator does not support the set
operation.IllegalArgumentException
- (optional) if the comparator is
found to violate the Comparator
contractThe methods of this class all throw a NullPointerException
if the collections or class objects provided to them are null.
The documentation for the polymorphic algorithms contained in this class
generally includes a brief description of the implementation. Such
descriptions should be regarded as implementation notes, rather than
parts of the specification. Implementors should feel free to
substitute other algorithms, so long as the specification itself is adhered
to. (For example, the algorithm used by sort
does not have to be
a mergesort, but it does have to be stable.)
The "destructive" algorithms contained in this class, that is, the
algorithms that modify the collection on which they operate, are specified
to throw UnsupportedOperationException
if the collection does not
support the appropriate mutation primitive(s), such as the set
method. These algorithms may, but are not required to, throw this
exception if an invocation would have no effect on the collection. For
example, invoking the sort
method on an unmodifiable list that is
already sorted may or may not throw UnsupportedOperationException
.
This class is a member of the Java Collections Framework.
System
class contains several useful class fields
and methods. It cannot be instantiated.
Among the facilities provided by the System
class
are standard input, standard output, and error output streams;
access to externally defined properties and environment
variables; a means of loading files and libraries; and a utility
method for quickly copying a portion of an array.System
class contains several useful class fields
and methods. It cannot be instantiated.
Among the facilities provided by the System
class
are standard input, standard output, and error output streams;
access to externally defined properties and environment
variables; a means of loading files and libraries; and a utility
method for quickly copying a portion of an array.Lists that support this operation may place limitations on what elements may be added to this list. In particular, some lists will refuse to add null elements, and others will impose restrictions on the type of elements that may be added. List classes should clearly specify in their documentation any restrictions on what elements may be added.
add
in interface Collection<E>
e
- element to be appended to this listtrue
(as specified by Collection.add(E)
)UnsupportedOperationException
- if the add
operation
is not supported by this listClassCastException
- if the class of the specified element
prevents it from being added to this listNullPointerException
- if the specified element is null and this
list does not permit null elementsIllegalArgumentException
- if some property of this element
prevents it from being added to this listStream
and IntStream
:
int sum = widgets.stream()
.filter(w -> w.getColor() == RED)
.mapToInt(w -> w.getWeight())
.sum();
In this example, widgets
is a Collection<Widget>
. We create
a stream of Widget
objects via Collection.stream()
,
filter it to produce a stream containing only the red widgets, and then
transform it into a stream of int
values representing the weight of
each red widget. Then this stream is summed to produce a total weight.
In addition to Stream
, which is a stream of object references,
there are primitive specializations for IntStream
, LongStream
,
and DoubleStream
, all of which are referred to as "streams" and
conform to the characteristics and restrictions described here.
To perform a computation, stream
operations are composed into a
stream pipeline. A stream pipeline consists of a source (which
might be an array, a collection, a generator function, an I/O channel,
etc), zero or more intermediate operations (which transform a
stream into another stream, such as filter(Predicate)
), and a
terminal operation (which produces a result or side-effect, such
as count()
or forEach(Consumer)
).
Streams are lazy; computation on the source data is only performed when the
terminal operation is initiated, and source elements are consumed only
as needed.
A stream implementation is permitted significant latitude in optimizing
the computation of the result. For example, a stream implementation is free
to elide operations (or entire stages) from a stream pipeline -- and
therefore elide invocation of behavioral parameters -- if it can prove that
it would not affect the result of the computation. This means that
side-effects of behavioral parameters may not always be executed and should
not be relied upon, unless otherwise specified (such as by the terminal
operations forEach
and forEachOrdered
). (For a specific
example of such an optimization, see the API note documented on the
count()
operation. For more detail, see the
side-effects section of the
stream package documentation.)
Collections and streams, while bearing some superficial similarities,
have different goals. Collections are primarily concerned with the efficient
management of, and access to, their elements. By contrast, streams do not
provide a means to directly access or manipulate their elements, and are
instead concerned with declaratively describing their source and the
computational operations which will be performed in aggregate on that source.
However, if the provided stream operations do not offer the desired
functionality, the BaseStream.iterator()
and BaseStream.spliterator()
operations
can be used to perform a controlled traversal.
A stream pipeline, like the "widgets" example above, can be viewed as
a query on the stream source. Unless the source was explicitly
designed for concurrent modification (such as a ConcurrentHashMap
),
unpredictable or erroneous behavior may result from modifying the stream
source while it is being queried.
Most stream operations accept parameters that describe user-specified
behavior, such as the lambda expression w -> w.getWeight()
passed to
mapToInt
in the example above. To preserve correct behavior,
these behavioral parameters:
Such parameters are always instances of a
functional interface such
as Function
, and are often lambda expressions or
method references. Unless otherwise specified these parameters must be
non-null.
A stream should be operated on (invoking an intermediate or terminal stream
operation) only once. This rules out, for example, "forked" streams, where
the same source feeds two or more pipelines, or multiple traversals of the
same stream. A stream implementation may throw IllegalStateException
if it detects that the stream is being reused. However, since some stream
operations may return their receiver rather than a new stream object, it may
not be possible to detect reuse in all cases.
Streams have a BaseStream.close()
method and implement AutoCloseable
.
Operating on a stream after it has been closed will throw IllegalStateException
.
Most stream instances do not actually need to be closed after use, as they
are backed by collections, arrays, or generating functions, which require no
special resource management. Generally, only streams whose source is an IO channel,
such as those returned by Files.lines(Path)
, will require closing. If a
stream does require closing, it must be opened as a resource within a try-with-resources
statement or similar control structure to ensure that it is closed promptly after its
operations have completed.
Stream pipelines may execute either sequentially or in
parallel. This
execution mode is a property of the stream. Streams are created
with an initial choice of sequential or parallel execution. (For example,
Collection.stream()
creates a sequential stream,
and Collection.parallelStream()
creates
a parallel one.) This choice of execution mode may be modified by the
BaseStream.sequential()
or BaseStream.parallel()
methods, and may be queried with
the BaseStream.isParallel()
method.
Collector
. A Collector
encapsulates the functions used as arguments to
collect(Supplier, BiConsumer, BiConsumer)
, allowing for reuse of
collection strategies and composition of collect operations such as
multiple-level grouping or partitioning.
Collector
. A Collector
encapsulates the functions used as arguments to
collect(Supplier, BiConsumer, BiConsumer)
, allowing for reuse of
collection strategies and composition of collect operations such as
multiple-level grouping or partitioning.
If the stream is parallel, and the Collector
is concurrent
, and
either the stream is unordered or the collector is
unordered
,
then a concurrent reduction will be performed (see Collector
for
details on concurrent reduction.)
This is a terminal operation.
When executed in parallel, multiple intermediate results may be
instantiated, populated, and merged so as to maintain isolation of
mutable data structures. Therefore, even when executed in parallel
with non-thread-safe data structures (such as ArrayList
), no
additional synchronization is needed for a parallel reduction.
List<String> asList = stringStream.collect(Collectors.toList());
The following will classify Person
objects by city:
Map<String, List<Person>> peopleByCity
= personStream.collect(Collectors.groupingBy(Person::getCity));
The following will classify Person
objects by state and city,
cascading two Collector
s together:
Map<String, Map<String, List<Person>>> peopleByStateAndCity
= personStream.collect(Collectors.groupingBy(Person::getState,
Collectors.groupingBy(Person::getCity)));
R
- the type of the resultA
- the intermediate accumulation type of the Collector
collector
- the Collector
describing the reductionStream
with this collection as its source.
Stream
with this collection as its source.
This method should be overridden when the spliterator()
method cannot return a spliterator that is IMMUTABLE
,
CONCURRENT
, or late-binding. (See spliterator()
for details.)
Stream
from the
collection's Spliterator
.Stream
over the elements in this collectionCollector
that accumulates the input elements into a
new List
. There are no guarantees on the type, mutability,
serializability, or thread-safety of the List
returned; if more
control over the returned List
is required, use toCollection(Supplier)
.Collector
that accumulates the input elements into a
new List
. There are no guarantees on the type, mutability,
serializability, or thread-safety of the List
returned; if more
control over the returned List
is required, use toCollection(Supplier)
.T
- the type of the input elementsCollector
which collects all the input elements into a
List
, in encounter orderCollector
that implement various useful reduction
operations, such as accumulating elements into collections, summarizing
elements according to various criteria, etc.
Collector
that implement various useful reduction
operations, such as accumulating elements into collections, summarizing
elements according to various criteria, etc.
The following are examples of using the predefined collectors to perform common mutable reduction tasks:
// Accumulate names into a List
List<String> list = people.stream()
.map(Person::getName)
.collect(Collectors.toList());
// Accumulate names into a TreeSet
Set<String> set = people.stream()
.map(Person::getName)
.collect(Collectors.toCollection(TreeSet::new));
// Convert elements to strings and concatenate them, separated by commas
String joined = things.stream()
.map(Object::toString)
.collect(Collectors.joining(", "));
// Compute sum of salaries of employee
int total = employees.stream()
.collect(Collectors.summingInt(Employee::getSalary));
// Group employees by department
Map<Department, List<Employee>> byDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
// Compute sum of salaries by department
Map<Department, Integer> totalByDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment,
Collectors.summingInt(Employee::getSalary)));
// Partition students into passing and failing
Map<Boolean, List<Student>> passingFailing = students.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
List
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
List
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
The size
, isEmpty
, get
, set
,
iterator
, and listIterator
operations run in constant
time. The add
operation runs in amortized constant time,
that is, adding n elements requires O(n) time. All of the other operations
run in linear time (roughly speaking). The constant factor is low compared
to that for the LinkedList
implementation.
Each ArrayList
instance has a capacity. The capacity is
the size of the array used to store the elements in the list. It is always
at least as large as the list size. As elements are added to an ArrayList,
its capacity grows automatically. The details of the growth policy are not
specified beyond the fact that adding an element has constant amortized
time cost.
An application can increase the capacity of an ArrayList
instance
before adding a large number of elements using the ensureCapacity
operation. This may reduce the amount of incremental reallocation.
Note that this implementation is not synchronized.
If multiple threads access an ArrayList
instance concurrently,
and at least one of the threads modifies the list structurally, it
must be synchronized externally. (A structural modification is
any operation that adds or deletes one or more elements, or explicitly
resizes the backing array; merely setting the value of an element is not
a structural modification.) This is typically accomplished by
synchronizing on some object that naturally encapsulates the list.
If no such object exists, the list should be "wrapped" using the
Collections.synchronizedList
method. This is best done at creation time, to prevent accidental
unsynchronized access to the list:
List list = Collections.synchronizedList(new ArrayList(...));
The iterators returned by this class's iterator
and
listIterator
methods are fail-fast:
if the list is structurally modified at any time after the iterator is
created, in any way except through the iterator's own
remove
or
add
methods, the iterator will throw a
ConcurrentModificationException
. Thus, in the face of
concurrent modification, the iterator fails quickly and cleanly, rather
than risking arbitrary, non-deterministic behavior at an undetermined
time in the future.
Note that the fail-fast behavior of an iterator cannot be guaranteed
as it is, generally speaking, impossible to make any hard guarantees in the
presence of unsynchronized concurrent modification. Fail-fast iterators
throw ConcurrentModificationException
on a best-effort basis.
Therefore, it would be wrong to write a program that depended on this
exception for its correctness: the fail-fast behavior of iterators
should be used only to detect bugs.
This class is a member of the Java Collections Framework.
closed
after its contents
have been placed into this stream. (If a mapped stream is null
an empty stream is used, instead.)
closed
after its contents
have been placed into this stream. (If a mapped stream is null
an empty stream is used, instead.)
This is an intermediate operation.
flatMap()
operation has the effect of applying a one-to-many
transformation to the elements of the stream, and then flattening the
resulting elements into a new stream.
Examples.
If orders
is a stream of purchase orders, and each purchase
order contains a collection of line items, then the following produces a
stream containing all the line items in all the orders:
orders.flatMap(order -> order.getLineItems().stream())...
If path
is the path to a file, then the following produces a
stream of the words
contained in that file:
Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8);
Stream<String> words = lines.flatMap(line -> Stream.of(line.split(" +")));
The mapper
function passed to flatMap
splits a line,
using a simple regular expression, into an array of words, and then
creates a stream of words from that array.R
- The element type of the new streammapper
- a non-interfering,
stateless
function to apply to each element which produces a stream
of new valuesSerializable
and implements RandomAccess
.
Serializable
and implements RandomAccess
.
The returned list implements the optional Collection
methods, except
those that would change the size of the returned list. Those methods leave
the list unchanged and throw UnsupportedOperationException
.
Collection.toArray()
.
This method provides a way to wrap an existing array:
Integer[] numbers = ...
...
List<Integer> values = Arrays.asList(numbers);
This method also provides a convenient way to create a fixed-size list initialized to contain several elements:
List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
The list returned by this method is modifiable.
To create an unmodifiable list, use
Collections.unmodifiableList
or Unmodifiable Lists.
T
- the class of the objects in the arraya
- the array by which the list will be backedNullPointerException
- if the specified array is null
The methods in this class all throw a NullPointerException
,
if the specified array reference is null, except where noted.
The documentation for the methods contained in this class includes
brief descriptions of the implementations. Such descriptions should
be regarded as implementation notes, rather than parts of the
specification. Implementors should feel free to substitute other
algorithms, so long as the specification itself is adhered to. (For
example, the algorithm used by sort(Object[])
does not have to be
a MergeSort, but it does have to be stable.)
This class is a member of the Java Collections Framework.
This is an intermediate operation.
mapper
- a non-interfering,
stateless
function to apply to each element
return reduce(0, Integer::sum);
This is a terminal operation.
List
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
List
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
The size
, isEmpty
, get
, set
,
iterator
, and listIterator
operations run in constant
time. The add
operation runs in amortized constant time,
that is, adding n elements requires O(n) time. All of the other operations
run in linear time (roughly speaking). The constant factor is low compared
to that for the LinkedList
implementation.
Each ArrayList
instance has a capacity. The capacity is
the size of the array used to store the elements in the list. It is always
at least as large as the list size. As elements are added to an ArrayList,
its capacity grows automatically. The details of the growth policy are not
specified beyond the fact that adding an element has constant amortized
time cost.
An application can increase the capacity of an ArrayList
instance
before adding a large number of elements using the ensureCapacity
operation. This may reduce the amount of incremental reallocation.
Note that this implementation is not synchronized.
If multiple threads access an ArrayList
instance concurrently,
and at least one of the threads modifies the list structurally, it
must be synchronized externally. (A structural modification is
any operation that adds or deletes one or more elements, or explicitly
resizes the backing array; merely setting the value of an element is not
a structural modification.) This is typically accomplished by
synchronizing on some object that naturally encapsulates the list.
If no such object exists, the list should be "wrapped" using the
Collections.synchronizedList
method. This is best done at creation time, to prevent accidental
unsynchronized access to the list:
List list = Collections.synchronizedList(new ArrayList(...));
The iterators returned by this class's iterator
and
listIterator
methods are fail-fast:
if the list is structurally modified at any time after the iterator is
created, in any way except through the iterator's own
remove
or
add
methods, the iterator will throw a
ConcurrentModificationException
. Thus, in the face of
concurrent modification, the iterator fails quickly and cleanly, rather
than risking arbitrary, non-deterministic behavior at an undetermined
time in the future.
Note that the fail-fast behavior of an iterator cannot be guaranteed
as it is, generally speaking, impossible to make any hard guarantees in the
presence of unsynchronized concurrent modification. Fail-fast iterators
throw ConcurrentModificationException
on a best-effort basis.
Therefore, it would be wrong to write a program that depended on this
exception for its correctness: the fail-fast behavior of iterators
should be used only to detect bugs.
This class is a member of the Java Collections Framework.
c
- the collection whose elements are to be placed into this listNullPointerException
- if the specified collection is nullList
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
List
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
The size
, isEmpty
, get
, set
,
iterator
, and listIterator
operations run in constant
time. The add
operation runs in amortized constant time,
that is, adding n elements requires O(n) time. All of the other operations
run in linear time (roughly speaking). The constant factor is low compared
to that for the LinkedList
implementation.
Each ArrayList
instance has a capacity. The capacity is
the size of the array used to store the elements in the list. It is always
at least as large as the list size. As elements are added to an ArrayList,
its capacity grows automatically. The details of the growth policy are not
specified beyond the fact that adding an element has constant amortized
time cost.
An application can increase the capacity of an ArrayList
instance
before adding a large number of elements using the ensureCapacity
operation. This may reduce the amount of incremental reallocation.
Note that this implementation is not synchronized.
If multiple threads access an ArrayList
instance concurrently,
and at least one of the threads modifies the list structurally, it
must be synchronized externally. (A structural modification is
any operation that adds or deletes one or more elements, or explicitly
resizes the backing array; merely setting the value of an element is not
a structural modification.) This is typically accomplished by
synchronizing on some object that naturally encapsulates the list.
If no such object exists, the list should be "wrapped" using the
Collections.synchronizedList
method. This is best done at creation time, to prevent accidental
unsynchronized access to the list:
List list = Collections.synchronizedList(new ArrayList(...));
The iterators returned by this class's iterator
and
listIterator
methods are fail-fast:
if the list is structurally modified at any time after the iterator is
created, in any way except through the iterator's own
remove
or
add
methods, the iterator will throw a
ConcurrentModificationException
. Thus, in the face of
concurrent modification, the iterator fails quickly and cleanly, rather
than risking arbitrary, non-deterministic behavior at an undetermined
time in the future.
Note that the fail-fast behavior of an iterator cannot be guaranteed
as it is, generally speaking, impossible to make any hard guarantees in the
presence of unsynchronized concurrent modification. Fail-fast iterators
throw ConcurrentModificationException
on a best-effort basis.
Therefore, it would be wrong to write a program that depended on this
exception for its correctness: the fail-fast behavior of iterators
should be used only to detect bugs.
This class is a member of the Java Collections Framework.
c
- the collection whose elements are to be placed into this listNullPointerException
- if the specified collection is nullList
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
List
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
The size
, isEmpty
, get
, set
,
iterator
, and listIterator
operations run in constant
time. The add
operation runs in amortized constant time,
that is, adding n elements requires O(n) time. All of the other operations
run in linear time (roughly speaking). The constant factor is low compared
to that for the LinkedList
implementation.
Each ArrayList
instance has a capacity. The capacity is
the size of the array used to store the elements in the list. It is always
at least as large as the list size. As elements are added to an ArrayList,
its capacity grows automatically. The details of the growth policy are not
specified beyond the fact that adding an element has constant amortized
time cost.
An application can increase the capacity of an ArrayList
instance
before adding a large number of elements using the ensureCapacity
operation. This may reduce the amount of incremental reallocation.
Note that this implementation is not synchronized.
If multiple threads access an ArrayList
instance concurrently,
and at least one of the threads modifies the list structurally, it
must be synchronized externally. (A structural modification is
any operation that adds or deletes one or more elements, or explicitly
resizes the backing array; merely setting the value of an element is not
a structural modification.) This is typically accomplished by
synchronizing on some object that naturally encapsulates the list.
If no such object exists, the list should be "wrapped" using the
Collections.synchronizedList
method. This is best done at creation time, to prevent accidental
unsynchronized access to the list:
List list = Collections.synchronizedList(new ArrayList(...));
The iterators returned by this class's iterator
and
listIterator
methods are fail-fast:
if the list is structurally modified at any time after the iterator is
created, in any way except through the iterator's own
remove
or
add
methods, the iterator will throw a
ConcurrentModificationException
. Thus, in the face of
concurrent modification, the iterator fails quickly and cleanly, rather
than risking arbitrary, non-deterministic behavior at an undetermined
time in the future.
Note that the fail-fast behavior of an iterator cannot be guaranteed
as it is, generally speaking, impossible to make any hard guarantees in the
presence of unsynchronized concurrent modification. Fail-fast iterators
throw ConcurrentModificationException
on a best-effort basis.
Therefore, it would be wrong to write a program that depended on this
exception for its correctness: the fail-fast behavior of iterators
should be used only to detect bugs.
This class is a member of the Java Collections Framework.
c
- the collection whose elements are to be placed into this listNullPointerException
- if the specified collection is nullIntStream
consisting of the results of applying the
given function to the elements of this stream.
IntStream
consisting of the results of applying the
given function to the elements of this stream.
This is an intermediate operation.
mapper
- a non-interfering,
stateless
function to apply to each elementint
values. That is,
the result the argument closer to the value of
Integer.MIN_VALUE
. If the arguments have the same
value, the result is that same value.int
values. That is,
the result the argument closer to the value of
Integer.MIN_VALUE
. If the arguments have the same
value, the result is that same value.a
- an argument.b
- another argument.a
and b
.Math
contains methods for performing basic
numeric operations such as the elementary exponential, logarithm,
square root, and trigonometric functions.
Math
contains methods for performing basic
numeric operations such as the elementary exponential, logarithm,
square root, and trigonometric functions.
Unlike some of the numeric methods of class
StrictMath
, all implementations of the equivalent
functions of class Math
are not defined to return the
bit-for-bit same results. This relaxation permits
better-performing implementations where strict reproducibility is
not required.
By default many of the Math
methods simply call
the equivalent method in StrictMath
for their
implementation. Code generators are encouraged to use
platform-specific native libraries or microprocessor instructions,
where available, to provide higher-performance implementations of
Math
methods. Such higher-performance
implementations still must conform to the specification for
Math
.
The quality of implementation specifications concern two
properties, accuracy of the returned result and monotonicity of the
method. Accuracy of the floating-point Math
methods is
measured in terms of ulps, units in the last place. For a
given floating-point format, an ulp of a
specific real number value is the distance between the two
floating-point values bracketing that numerical value. When
discussing the accuracy of a method as a whole rather than at a
specific argument, the number of ulps cited is for the worst-case
error at any argument. If a method always has an error less than
0.5 ulps, the method always returns the floating-point number
nearest the exact result; such a method is correctly
rounded. A correctly rounded method is generally the best a
floating-point approximation can be; however, it is impractical for
many floating-point methods to be correctly rounded. Instead, for
the Math
class, a larger error bound of 1 or 2 ulps is
allowed for certain methods. Informally, with a 1 ulp error bound,
when the exact result is a representable number, the exact result
should be returned as the computed result; otherwise, either of the
two floating-point values which bracket the exact result may be
returned. For exact results large in magnitude, one of the
endpoints of the bracket may be infinite. Besides accuracy at
individual arguments, maintaining proper relations between the
method at different arguments is also important. Therefore, most
methods with more than 0.5 ulp errors are required to be
semi-monotonic: whenever the mathematical function is
non-decreasing, so is the floating-point approximation, likewise,
whenever the mathematical function is non-increasing, so is the
floating-point approximation. Not all approximations that have 1
ulp accuracy will automatically meet the monotonicity requirements.
The platform uses signed two's complement integer arithmetic with
int and long primitive types. The developer should choose
the primitive type to ensure that arithmetic operations consistently
produce correct results, which in some cases means the operations
will not overflow the range of values of the computation.
The best practice is to choose the primitive type and algorithm to avoid
overflow. In cases where the size is int
or long
and
overflow errors need to be detected, the methods whose names end with
Exact
throw an ArithmeticException
when the results overflow.
sin
, cos
, tan
, asin
, acos
, atan
, exp
, expm1
, log
, log10
, log1p
,
sinh
, cosh
, tanh
, hypot
, and pow
. (The sqrt
operation is a required part of IEEE 754 from a different section
of the standard.) The special case behavior of the recommended
operations generally follows the guidance of the IEEE 754
standard. However, the pow
method defines different
behavior for some arguments, as noted in its specification. The IEEE 754 standard defines its operations to be
correctly rounded, which is a more stringent quality of
implementation condition than required for most of the methods in
question that are also included in this class.String
class represents character strings. All
string literals in Java programs, such as "abc"
, are
implemented as instances of this class.
String
class represents character strings. All
string literals in Java programs, such as "abc"
, are
implemented as instances of this class.
Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared. For example:
String str = "abc";
is equivalent to:
char data[] = {'a', 'b', 'c'}; String str = new String(data);
Here are some more examples of how strings can be used:
System.out.println("abc"); String cde = "cde"; System.out.println("abc" + cde); String c = "abc".substring(2, 3); String d = cde.substring(1, 2);
The class String
includes methods for examining
individual characters of the sequence, for comparing strings, for
searching strings, for extracting substrings, and for creating a
copy of a string with all characters translated to uppercase or to
lowercase. Case mapping is based on the Unicode Standard version
specified by the Character
class.
The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. For additional information on string concatenation and conversion, see The Java Language Specification.
Unless otherwise noted, passing a null
argument to a constructor
or method in this class will cause a NullPointerException
to be
thrown.
A String
represents a string in the UTF-16 format
in which supplementary characters are represented by surrogate
pairs (see the section Unicode
Character Representations in the Character
class for
more information).
Index values refer to char
code units, so a supplementary
character uses two positions in a String
.
The String
class provides methods for dealing with
Unicode code points (i.e., characters), in addition to those for
dealing with Unicode code units (i.e., char
values).
Unless otherwise noted, methods for comparing Strings do not take locale
into account. The Collator
class provides methods for
finer-grain, locale-sensitive String comparison.
javac
compiler
may implement the operator with StringBuffer
, StringBuilder
,
or java.lang.invoke.StringConcatFactory
depending on the JDK version. The
implementation of string conversion is typically through the method toString
,
defined by Object
and inherited by all classes in Java.compareTo
in interface Comparable<E extends Enum<E>>
o
- the object to be compared.This is an intermediate operation.
R
- The element type of the new streammapper
- a non-interfering,
stateless
function to apply to each elementEnumSet
and EnumMap
.This is an intermediate operation.
predicate
- a non-interfering,
stateless
predicate to apply to each element to determine if it
should be includedtrue
is
returned and the predicate is not evaluated.
true
is
returned and the predicate is not evaluated.
This is a short-circuiting terminal operation.
true
(regardless of P(x)).predicate
- a non-interfering,
stateless
predicate to apply to elements of this streamtrue
if either all elements of the stream match the
provided predicate or the stream is empty, otherwise false
Object.equals(Object)
) of this stream.
Object.equals(Object)
) of this stream.
For ordered streams, the selection of distinct elements is stable (for duplicated elements, the element appearing first in the encounter order is preserved.) For unordered streams, no stability guarantees are made.
This is a stateful intermediate operation.
distinct()
in parallel pipelines is
relatively expensive (requires that the operation act as a full barrier,
with substantial buffering overhead), and stability is often not needed.
Using an unordered stream source (such as generate(Supplier)
)
or removing the ordering constraint with BaseStream.unordered()
may result
in significantly more efficient execution for distinct()
in parallel
pipelines, if the semantics of your situation permit. If consistency
with encounter order is required, and you are experiencing poor performance
or memory utilization with distinct()
in parallel pipelines,
switching to sequential execution with BaseStream.sequential()
may improve
performance.Collections.sort
or Arrays.sort
) to allow precise control over the sort order.
Comparators can also be used to control the order of certain data
structures (such as sorted sets or
sorted maps), or to provide an ordering for
collections of objects that don't have a natural ordering.Collections.sort
or Arrays.sort
) to allow precise control over the sort order.
Comparators can also be used to control the order of certain data
structures (such as sorted sets or
sorted maps), or to provide an ordering for
collections of objects that don't have a natural ordering.
The ordering imposed by a comparator c
on a set of elements
S
is said to be consistent with equals if and only if
c.compare(e1, e2)==0
has the same boolean value as
e1.equals(e2)
for every e1
and e2
in
S
.
Caution should be exercised when using a comparator capable of imposing an
ordering inconsistent with equals to order a sorted set (or sorted map).
Suppose a sorted set (or sorted map) with an explicit comparator c
is used with elements (or keys) drawn from a set S
. If the
ordering imposed by c
on S
is inconsistent with equals,
the sorted set (or sorted map) will behave "strangely." In particular the
sorted set (or sorted map) will violate the general contract for set (or
map), which is defined in terms of equals
.
For example, suppose one adds two elements a
and b
such that
(a.equals(b) && c.compare(a, b) != 0)
to an empty TreeSet
with comparator c
.
The second add
operation will return
true (and the size of the tree set will increase) because a
and
b
are not equivalent from the tree set's perspective, even though
this is contrary to the specification of the
Set.add
method.
Note: It is generally a good idea for comparators to also implement
java.io.Serializable
, as they may be used as ordering methods in
serializable data structures (like TreeSet
, TreeMap
). In
order for the data structure to serialize successfully, the comparator (if
provided) must implement Serializable
.
For the mathematically inclined, the relation that defines the
imposed ordering that a given comparator c
imposes on a
given set of objects S
is:
{(x, y) such that c.compare(x, y) <= 0}.The quotient for this total order is:
{(x, y) such that c.compare(x, y) == 0}.It follows immediately from the contract for
compare
that the
quotient is an equivalence relation on S
, and that the
imposed ordering is a total order on S
. When we say that
the ordering imposed by c
on S
is consistent with
equals, we mean that the quotient for the ordering is the equivalence
relation defined by the objects' equals(Object)
method(s):{(x, y) such that x.equals(y)}.In other words, when the imposed ordering is consistent with equals, the equivalence classes defined by the equivalence relation of the
equals
method and the equivalence classes defined by
the quotient of the compare
method are the same.
Unlike Comparable
, a comparator may optionally permit
comparison of null arguments, while maintaining the requirements for
an equivalence relation.
This interface is a member of the Java Collections Framework.
This method operates on the two input streams and binds each stream to its source. As a result subsequent modifications to an input stream source may not be reflected in the concatenated stream result.
Stream<T> concat = Stream.of(s1, s2, s3, s4).flatMap(s -> s);
StackOverflowError
.
Subsequent changes to the sequential/parallel execution mode of the returned stream are not guaranteed to be propagated to the input streams.
T
- The type of stream elementsa
- the first streamb
- the second streammaxSize
in length.
maxSize
in length.
limit()
is generally a cheap operation on sequential
stream pipelines, it can be quite expensive on ordered parallel pipelines,
especially for large values of maxSize
, since limit(n)
is constrained to return not just any n elements, but the
first n elements in the encounter order. Using an unordered
stream source (such as generate(Supplier)
) or removing the
ordering constraint with BaseStream.unordered()
may result in significant
speedups of limit()
in parallel pipelines, if the semantics of
your situation permit. If consistency with encounter order is required,
and you are experiencing poor performance or memory utilization with
limit()
in parallel pipelines, switching to sequential execution
with BaseStream.sequential()
may improve performance.maxSize
- the number of elements the stream should be limited toIllegalArgumentException
- if maxSize
is negativeThis is a terminal operation.
The behavior of this operation is explicitly nondeterministic. For parallel stream pipelines, this operation does not guarantee to respect the encounter order of the stream, as doing so would sacrifice the benefit of parallelism. For any given element, the action may be performed at whatever time and in whatever thread the library chooses. If the action accesses shared state, it is responsible for providing the required synchronization.
action
- a
non-interfering action to perform on the elementsList
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
List
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
The size
, isEmpty
, get
, set
,
iterator
, and listIterator
operations run in constant
time. The add
operation runs in amortized constant time,
that is, adding n elements requires O(n) time. All of the other operations
run in linear time (roughly speaking). The constant factor is low compared
to that for the LinkedList
implementation.
Each ArrayList
instance has a capacity. The capacity is
the size of the array used to store the elements in the list. It is always
at least as large as the list size. As elements are added to an ArrayList,
its capacity grows automatically. The details of the growth policy are not
specified beyond the fact that adding an element has constant amortized
time cost.
An application can increase the capacity of an ArrayList
instance
before adding a large number of elements using the ensureCapacity
operation. This may reduce the amount of incremental reallocation.
Note that this implementation is not synchronized.
If multiple threads access an ArrayList
instance concurrently,
and at least one of the threads modifies the list structurally, it
must be synchronized externally. (A structural modification is
any operation that adds or deletes one or more elements, or explicitly
resizes the backing array; merely setting the value of an element is not
a structural modification.) This is typically accomplished by
synchronizing on some object that naturally encapsulates the list.
If no such object exists, the list should be "wrapped" using the
Collections.synchronizedList
method. This is best done at creation time, to prevent accidental
unsynchronized access to the list:
List list = Collections.synchronizedList(new ArrayList(...));
The iterators returned by this class's iterator
and
listIterator
methods are fail-fast:
if the list is structurally modified at any time after the iterator is
created, in any way except through the iterator's own
remove
or
add
methods, the iterator will throw a
ConcurrentModificationException
. Thus, in the face of
concurrent modification, the iterator fails quickly and cleanly, rather
than risking arbitrary, non-deterministic behavior at an undetermined
time in the future.
Note that the fail-fast behavior of an iterator cannot be guaranteed
as it is, generally speaking, impossible to make any hard guarantees in the
presence of unsynchronized concurrent modification. Fail-fast iterators
throw ConcurrentModificationException
on a best-effort basis.
Therefore, it would be wrong to write a program that depended on this
exception for its correctness: the fail-fast behavior of iterators
should be used only to detect bugs.
This class is a member of the Java Collections Framework.
c
- the collection whose elements are to be placed into this listNullPointerException
- if the specified collection is nullList
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
List
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
The size
, isEmpty
, get
, set
,
iterator
, and listIterator
operations run in constant
time. The add
operation runs in amortized constant time,
that is, adding n elements requires O(n) time. All of the other operations
run in linear time (roughly speaking). The constant factor is low compared
to that for the LinkedList
implementation.
Each ArrayList
instance has a capacity. The capacity is
the size of the array used to store the elements in the list. It is always
at least as large as the list size. As elements are added to an ArrayList,
its capacity grows automatically. The details of the growth policy are not
specified beyond the fact that adding an element has constant amortized
time cost.
An application can increase the capacity of an ArrayList
instance
before adding a large number of elements using the ensureCapacity
operation. This may reduce the amount of incremental reallocation.
Note that this implementation is not synchronized.
If multiple threads access an ArrayList
instance concurrently,
and at least one of the threads modifies the list structurally, it
must be synchronized externally. (A structural modification is
any operation that adds or deletes one or more elements, or explicitly
resizes the backing array; merely setting the value of an element is not
a structural modification.) This is typically accomplished by
synchronizing on some object that naturally encapsulates the list.
If no such object exists, the list should be "wrapped" using the
Collections.synchronizedList
method. This is best done at creation time, to prevent accidental
unsynchronized access to the list:
List list = Collections.synchronizedList(new ArrayList(...));
The iterators returned by this class's iterator
and
listIterator
methods are fail-fast:
if the list is structurally modified at any time after the iterator is
created, in any way except through the iterator's own
remove
or
add
methods, the iterator will throw a
ConcurrentModificationException
. Thus, in the face of
concurrent modification, the iterator fails quickly and cleanly, rather
than risking arbitrary, non-deterministic behavior at an undetermined
time in the future.
Note that the fail-fast behavior of an iterator cannot be guaranteed
as it is, generally speaking, impossible to make any hard guarantees in the
presence of unsynchronized concurrent modification. Fail-fast iterators
throw ConcurrentModificationException
on a best-effort basis.
Therefore, it would be wrong to write a program that depended on this
exception for its correctness: the fail-fast behavior of iterators
should be used only to detect bugs.
This class is a member of the Java Collections Framework.
c
- the collection whose elements are to be placed into this listNullPointerException
- if the specified collection is nullprint(String)
and then
println()
.print(String)
and then
println()
.x
- The Object
to be printed.Comparable
, a java.lang.ClassCastException
may be thrown
when the terminal operation is executed.
Comparable
, a java.lang.ClassCastException
may be thrown
when the terminal operation is executed.
For ordered streams, the sort is stable. For unordered streams, no stability guarantees are made.
This is a stateful intermediate operation.
List
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
List
interface. Implements
all optional list operations, and permits all elements, including
null
. In addition to implementing the List
interface,
this class provides methods to manipulate the size of the array that is
used internally to store the list. (This class is roughly equivalent to
Vector
, except that it is unsynchronized.)
The size
, isEmpty
, get
, set
,
iterator
, and listIterator
operations run in constant
time. The add
operation runs in amortized constant time,
that is, adding n elements requires O(n) time. All of the other operations
run in linear time (roughly speaking). The constant factor is low compared
to that for the LinkedList
implementation.
Each ArrayList
instance has a capacity. The capacity is
the size of the array used to store the elements in the list. It is always
at least as large as the list size. As elements are added to an ArrayList,
its capacity grows automatically. The details of the growth policy are not
specified beyond the fact that adding an element has constant amortized
time cost.
An application can increase the capacity of an ArrayList
instance
before adding a large number of elements using the ensureCapacity
operation. This may reduce the amount of incremental reallocation.
Note that this implementation is not synchronized.
If multiple threads access an ArrayList
instance concurrently,
and at least one of the threads modifies the list structurally, it
must be synchronized externally. (A structural modification is
any operation that adds or deletes one or more elements, or explicitly
resizes the backing array; merely setting the value of an element is not
a structural modification.) This is typically accomplished by
synchronizing on some object that naturally encapsulates the list.
If no such object exists, the list should be "wrapped" using the
Collections.synchronizedList
method. This is best done at creation time, to prevent accidental
unsynchronized access to the list:
List list = Collections.synchronizedList(new ArrayList(...));
The iterators returned by this class's iterator
and
listIterator
methods are fail-fast:
if the list is structurally modified at any time after the iterator is
created, in any way except through the iterator's own
remove
or
add
methods, the iterator will throw a
ConcurrentModificationException
. Thus, in the face of
concurrent modification, the iterator fails quickly and cleanly, rather
than risking arbitrary, non-deterministic behavior at an undetermined
time in the future.
Note that the fail-fast behavior of an iterator cannot be guaranteed
as it is, generally speaking, impossible to make any hard guarantees in the
presence of unsynchronized concurrent modification. Fail-fast iterators
throw ConcurrentModificationException
on a best-effort basis.
Therefore, it would be wrong to write a program that depended on this
exception for its correctness: the fail-fast behavior of iterators
should be used only to detect bugs.
This class is a member of the Java Collections Framework.
print(long)
and then
println()
.print(long)
and then
println()
.x
- a The long
to be printed.
return mapToLong(e -> 1L).sum();
This is a terminal operation.
List<String> l = Arrays.asList("A", "B", "C", "D");
long count = l.stream().peek(System.out::println).count();
The number of elements covered by the stream source, a List
, is
known and the intermediate operation, peek
, does not inject into
or remove elements from the stream (as may be the case for
flatMap
or filter
operations). Thus the count is the
size of the List
and there is no need to execute the pipeline
and, as a side-effect, print out the list elements.removeIf
in interface Collection<E>
filter
- a predicate which returns true
for elements to be
removedtrue
if any elements were removedNullPointerException
- if the specified filter is nullprint(int)
and then
println()
.print(int)
and then
println()
.x
- The int
to be printed.Console.charset()
if the Console
exists,
stdout.encoding otherwise.
Console.charset()
if the Console
exists,
stdout.encoding otherwise.
For simple stand-alone Java applications, a typical way to write a line of output data is:
System.out.println(data)
See the println
methods in class PrintStream
.
t
- the input argumenttrue
if the input argument matches the predicate,
otherwise false
This is a functional interface
whose functional method is test(Object)
.
The SuppressWarnings
annotation interface is applicable
in all declaration contexts, so an @SuppressWarnings
annotation can be used on any element. As a matter of style,
programmers should always use this annotation on the most deeply
nested element where it is effective. For example, if you want to
suppress a warning in a particular method, you should annotate that
method rather than its class.
The set of warnings suppressed in a given element is a union of
the warnings suppressed in all containing elements. For example,
if you annotate a class to suppress one warning and annotate a
method in the class to suppress another, both warnings will be
suppressed in the method. However, note that if a warning is
suppressed in a module-info
file, the suppression applies
to elements within the file and not to types contained
within the module. Likewise, if a warning is suppressed in a
package-info
file, the suppression applies to elements
within the file and not to types contained within the
package.
Java compilers must recognize all the kinds of warnings defined in the Java Language Specification (JLS section 9.6.4.5) which include:
"unchecked"
.
"deprecation"
.
"removal"
.
"preview"
.
javac
reference implementation recognizes compilation-related warning
names documented in its --help-lint
output.
Unlike sets, lists typically allow duplicate elements. More formally,
lists typically allow pairs of elements e1
and e2
such that e1.equals(e2)
, and they typically allow multiple
null elements if they allow null elements at all. It is not inconceivable
that someone might wish to implement a list that prohibits duplicates, by
throwing runtime exceptions when the user attempts to insert them, but we
expect this usage to be rare.
The List
interface places additional stipulations, beyond those
specified in the Collection
interface, on the contracts of the
iterator
, add
, remove
, equals
, and
hashCode
methods. Declarations for other inherited methods are
also included here for convenience.
The List
interface provides four methods for positional (indexed)
access to list elements. Lists (like Java arrays) are zero based. Note
that these operations may execute in time proportional to the index value
for some implementations (the LinkedList
class, for
example). Thus, iterating over the elements in a list is typically
preferable to indexing through it if the caller does not know the
implementation.
The List
interface provides a special iterator, called a
ListIterator
, that allows element insertion and replacement, and
bidirectional access in addition to the normal operations that the
Iterator
interface provides. A method is provided to obtain a
list iterator that starts at a specified position in the list.
The List
interface provides two methods to search for a specified
object. From a performance standpoint, these methods should be used with
caution. In many implementations they will perform costly linear
searches.
The List
interface provides two methods to efficiently insert and
remove multiple elements at an arbitrary point in the list.
Note: While it is permissible for lists to contain themselves as elements,
extreme caution is advised: the equals
and hashCode
methods are no longer well defined on such a list.
Some list implementations have restrictions on the elements that
they may contain. For example, some implementations prohibit null elements,
and some have restrictions on the types of their elements. Attempting to
add an ineligible element throws an unchecked exception, typically
NullPointerException
or ClassCastException
. Attempting
to query the presence of an ineligible element may throw an exception,
or it may simply return false; some implementations will exhibit the former
behavior and some will exhibit the latter. More generally, attempting an
operation on an ineligible element whose completion would not result in
the insertion of an ineligible element into the list may throw an
exception or it may succeed, at the option of the implementation.
Such exceptions are marked as "optional" in the specification for this
interface.
The List.of
and
List.copyOf
static factory methods
provide a convenient way to create unmodifiable lists. The List
instances created by these methods have the following characteristics:
UnsupportedOperationException
to be thrown.
However, if the contained elements are themselves mutable,
this may cause the List's contents to appear to change.
null
elements. Attempts to create them with
null
elements result in NullPointerException
.
subList
views implement the
RandomAccess
interface.
This interface is a member of the Java Collections Framework.