提交 a24e4400 编写于 作者: M mduigou

Merge

/*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -203,6 +203,12 @@ class Inet6Address extends InetAddress {
*/
private transient NetworkInterface scope_ifname; // null
/**
* set if the object is constructed with a scoped
* interface instead of a numeric scope id.
*/
private boolean scope_ifname_set; // false;
private static final long serialVersionUID = 6880410070516793377L;
// Perform native initialization
......@@ -332,7 +338,7 @@ class Inet6Address extends InetAddress {
}
}
private void initif(String hostName, byte addr[],NetworkInterface nif)
private void initif(String hostName, byte addr[], NetworkInterface nif)
throws UnknownHostException
{
holder().hostName = hostName;
......@@ -344,6 +350,7 @@ class Inet6Address extends InetAddress {
scope_ifname = nif;
scope_id = deriveNumericScope(nif);
scope_id_set = true;
scope_ifname_set = true; // for consistency
}
}
......@@ -431,6 +438,7 @@ class Inet6Address extends InetAddress {
try {
scope_ifname = NetworkInterface.getByName(ifname);
if (scope_ifname != null) {
scope_ifname_set = true;
try {
scope_id = deriveNumericScope(scope_ifname);
} catch (UnknownHostException e) {
......@@ -438,6 +446,12 @@ class Inet6Address extends InetAddress {
// the machine being used for deserialization has
// the same interface name but without IPv6 configured.
}
} else {
/* the interface does not exist on this system, so we clear
* the scope information completely */
scope_id_set = false;
scope_ifname_set = false;
scope_id = 0;
}
} catch (SocketException e) {}
......@@ -784,8 +798,10 @@ class Inet6Address extends InetAddress {
private synchronized void writeObject(java.io.ObjectOutputStream s)
throws IOException
{
if (scope_ifname != null)
if (scope_ifname != null) {
ifname = scope_ifname.getName();
scope_ifname_set = true;
}
s.defaultWriteObject();
}
}
......@@ -44,13 +44,16 @@ import java.util.logging.Logger;
*
* <P>When a Driver class is loaded, it should create an instance of
* itself and register it with the DriverManager. This means that a
* user can load and register a driver by calling
* <pre>
* <code>Class.forName("foo.bah.Driver")</code>
* </pre>
*
* user can load and register a driver by calling:
* <p>
* {@code Class.forName("foo.bah.Driver")}
* <p>
* A JDBC driver may create a {@linkplain DriverAction} implementation in order
* to receive notifications when {@linkplain DriverManager#deregisterDriver} has
* been called.
* @see DriverManager
* @see Connection
* @see DriverAction
*/
public interface Driver {
......
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.sql;
/**
* An interface that must be implemented when a {@linkplain Driver} wants to be
* notified by {@code DriverManager}.
*<P>
* A {@code DriverAction} implementation is not intended to be used
* directly by applications. A JDBC Driver may choose
* to create its {@code DriverAction} implementation in a private class
* to avoid it being called directly.
* <o>
* The JDBC driver's static initialization block must call
* {@linkplain DriverManager#registerDriver(java.sql.Driver, java.sql.DriverAction) } in order
* to inform {@code DriverManager} which {@code DriverAction} implementation to
* call when the JDBC driver is de-registered.
* @since 1.8
*/
public interface DriverAction {
/**
* Method called by
* {@linkplain DriverManager#deregisterDriver(Driver) }
* to notify the JDBC driver that it was de-registered.
* <p>
* The {@code deregister} method is intended only to be used by JDBC Drivers
* and not by applications. JDBC drivers are recommended to not implement
* {@code DriverAction} in a public class. If there are active
* connections to the database at the time that the {@code deregister}
* method is called, it is implementation specific as to whether the
* connections are closed or allowed to continue. Once this method is
* called, it is implementation specific as to whether the driver may
* limit the ability to create new connections to the database, invoke
* other {@code Driver} methods or throw a {@code SQLException}.
* Consult your JDBC driver's documentation for additional information
* on its behavior.
* @see DriverManager#registerDriver(java.sql.Driver, java.sql.DriverAction)
* @see DriverManager#deregisterDriver(Driver)
* @since 1.8
*/
void deregister();
}
......@@ -110,6 +110,14 @@ public class DriverManager {
final static SQLPermission SET_LOG_PERMISSION =
new SQLPermission("setLog");
/**
* The {@code SQLPermission} constant that allows the
* un-register a registered JDBC driver.
* @since 1.8
*/
final static SQLPermission DEREGISTER_DRIVER_PERMISSION =
new SQLPermission("deregisterDriver");
//--------------------------JDBC 2.0-----------------------------
/**
......@@ -309,21 +317,42 @@ public class DriverManager {
/**
* Registers the given driver with the <code>DriverManager</code>.
* Registers the given driver with the {@code DriverManager}.
* A newly-loaded driver class should call
* the method <code>registerDriver</code> to make itself
* known to the <code>DriverManager</code>.
* the method {@code registerDriver} to make itself
* known to the {@code DriverManager}. If the driver had previously been
* registered, no action is taken.
*
* @param driver the new JDBC Driver that is to be registered with the
* <code>DriverManager</code>
* {@code DriverManager}
* @exception SQLException if a database access error occurs
*/
public static synchronized void registerDriver(java.sql.Driver driver)
throws SQLException {
registerDriver(driver, null);
}
/**
* Registers the given driver with the {@code DriverManager}.
* A newly-loaded driver class should call
* the method {@code registerDriver} to make itself
* known to the {@code DriverManager}. If the driver had previously been
* registered, no action is taken.
*
* @param driver the new JDBC Driver that is to be registered with the
* {@code DriverManager}
* @param da the {@code DriverAction} implementation to be used when
* {@code DriverManager#deregisterDriver} is called
* @exception SQLException if a database access error occurs
*/
public static synchronized void registerDriver(java.sql.Driver driver,
DriverAction da)
throws SQLException {
/* Register the driver if it has not already been added to our list */
if(driver != null) {
registeredDrivers.addIfAbsent(new DriverInfo(driver));
registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
} else {
// This is for compatibility with the original DriverManager
throw new NullPointerException();
......@@ -334,11 +363,29 @@ public class DriverManager {
}
/**
* Drops a driver from the <code>DriverManager</code>'s list.
* Applets can only deregister drivers from their own classloaders.
* Removes the specified driver from the {@code DriverManager}'s list of
* registered drivers.
* <p>
* If a {@code null} value is specified for the driver to be removed, then no
* action is taken.
* <p>
* If a security manager exists and its {@code checkPermission} denies
* permission, then a {@code SecurityException} will be thrown.
* <p>
* If the specified driver is not found in the list of registered drivers,
* then no action is taken. If the driver was found, it will be removed
* from the list of registered drivers.
* <p>
* If a {@code DriverAction} instance was specified when the JDBC driver was
* registered, its deregister method will be called
* prior to the driver being removed from the list of registered drivers.
*
* @param driver the JDBC Driver to drop
* @param driver the JDBC Driver to remove
* @exception SQLException if a database access error occurs
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method denies permission to deregister a driver.
*
* @see SecurityManager#checkPermission
*/
@CallerSensitive
public static synchronized void deregisterDriver(Driver driver)
......@@ -347,11 +394,22 @@ public class DriverManager {
return;
}
SecurityManager sec = System.getSecurityManager();
if (sec != null) {
sec.checkPermission(DEREGISTER_DRIVER_PERMISSION);
}
println("DriverManager.deregisterDriver: " + driver);
DriverInfo aDriver = new DriverInfo(driver);
DriverInfo aDriver = new DriverInfo(driver, null);
if(registeredDrivers.contains(aDriver)) {
if (isDriverAllowed(driver, Reflection.getCallerClass())) {
DriverInfo di = registeredDrivers.get(registeredDrivers.indexOf(aDriver));
// If a DriverAction was specified, Call it to notify the
// driver that it has been deregistered
if(di.action() != null) {
di.action().deregister();
}
registeredDrivers.remove(aDriver);
} else {
// If the caller does not have permission to load the driver then
......@@ -639,8 +697,10 @@ public class DriverManager {
class DriverInfo {
final Driver driver;
DriverInfo(Driver driver) {
DriverAction da;
DriverInfo(Driver driver, DriverAction action) {
this.driver = driver;
da = action;
}
@Override
......@@ -658,4 +718,8 @@ class DriverInfo {
public String toString() {
return ("driver[className=" + driver + "]");
}
DriverAction action() {
return da;
}
}
/*
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -30,8 +30,9 @@ import java.security.*;
/**
* The permission for which the <code>SecurityManager</code> will check
* when code that is running in an applet, or an application with a
* when code that is running an application with a
* <code>SecurityManager</code> enabled, calls the
* {@code DriverManager.deregisterDriver} method,
* <code>DriverManager.setLogWriter</code> method,
* <code>DriverManager.setLogStream</code> (deprecated) method,
* {@code SyncFactory.setJNDIContext} method,
......@@ -95,14 +96,16 @@ import java.security.*;
* <code>Connection</code> or
* objects created from the <code>Connection</code>
* will wait for the database to reply to any one request.</td>
* <tr>
* <td>deregisterDriver</td>
* <td>Allows the invocation of the {@code DriverManager}
* method {@code deregisterDriver}</td>
* <td>Permits an application to remove a JDBC driver from the list of
* registered Drivers and release its resources.</td>
* </tr>
* </tr>
* </table>
*<p>
* The person running an applet decides what permissions to allow
* and will run the <code>Policy Tool</code> to create an
* <code>SQLPermission</code> in a policy file. A programmer does
* not use a constructor directly to create an instance of <code>SQLPermission</code>
* but rather uses a tool.
* @since 1.3
* @see java.security.BasicPermission
* @see java.security.Permission
......
此差异已折叠。
......@@ -24,15 +24,19 @@
*/
package java.util.stream;
import java.util.Arrays;
import java.util.DoubleSummaryStatistics;
import java.util.Objects;
import java.util.OptionalDouble;
import java.util.PrimitiveIterator;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.BiConsumer;
import java.util.function.DoubleBinaryOperator;
import java.util.function.DoubleConsumer;
import java.util.function.DoubleFunction;
import java.util.function.DoublePredicate;
import java.util.function.DoubleSupplier;
import java.util.function.DoubleToIntFunction;
import java.util.function.DoubleToLongFunction;
import java.util.function.DoubleUnaryOperator;
......@@ -649,4 +653,175 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
@Override
Spliterator.OfDouble spliterator();
// Static factories
/**
* Returns a builder for a {@code DoubleStream}.
*
* @return a stream builder
*/
public static StreamBuilder.OfDouble builder() {
return new Streams.DoubleStreamBuilderImpl();
}
/**
* Returns an empty sequential {@code DoubleStream}.
*
* @return an empty sequential stream
*/
public static DoubleStream empty() {
return StreamSupport.doubleStream(Spliterators.emptyDoubleSpliterator());
}
/**
* Returns a sequential {@code DoubleStream} containing a single element.
*
* @param t the single element
* @return a singleton sequential stream
*/
public static DoubleStream of(double t) {
return StreamSupport.doubleStream(new Streams.DoubleStreamBuilderImpl(t));
}
/**
* Returns a sequential stream whose elements are the specified values.
*
* @param values the elements of the new stream
* @return the new stream
*/
public static DoubleStream of(double... values) {
return Arrays.stream(values);
}
/**
* Returns an infinite sequential {@code DoubleStream} produced by iterative
* application of a function {@code f} to an initial element {@code seed},
* producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
* {@code f(f(seed))}, etc.
*
* <p>The first element (position {@code 0}) in the {@code DoubleStream}
* will be the provided {@code seed}. For {@code n > 0}, the element at
* position {@code n}, will be the result of applying the function {@code f}
* to the element at position {@code n - 1}.
*
* @param seed the initial element
* @param f a function to be applied to to the previous element to produce
* a new element
* @return a new sequential {@code DoubleStream}
*/
public static DoubleStream iterate(final double seed, final DoubleUnaryOperator f) {
Objects.requireNonNull(f);
final PrimitiveIterator.OfDouble iterator = new PrimitiveIterator.OfDouble() {
double t = seed;
@Override
public boolean hasNext() {
return true;
}
@Override
public double nextDouble() {
double v = t;
t = f.applyAsDouble(t);
return v;
}
};
return StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(
iterator,
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL));
}
/**
* Returns a sequential {@code DoubleStream} where each element is
* generated by an {@code DoubleSupplier}. This is suitable for generating
* constant streams, streams of random elements, etc.
*
* @param s the {@code DoubleSupplier} for generated elements
* @return a new sequential {@code DoubleStream}
*/
public static DoubleStream generate(DoubleSupplier s) {
Objects.requireNonNull(s);
return StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(
new PrimitiveIterator.OfDouble() {
@Override
public boolean hasNext() { return true; }
@Override
public double nextDouble() { return s.getAsDouble(); }
},
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL));
}
/**
* Returns a sequential {@code DoubleStream} from {@code startInclusive} (inclusive)
* to {@code endExclusive} (exclusive) by an incremental step of 1.0.
*
* @implSpec
* The implementation behaves as if:
* <pre>{@code
* doubleRange(startInclusive, endExclusive, 1.0);
* }</pre>
*
* @param startInclusive the (inclusive) initial value
* @param endExclusive the exclusive upper bound
* @return a sequential {@code DoubleStream} for the range of {@code double}
* elements
*/
public static DoubleStream range(double startInclusive, double endExclusive) {
return range(startInclusive, endExclusive, 1.0);
}
/**
* Returns a sequential {@code DoubleStream} from {@code startInclusive}
* (inclusive) to {@code endExclusive} (exclusive) by {@code step}. If
* {@code startInclusive} is greater than or equal to {@code
* endExclusive}, an empty stream is returned.
*
* An equivalent sequence of increasing values can be produced
* sequentially using a {@code for} loop as follows:
* <pre>{@code
* long size = (long) Math.ceil((startInclusive - endExclusive) / step);
* long i = 0
* for (double v = startInclusive; i < size; i++, v = startInclusive + step * i) {
* ...
* }
* }</pre>
*
* @param startInclusive the (inclusive) initial value
* @param endExclusive the exclusive upper bound
* @param step the difference between consecutive values
* @return a sequential {@code DoubleStream} for tne range of {@code double}
* elements
* @throws IllegalArgumentException if {@code step} is less than or equal to
* 0. is {@code NaN}, or the count of elements in the range would be
* greater than {@code Long.MAX_VALUE}
*/
public static DoubleStream range(double startInclusive, double endExclusive, double step) {
// @@@ Need to check for ranges that may not produce distinct values
// such as when the step is very small
// Also clarify the size of the range which may produce more or less
// than expected
if (step <= 0 || Double.isNaN(step)) {
throw new IllegalArgumentException(String.format("Illegal step: %f", step));
} else {
double range = endExclusive - startInclusive;
if (range <= 0) {
return empty();
}
double size = Math.ceil((endExclusive - startInclusive) / step);
if (Double.isNaN(size)) {
throw new IllegalArgumentException(
String.format("Illegal range: %f size is NaN", size));
} else if (size > Long.MAX_VALUE) {
throw new IllegalArgumentException(
String.format("Illegal range: size %f > Long.MAX_VALUE", size));
} else {
return StreamSupport.doubleStream(
new Streams.RangeDoubleSpliterator(
startInclusive, endExclusive, step, 0, (long) size));
}
}
}
}
......@@ -24,17 +24,21 @@
*/
package java.util.stream;
import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.Objects;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.PrimitiveIterator;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.IntBinaryOperator;
import java.util.function.IntConsumer;
import java.util.function.IntFunction;
import java.util.function.IntPredicate;
import java.util.function.IntSupplier;
import java.util.function.IntToDoubleFunction;
import java.util.function.IntToLongFunction;
import java.util.function.IntUnaryOperator;
......@@ -652,4 +656,153 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
@Override
Spliterator.OfInt spliterator();
// Static factories
/**
* Returns a builder for an {@code IntStream}.
*
* @return a stream builder
*/
public static StreamBuilder.OfInt builder() {
return new Streams.IntStreamBuilderImpl();
}
/**
* Returns an empty sequential {@code IntStream}.
*
* @return an empty sequential stream
*/
public static IntStream empty() {
return StreamSupport.intStream(Spliterators.emptyIntSpliterator());
}
/**
* Returns a sequential {@code IntStream} containing a single element.
*
* @param t the single element
* @return a singleton sequential stream
*/
public static IntStream of(int t) {
return StreamSupport.intStream(new Streams.IntStreamBuilderImpl(t));
}
/**
* Returns a sequential stream whose elements are the specified values.
*
* @param values the elements of the new stream
* @return the new stream
*/
public static IntStream of(int... values) {
return Arrays.stream(values);
}
/**
* Returns an infinite sequential {@code IntStream} produced by iterative
* application of a function {@code f} to an initial element {@code seed},
* producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
* {@code f(f(seed))}, etc.
*
* <p>The first element (position {@code 0}) in the {@code IntStream} will be
* the provided {@code seed}. For {@code n > 0}, the element at position
* {@code n}, will be the result of applying the function {@code f} to the
* element at position {@code n - 1}.
*
* @param seed the initial element
* @param f a function to be applied to to the previous element to produce
* a new element
* @return A new sequential {@code IntStream}
*/
public static IntStream iterate(final int seed, final IntUnaryOperator f) {
Objects.requireNonNull(f);
final PrimitiveIterator.OfInt iterator = new PrimitiveIterator.OfInt() {
int t = seed;
@Override
public boolean hasNext() {
return true;
}
@Override
public int nextInt() {
int v = t;
t = f.applyAsInt(t);
return v;
}
};
return StreamSupport.intStream(Spliterators.spliteratorUnknownSize(
iterator,
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL));
}
/**
* Returns a sequential {@code IntStream} where each element is
* generated by an {@code IntSupplier}. This is suitable for generating
* constant streams, streams of random elements, etc.
*
* @param s the {@code IntSupplier} for generated elements
* @return a new sequential {@code IntStream}
*/
public static IntStream generate(IntSupplier s) {
Objects.requireNonNull(s);
return StreamSupport.intStream(Spliterators.spliteratorUnknownSize(
new PrimitiveIterator.OfInt() {
@Override
public boolean hasNext() { return true; }
@Override
public int nextInt() { return s.getAsInt(); }
},
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL));
}
/**
* Returns a sequential {@code IntStream} from {@code startInclusive}
* (inclusive) to {@code endExclusive} (exclusive) by an incremental step of
* 1.
*
* @implSpec
* The implementation behaves as if:
* <pre>{@code
* intRange(startInclusive, endExclusive, 1);
* }</pre>
*
* @param startInclusive the (inclusive) initial value
* @param endExclusive the exclusive upper bound
* @return a sequential {@code IntStream} for the range of {@code int}
* elements
*/
public static IntStream range(int startInclusive, int endExclusive) {
return range(startInclusive, endExclusive, 1);
}
/**
* Returns a sequential {@code IntStream} from {@code startInclusive}
* (inclusive) to {@code endExclusive} (exclusive) by a positive {@code
* step}. If {@code startInclusive} is greater than or equal to {@code
* endExclusive}, an empty stream is returned.
*
* <p>An equivalent sequence of increasing values can be produced
* sequentially using a {@code for} loop as follows:
* <pre>{@code
* for (int i = startInclusive; i < endExclusive ; i += step) { ... }
* }</pre>
*
* @param startInclusive the (inclusive) initial value
* @param endExclusive the exclusive upper bound
* @param step the positive difference between consecutive values
* @return a sequential {@code IntStream} for the range of {@code int}
* elements
* @throws IllegalArgumentException if {@code step} is less than or equal to
* 0
*/
public static IntStream range(int startInclusive, int endExclusive, int step) {
if (step <= 0) {
throw new IllegalArgumentException(String.format("Illegal step: %d", step));
} else if (startInclusive >= endExclusive) {
return empty();
} else {
return StreamSupport.intStream(new Streams.RangeIntSpliterator(startInclusive, endExclusive, step));
}
}
}
......@@ -24,17 +24,21 @@
*/
package java.util.stream;
import java.util.Arrays;
import java.util.LongSummaryStatistics;
import java.util.Objects;
import java.util.OptionalDouble;
import java.util.OptionalLong;
import java.util.PrimitiveIterator;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.LongBinaryOperator;
import java.util.function.LongConsumer;
import java.util.function.LongFunction;
import java.util.function.LongPredicate;
import java.util.function.LongSupplier;
import java.util.function.LongToDoubleFunction;
import java.util.function.LongToIntFunction;
import java.util.function.LongUnaryOperator;
......@@ -643,4 +647,153 @@ public interface LongStream extends BaseStream<Long, LongStream> {
@Override
Spliterator.OfLong spliterator();
// Static factories
/**
* Returns a builder for a {@code LongStream}.
*
* @return a stream builder
*/
public static StreamBuilder.OfLong builder() {
return new Streams.LongStreamBuilderImpl();
}
/**
* Returns an empty sequential {@code LongStream}.
*
* @return an empty sequential stream
*/
public static LongStream empty() {
return StreamSupport.longStream(Spliterators.emptyLongSpliterator());
}
/**
* Returns a sequential {@code LongStream} containing a single element.
*
* @param t the single element
* @return a singleton sequential stream
*/
public static LongStream of(long t) {
return StreamSupport.longStream(new Streams.LongStreamBuilderImpl(t));
}
/**
* Returns a sequential stream whose elements are the specified values.
*
* @param values the elements of the new stream
* @return the new stream
*/
public static LongStream of(long... values) {
return Arrays.stream(values);
}
/**
* Returns an infinite sequential {@code LongStream} produced by iterative
* application of a function {@code f} to an initial element {@code seed},
* producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
* {@code f(f(seed))}, etc.
*
* <p>The first element (position {@code 0}) in the {@code LongStream} will
* be the provided {@code seed}. For {@code n > 0}, the element at position
* {@code n}, will be the result of applying the function {@code f} to the
* element at position {@code n - 1}.
*
* @param seed the initial element
* @param f a function to be applied to to the previous element to produce
* a new element
* @return a new sequential {@code LongStream}
*/
public static LongStream iterate(final long seed, final LongUnaryOperator f) {
Objects.requireNonNull(f);
final PrimitiveIterator.OfLong iterator = new PrimitiveIterator.OfLong() {
long t = seed;
@Override
public boolean hasNext() {
return true;
}
@Override
public long nextLong() {
long v = t;
t = f.applyAsLong(t);
return v;
}
};
return StreamSupport.longStream(Spliterators.spliteratorUnknownSize(
iterator,
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL));
}
/**
* Returns a sequential {@code LongStream} where each element is generated
* by a {@code LongSupplier}. This is suitable for generating constant
* streams, streams of random elements, etc.
*
* @param s the {@code LongSupplier} for generated elements
* @return a new sequential {@code LongStream}
*/
public static LongStream generate(LongSupplier s) {
Objects.requireNonNull(s);
return StreamSupport.longStream(Spliterators.spliteratorUnknownSize(
new PrimitiveIterator.OfLong() {
@Override
public boolean hasNext() { return true; }
@Override
public long nextLong() { return s.getAsLong(); }
},
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL));
}
/**
* Returns a sequential {@code LongStream} from {@code startInclusive}
* (inclusive) to {@code endExclusive} (exclusive) by an incremental step of
* 1.
*
* @implSpec
* The implementation behaves as if:
* <pre>{@code
* longRange(startInclusive, endExclusive, 1);
* }</pre>
*
* @param startInclusive the (inclusive) initial value
* @param endExclusive the exclusive upper bound
* @return a sequential {@code LongStream} for the range of {@code long}
* elements
*/
public static LongStream range(long startInclusive, final long endExclusive) {
return range(startInclusive, endExclusive, 1);
}
/**
* Returns a sequential {@code LongStream} from {@code startInclusive}
* (inclusive) to {@code endExclusive} (exclusive) by {@code step}. If
* {@code startInclusive} is greater than or equal to {@code
* endExclusive}, an empty stream is returned.
*
* <p>An equivalent sequence of increasing values can be produced
* sequentially using a {@code for} loop as follows:
* <pre>{@code
* for (long i = startInclusive; i < endExclusive ; i += step) { ... }
* }</pre>
*
* @param startInclusive the (inclusive) initial value
* @param endExclusive the exclusive upper bound
* @param step the difference between consecutive values
* @return a sequential {@code LongStream} for the range of {@code long}
* elements
* @throws IllegalArgumentException if {@code step} is less than or equal to
* 0
*/
public static LongStream range(long startInclusive, final long endExclusive, final long step) {
if (step <= 0) {
throw new IllegalArgumentException(String.format("Illegal step: %d", step));
} else if (startInclusive >= endExclusive) {
return empty();
} else {
return StreamSupport.longStream(new Streams.RangeLongSpliterator(startInclusive, endExclusive, step));
}
}
}
......@@ -24,8 +24,13 @@
*/
package java.util.stream;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Objects;
import java.util.Optional;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
......@@ -37,6 +42,7 @@ import java.util.function.Supplier;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.UnaryOperator;
// @@@ Specification to-do list @@@
// - Describe the difference between sequential and parallel streams
......@@ -779,4 +785,109 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
* @see #findFirst()
*/
Optional<T> findAny();
// Static factories
/**
* Returns a builder for a {@code Stream}.
*
* @param <T> type of elements
* @return a stream builder
*/
public static<T> StreamBuilder<T> builder() {
return new Streams.StreamBuilderImpl<>();
}
/**
* Returns an empty sequential {@code Stream}.
*
* @param <T> the type of stream elements
* @return an empty sequential stream
*/
public static<T> Stream<T> empty() {
return StreamSupport.stream(Spliterators.<T>emptySpliterator());
}
/**
* Returns a sequential {@code Stream} containing a single element.
*
* @param t the single element
* @param <T> the type of stream elements
* @return a singleton sequential stream
*/
public static<T> Stream<T> of(T t) {
return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t));
}
/**
* Returns a sequential stream whose elements are the specified values.
*
* @param <T> the type of stream elements
* @param values the elements of the new stream
* @return the new stream
*/
@SafeVarargs
public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
/**
* Returns an infinite sequential {@code Stream} produced by iterative
* application of a function {@code f} to an initial element {@code seed},
* producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
* {@code f(f(seed))}, etc.
*
* <p>The first element (position {@code 0}) in the {@code Stream} will be
* the provided {@code seed}. For {@code n > 0}, the element at position
* {@code n}, will be the result of applying the function {@code f} to the
* element at position {@code n - 1}.
*
* @param <T> the type of stream elements
* @param seed the initial element
* @param f a function to be applied to to the previous element to produce
* a new element
* @return a new sequential {@code Stream}
*/
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {
Objects.requireNonNull(f);
final Iterator<T> iterator = new Iterator<T>() {
@SuppressWarnings("unchecked")
T t = (T) Streams.NONE;
@Override
public boolean hasNext() {
return true;
}
@Override
public T next() {
return t = (t == Streams.NONE) ? seed : f.apply(t);
}
};
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
iterator,
Spliterator.ORDERED | Spliterator.IMMUTABLE));
}
/**
* Returns a sequential {@code Stream} where each element is
* generated by a {@code Supplier}. This is suitable for generating
* constant streams, streams of random elements, etc.
*
* @param <T> the type of stream elements
* @param s the {@code Supplier} of generated elements
* @return a new sequential {@code Stream}
*/
public static<T> Stream<T> generate(Supplier<T> s) {
Objects.requireNonNull(s);
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
new Iterator<T>() {
@Override
public boolean hasNext() { return true; }
@Override
public T next() { return s.get(); }
},
Spliterator.ORDERED | Spliterator.IMMUTABLE));
}
}
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.util.stream;
import java.util.function.Consumer;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
/**
* A mutable builder for a {@code Stream}. This allows the creation of a
* {@code Stream} by generating elements individually and adding them to the
* {@code StreamBuilder} (without the copying overhead that comes from using
* an {@code ArrayList} as a temporary buffer.)
*
* <p>A {@code StreamBuilder} has a lifecycle, where it starts in a building
* phase, during which elements can be added, and then transitions to a built
* phase, after which elements may not be added. The built phase begins
* when the {@link #build()}} method is called, which creates an ordered
* {@code Stream} whose elements are the elements that were added to the stream
* builder, in the order they were added.
*
* <p>Primitive specializations of {@code StreamBuilder} are provided
* for {@link OfInt int}, {@link OfLong long}, and {@link OfDouble double}
* values.
*
* @param <T> the type of stream elements
* @see Stream#builder()
* @since 1.8
*/
public interface StreamBuilder<T> extends Consumer<T> {
/**
* Adds an element to the stream being built.
*
* @throws IllegalStateException if the builder has already transitioned to
* the built state
*/
@Override
void accept(T t);
/**
* Adds an element to the stream being built.
*
* @implSpec
* The default implementation behaves as if:
* <pre>{@code
* accept(t)
* return this;
* }</pre>
*
* @param t the element to add
* @return {@code this} builder
* @throws IllegalStateException if the builder has already transitioned to
* the built state
*/
default StreamBuilder<T> add(T t) {
accept(t);
return this;
}
/**
* Builds the stream, transitioning this builder to the built state.
* An {@code IllegalStateException} is thrown if there are further attempts
* to operate on the builder after it has entered the built state.
*
* @return the built stream
* @throws IllegalStateException if the builder has already transitioned to
* the built state
*/
Stream<T> build();
/**
* A mutable builder for an {@code IntStream}.
*
* <p>A stream builder has a lifecycle, where it starts in a building
* phase, during which elements can be added, and then transitions to a
* built phase, after which elements may not be added. The built phase
* begins when the {@link #build()}} method is called, which creates an
* ordered stream whose elements are the elements that were added to the
* stream builder, in the order they were added.
*
* @see IntStream#builder()
* @since 1.8
*/
interface OfInt extends IntConsumer {
/**
* Adds an element to the stream being built.
*
* @throws IllegalStateException if the builder has already transitioned
* to the built state
*/
@Override
void accept(int t);
/**
* Adds an element to the stream being built.
*
* @implSpec
* The default implementation behaves as if:
* <pre>{@code
* accept(t)
* return this;
* }</pre>
*
* @param t the element to add
* @return {@code this} builder
* @throws IllegalStateException if the builder has already transitioned
* to the built state
*/
default StreamBuilder.OfInt add(int t) {
accept(t);
return this;
}
/**
* Builds the stream, transitioning this builder to the built state.
* An {@code IllegalStateException} is thrown if there are further
* attempts to operate on the builder after it has entered the built
* state.
*
* @return the built stream
* @throws IllegalStateException if the builder has already transitioned to
* the built state
*/
IntStream build();
}
/**
* A mutable builder for a {@code LongStream}.
*
* <p>A stream builder has a lifecycle, where it starts in a building
* phase, during which elements can be added, and then transitions to a
* built phase, after which elements may not be added. The built phase
* begins when the {@link #build()}} method is called, which creates an
* ordered stream whose elements are the elements that were added to the
* stream builder, in the order they were added.
*
* @see LongStream#builder()
* @since 1.8
*/
interface OfLong extends LongConsumer {
/**
* Adds an element to the stream being built.
*
* @throws IllegalStateException if the builder has already transitioned
* to the built state
*/
@Override
void accept(long t);
/**
* Adds an element to the stream being built.
*
* @implSpec
* The default implementation behaves as if:
* <pre>{@code
* accept(t)
* return this;
* }</pre>
*
* @param t the element to add
* @return {@code this} builder
* @throws IllegalStateException if the builder has already transitioned
* to the built state
*/
default StreamBuilder.OfLong add(long t) {
accept(t);
return this;
}
/**
* Builds the stream, transitioning this builder to the built state.
* An {@code IllegalStateException} is thrown if there are further
* attempts to operate on the builder after it has entered the built
* state.
*
* @return the built stream
* @throws IllegalStateException if the builder has already transitioned
* to the built state
*/
LongStream build();
}
/**
* A mutable builder for a {@code DoubleStream}.
*
* @see LongStream#builder()
* @since 1.8
*/
interface OfDouble extends DoubleConsumer {
/**
* Adds an element to the stream being built.
*
* <p>A stream builder has a lifecycle, where it starts in a building
* phase, during which elements can be added, and then transitions to a
* built phase, after which elements may not be added. The built phase
* begins when the {@link #build()}} method is called, which creates an
* ordered stream whose elements are the elements that were added to the
* stream builder, in the order they were added.
*
* @throws IllegalStateException if the builder has already transitioned
* to the built state
*/
@Override
void accept(double t);
/**
* Adds an element to the stream being built.
*
* @implSpec
* The default implementation behaves as if:
* <pre>{@code
* accept(t)
* return this;
* }</pre>
*
* @param t the element to add
* @return {@code this} builder
* @throws IllegalStateException if the builder has already transitioned
* to the built state
*/
default StreamBuilder.OfDouble add(double t) {
accept(t);
return this;
}
/**
* Builds the stream, transitioning this builder to the built state.
* An {@code IllegalStateException} is thrown if there are further
* attempts to operate on the builder after it has entered the built
* state.
*
* @return the built stream
* @throws IllegalStateException if the builder has already transitioned
* to the built state
*/
DoubleStream build();
}
}
此差异已折叠。
......@@ -128,19 +128,13 @@ public class AgentConfigurationError extends Error {
public AgentConfigurationError(String error, String... params) {
super();
this.error = error;
this.params = new String[params.length];
for (int i = 0; i < params.length; i++) {
this.params[i] = params[i];
}
this.params = params.clone();
}
public AgentConfigurationError(String error, Throwable cause, String... params) {
super(cause);
this.error = error;
this.params = new String[params.length];
for (int i = 0; i < params.length; i++) {
this.params[i] = params[i];
}
this.params = params.clone();
}
public String getError() {
......@@ -148,7 +142,7 @@ public class AgentConfigurationError extends Error {
}
public String[] getParams() {
return params;
return params.clone();
}
private static final long serialVersionUID = 1211605593516195475L;
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册