--- /dev/null 2014-02-02 21:38:41.000000000 +0800 +++ new/src/share/sample/stream/Aggregation.java 2014-02-02 21:38:40.000000000 +0800 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream; + +import stream.data.Customer; +import stream.data.Order; +import java.util.Map; +import java.util.function.Predicate; +import static java.util.stream.Collectors.*; + +/** + * A demo shows how does Stream's aggregation works. Demo shows 1. Sum operation + * on stream interface 2. Use Stream's count operation as Function output + * + * @author tyan + */ +public class Aggregation extends DemoHelper { + + /** + * Calculate total product's price. + * + * @return total product's price + */ + public static double totalProductPrice() { + return products.stream(). + //map every product to its price + mapToDouble(p -> p.getUnitPrice() * p.getUnitsInStock()). + //caculation total price + sum(); + } + + /** + * Get every customer's order count that order meets the predicate

+ * It's possible some customers who don't have any order in given period. + * + * @param predicate a order predicate + * @return map for customer's name and its number of order meets the predicate. + */ + public static Map customerAndOrderCount( + Predicate predicate) { + return customers.stream(). + //convert customers into a map that key is customer's name and + //value is number of orders which filter by predicate + collect(toMap( + Customer::getCompanyName, c + -> c.getOrders().stream(). + //filter orders' stream by given predicate + filter(predicate). + //get number of order which filter by given predicate + count() + )); + } +} --- /dev/null 2014-02-02 21:38:42.000000000 +0800 +++ new/src/share/sample/stream/Conditional.java 2014-02-02 21:38:41.000000000 +0800 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream; + +import stream.data.Customer; +import stream.data.Product; +import stream.data.Order; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Predicate; +import static java.util.stream.Collectors.*; + +/** + * This class demos conditional filter usage for collection interface. Which + * includes + * 1. Simple filter on collection + * 2. Combination of predicates filter on collection + * 3. Grouping collection, also attach filter at the same time + * @author tyan + */ +public class Conditional extends DemoHelper { + /** + * Filter products that are out of stock. This is demo for simple filter for + * one predicate.

+ * + * @return name list of product that is out of stock + */ + public static List outOfStock() { + return products.stream(). + //filter out of stock product + filter(p -> p.getUnitsInStock() == 0). + //map product to name + map(Product::getProductName). + //get product name list + collect(toList()); + } + + /* + * Filter products that are in stock. This demo shows case that uses a given + * predicate concatenate another predicate. + * + * @predicate a predicate that filter on products + * @return product lists which fits predicate and in-sotck both + */ + public static List inStockWithPreicate(Predicate predicate) { + //Oher way to do this is filter(isInStock).filter(predicate) + return products.stream(). + //filter product with predicate and in-stcok + filter(predicate.and(p -> p.getUnitsInStock() > 0)) + //map product to name + .map(Product::getProductName). + //get product name lis + collect(toList()); + } + /* + * Filter customers in state and their orders, this is a demo for filter + * predicate join with other data source + * + * @region region be used to look for customer + * @return map from customer to its order list in given state + */ + + public static Map> customerMapOrdersFromRegion( + String region) { + return customers.stream() + //filter customer in given region + .filter(c -> region.equals(c.getRegion())) + //convert customers into a map, which key is customer, value is + //customer's list of orders + .collect( + //Accumulate customers into a Map, key is customer and value + //is cusromer's orders + toMap(Function.identity(), Customer::getOrders)); + } +} --- /dev/null 2014-02-02 21:38:43.000000000 +0800 +++ new/src/share/sample/stream/Conversion.java 2014-02-02 21:38:42.000000000 +0800 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream; + +import stream.data.Customer; +import stream.data.Product; +import java.util.Collection; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import static java.util.stream.Collectors.*; +import static java.util.Comparator.*; +import java.util.stream.Stream; + +/** + * This program is demo how to use the conversion operator like toArray, + * collect(Collectors.toList()), collect(Collectors.toCollection()) + * + * @author tyan + */ +public class Conversion extends DemoHelper { + + /** + * Convert products which is most expensive in the same category into an + * array + * + * @param func Function convert Product to T, T could be any type that + * Product can convert, like price + * @return product array which is in every category, value of T is highest + */ + + public static > Product[] mostTProductsByCategory( + Function func) { + //Grouping product by category, only select maximal product by comparing + //on func + Map> categoryToProduct = products.stream(). + collect(groupingBy(Product::getCategory, + maxBy(comparing(func)))); + + return categoryToProduct.values().stream(). + //get Product object + map(Optional::get). + //converting stream to an array + toArray(Product[]::new); + } + + /** + * Convert customers to a distinct countries list + * + * @param ordered true keep original countries list order false not keep + * original countries list order + * @return a distinct ordered/unordered countries list for all of customers + * by given ordered flag + */ + public static Collection countries(boolean ordered) { + Stream countries = customers.stream().map(Customer::getCountry); + if (ordered) { + /** + * Use distinct() follow with collect(Collectors.toCollection) to + * get unique countries linked list. Note this way can generate + * target container + */ + return countries.distinct().collect(toList()); + } else { + /** + * Use collect(Collectors.toSet) to get unique countries list. Note + * the difference between this and first one is this way doesn't + * guarantee the order + */ + return countries.collect(toSet()); + } + } +} --- /dev/null 2014-02-02 21:38:43.000000000 +0800 +++ new/src/share/sample/stream/DemoHelper.java 2014-02-02 21:38:43.000000000 +0800 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream; + +import stream.data.Vendor; +import stream.data.Customer; +import stream.data.Product; +import stream.data.DataUtilities; +import java.util.List; + +/** + * This is a helper class which is a single point to provide data, every demo + * class should extends this class. + */ +public class DemoHelper { + + //Vendor list that can be used as a source to populated + protected final static List vendors + = DataUtilities.getUtilities().getVendorList(); + + //Customer list that can be used as a source to populated + protected final static List customers + = DataUtilities.getUtilities().getCustomerList(); + + //Product list that can be used as a source to populated + protected final static List products + = DataUtilities.getUtilities().getProductList(); +} --- /dev/null 2014-02-02 21:38:44.000000000 +0800 +++ new/src/share/sample/stream/Elements.java 2014-02-02 21:38:44.000000000 +0800 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream; + +import stream.data.Vendor; +import stream.data.Product; +import java.util.Map; +import java.util.Optional; +import java.util.function.BinaryOperator; +import static java.util.stream.Collectors.*; +import java.util.stream.Stream; + +/** + * This class demos find operation that attach to collection, findFirst returns + * first element in the stream, it's reasonable we can expect it's the first + * element in the collection if collection is ordered. On the contrary, findAny + * returns any element in the stream. + * + * @author tyan + */ +public class Elements extends DemoHelper { + + /** + * Find any vendor or first vendor in country, this demos how implement a + * simple find on a source with one condition + * + * @param findAny true perform findAny on stream false perform findFirst on + * stream + * @param country vendor's country + * @return any/first vendor in given country + */ + + public static Optional vendorsInCountry(boolean findAny, + String country) { + Stream s = vendors.stream(). + //filter vendor who is same sa given country + filter(vendor -> country. + equals(vendor.getCountry())); + + return findAny ? s.findAny() : s.findFirst(); + } + + /** + * Get mapping table between category to any/first in-stock product. + * + * @param findAny true perform findAny on stream false perform findFirst on + * stream + * @return a map mapping every category to any/first in-stock product + */ + public static Map inStockProductsByCategory( + boolean findAny) { + //A BinaryOperator only select first non-null element + BinaryOperator reduceToFirstMatch = (l, r) -> (l != null) + ? l : (r != null && r.getUnitsInStock() > 0) + ? r : null; + + //grouping products by category, pick first element in same category + return products.stream().collect( + groupingBy(Product::getCategory, + reducing(null, reduceToFirstMatch))); + } +} --- /dev/null 2014-02-02 21:38:45.000000000 +0800 +++ new/src/share/sample/stream/Grouping.java 2014-02-02 21:38:45.000000000 +0800 @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream; + +import stream.data.Customer; +import stream.data.Product; +import stream.data.Order; +import java.util.ArrayList; +import java.util.Comparator; +import static java.util.Comparator.*; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import static java.util.stream.Collectors.*; +import java.util.stream.Stream; + +/** + * This class demos shows usage of group Collector working with collect method. + * + * @author tyan + */ +public class Grouping extends DemoHelper { + + /** + * Group products by T + * + * @param byXXX a function which convert Product to T + * @return a map between T object to a product list, any product in this + * list using byXXX conversion is same to map's key + */ + + public static Map> groupProduct( + Function byXXX) { + return products.stream(). + //grouping product by given function + collect(groupingBy(byXXX)); + } + + /** + * Group orders by customer with using Collectors.groupingBy(Function, + * Collector) + * + * @return map customer to its order list + */ + public static Map> groupOrdersByCustomer() { + //a collector that generate a order list from a customer + Collector, List> collectOrder = Collector. + of(ArrayList::new, + (orders, customer) -> { + orders.addAll(customer.getOrders()); + }, + (left, right) -> { + left.addAll(right); + return left; + }); + return customers.stream(). + //convert customers to a Map which key is it name, value is its + //orders + collect(groupingBy(Customer::getCompanyName, + collectOrder)); + } + + /** + * Group products by categories, only select max/min value of product + * ordered by compFunc + * + * @param maxBy true select max value product false select min value product + * @param groupFunc function provides how to group product + * @param compFunc function provides how to sort product + * @return a map between a instance of S to instance of T + */ + public static > Map> + productMaxByTGroupByS(boolean maxBy, Function groupFunc, + Function compFunc) { + //Comparator of Product which will compare on T by given function + Comparator comp = comparing(compFunc); + //A collector that collet maximal or minimal element according to a + //given maxBy and Comparator + Collector> collector + = maxBy ? maxBy(comp) : minBy(comp); + return products.stream(). + //collect products into a Map, which key is S by function of + //groupFunc, value is max or min by given max and function of + //compFunc + collect(Collectors.groupingBy(groupFunc, collector)); + } + + /** + * Group products by R, this is demo for grouping by different element one + * by one. + * + * @param func1 function that convert Product to R + * @param func2 function that convert Product to T + * @return a map which groups products to R then T + */ + public static Map>> ordersByRThenT( + Function func1, Function func2) { + return customers.stream().collect( + streaming(customer -> customer.getOrders().stream(), + groupingBy(func1, groupingBy(func2)))); + } + + /** + * A downstream collector that streams elements to a further downstream + * collector. + * + * @param the type of the input elements + * @param the supplier type of the downstream collector + * @param the intermediate accumulation type of the downstream collector + * @param the result type of the downstream reduction + * @param mapper the classifier function mapping input elements to object of + * U + * @param downstream a collector implementing the downstream reduction + * @return a collector convert element to other object followed by an + * downstream a collector which performs the action + */ + public static + Collector streaming(Function> mapper, + Collector downstream) { + BiConsumer downstreamAccumulator = downstream.accumulator(); + return Collector.of(downstream.supplier(), + (r, t) -> mapper.apply(t).sequential().forEach( + u -> downstreamAccumulator.accept(r, u)), + downstream.combiner(), + downstream.finisher(), + downstream.characteristics().stream().toArray( + Collector.Characteristics[]::new)); + } + +} --- /dev/null 2014-02-02 21:38:46.000000000 +0800 +++ new/src/share/sample/stream/Selection.java 2014-02-02 21:38:46.000000000 +0800 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream; + +import stream.data.Customer; +import stream.data.Order; +import java.util.Map; +import java.util.function.Function; +import static java.util.stream.Collectors.toConcurrentMap; + +public class Selection extends DemoHelper { + + /** + * Mapping customer to its total order price, only customer whose total + * order price is bigger than bigValue will be put into the map + * + * @param bigValue customer's total price low limit + * @return a map which map customer to its order price + */ + public static Map bigOrderCustomers(double bigValue) { + Function orderTotal + = c -> c.getOrders().stream(). + //map order to order price + mapToDouble(Order::getTotal). + //calculate total price + sum(); + Map customersToBigOrder = customers.stream(). + //grouping customer to a Map which key is customer, value is + //total order price + collect(toConcurrentMap(Function.identity(), + orderTotal)); + customersToBigOrder.forEach((customer, totalAmount) -> { + //Remove all customer whose total order amount is not greater than + //bigValue + if (totalAmount <= bigValue) { + customersToBigOrder.remove(customer); + } + }); + return customersToBigOrder; + } +} --- /dev/null 2014-02-02 21:38:47.000000000 +0800 +++ new/src/share/sample/stream/Subset.java 2014-02-02 21:38:47.000000000 +0800 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream; + +import stream.data.Customer; +import stream.data.Order; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * A demo shows how does Stream's subset works. This demo provides two methods + * which is using substream method on Stream to get subset of the elements. Note + * we can use substream on sorted stream to get top number elements, but we + * can't guarantee the element order if stream is not sorted. + * + * @author hyan + */ +public class Subset extends DemoHelper { + + /** + * Returns a List that contains numbers order which customer is from state, + * also execute action on every returned order element. The number must be a + * non-negative digit. + *

+ * + * @param number integer how many orders are expected to be returned + * @param state state that customer of order belong to + * @return a list contains top number customers that sorted by comp + */ + public static List firstNOrdersFromState(int number, + String state) { + return customers.stream(). + //only take customers from a particular state + filter(c -> state.equals(c.getRegion())). + //get orders of those customers + flatMap(c -> c.getOrders().stream()). + //get first number of orders + limit(number). + //collect to a list + collect(Collectors.toList()); + } + + /** + * Returns a List that contains numbers customer sorted by comp, also + * execute action on every returned customer element. The number must be a + * non-negative digit. + *

+ * + * @param number integer how many customers are expected to be returned + * @param comp Comparator to compare customer + * @return a list contains top number customers that sorted by comp + */ + public static List topNCustomer(int number, + Comparator comp) { + //We keep result in topN, then we can test it + return customers.stream() +. //sort customers by comp + sorted(comp). + //get first number of orders + limit(number). + //collect to a list + collect(Collectors.toList()); + } +} --- /dev/null 2014-02-02 21:38:48.000000000 +0800 +++ new/src/share/sample/stream/Tabulate.java 2014-02-02 21:38:48.000000000 +0800 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream; + +import stream.data.Customer; +import stream.data.Vendor; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; +import static java.util.stream.Collectors.*; +import java.util.stream.Stream; + +/** + * A demo shows how does Stream's flatMap works. Demo shows tabulate stream + * element to single element stream or empty stream + * + * @author tyan + */ +public class Tabulate extends DemoHelper { + /** + * Join vendor and customer that in same country. note not all vendor + * has customer + * @return a list of customer-vendor pair which in same country + */ + public static Map> sameCountryCustomerAndVendors() { + Map> countryToVendors = vendors.stream(). + // group vendors by their country + collect(groupingBy(Vendor::getCountry)); + //Find customer in countryToVendors with key as customer's country + Function> vendorsInSameCustomerCountry + = customer-> countryToVendors.getOrDefault( + customer.getCountry(), new ArrayList<>()); + //Map customer to vendor who are same country as customer's + return customers.stream(). + filter(c -> countryToVendors.containsKey(c.getCountry())). + collect(toMap(Function.identity(), vendorsInSameCustomerCountry)); + } + + /** + * flatMap can generate empty stream, sometimes it's helpful for ruling + * out data + * @return a string set who is either customer and vendor both. + */ + public static Set bothCustomerAndVendor() { + Set vendorsName = vendors.stream(). + map(Vendor::getVendorName). + collect(toSet()); + return customers.stream(). + //map customer to its name + map(Customer::getCompanyName). + //query vendor set with customer's name, if exist, create + //a stream with single element customer name, if doesn't, create + //an empty stream + flatMap(c -> vendorsName.contains(c) + ? Stream.of(c) : Stream.empty()). + //convert all match name into a set + collect(Collectors.toSet()); + } +} --- /dev/null 2014-02-02 21:38:49.000000000 +0800 +++ new/src/share/sample/stream/data/Customer.java 2014-02-02 21:38:49.000000000 +0800 @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream.data; + +import java.util.ArrayList; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * Customer meta data class, one customer could have zero to multiple orders + * + * @author tyan + */ +public @XmlRootElement(name = "customer") +@XmlType(propOrder = {"customerID", "companyName", "address", "city", "region", + "postalcode", "country", "phone", "fax", "orders"}) +class Customer { + + private String customerID; + private String companyName; + private String address; + private String city; + private String region; + private String postalcode; + private String country; + private String phone; + private String fax; + + @XmlElementWrapper(name = "orders") + @XmlElement(name = "order") + private ArrayList orders; + + /** + * @return the customerID + */ + @XmlElement(name = "id") + public String getCustomerID() { + return customerID; + } + + /** + * @param customerID the customerID to set + */ + public void setCustomerID(String customerID) { + this.customerID = customerID; + } + + /** + * @return the companyName + */ + @XmlElement(name = "name") + public String getCompanyName() { + return companyName; + } + + /** + * @param companyName the companyName to set + */ + public void setCompanyName(String companyName) { + this.companyName = companyName; + } + + /** + * @return the address + */ + public String getAddress() { + return address; + } + + /** + * @param address the address to set + */ + public void setAddress(String address) { + this.address = address; + } + + /** + * @return the city + */ + public String getCity() { + return city; + } + + /** + * @param city the city to set + */ + public void setCity(String city) { + this.city = city; + } + + /** + * @return the region + */ + public String getRegion() { + return region; + } + + /** + * @param region the region to set + */ + public void setRegion(String region) { + this.region = region; + } + + /** + * @return the postalcode + */ + public String getPostalcode() { + return postalcode; + } + + /** + * @param postalcode the postalcode to set + */ + public void setPostalcode(String postalcode) { + this.postalcode = postalcode; + } + + /** + * @return the country + */ + public String getCountry() { + return country; + } + + /** + * @param country the country to set + */ + public void setCountry(String country) { + this.country = country; + } + + /** + * @return the phone + */ + public String getPhone() { + return phone; + } + + /** + * @param phone the phone to set + */ + public void setPhone(String phone) { + this.phone = phone; + } + + /** + * @return the fax + */ + public String getFax() { + return fax; + } + + /** + * @param fax the fax to set + */ + public void setFax(String fax) { + this.fax = fax; + } + + /** + * @return the orders + */ + public final ArrayList getOrders() { + return orders; + } +} --- /dev/null 2014-02-02 21:38:50.000000000 +0800 +++ new/src/share/sample/stream/data/DataUtilities.java 2014-02-02 21:38:50.000000000 +0800 @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream.data; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * DataUtilities is a singleton helper class that creates test data. This class + * uses jaxws API to read xml into java object, which includes 3 list of data 1. + * Customers 2. Products 3. Vendors Note in this demo here we don't use stream + * API to change data, if we use stream API to populate source data, we should + * be aware this is not free and not thread-safe. + */ +interface XMLList { + + public List getList(); +} + +/** + * class for PRODUCTS_XML's root + */ +@XmlRootElement(name = "products") +class Products implements XMLList { + + /** + * node products only contains product list + */ + @XmlElement(name = "product") + private ArrayList products; + + /** + * product list + */ + @Override + public List getList() { + return products; + } +} + +/** + * class for VENDORS_XML's root + */ +@XmlRootElement(name = "vendors") +class Vendors implements XMLList { + + /** + * node Vendors only contains vendor list + */ + + @Override + public List getList() { + return vendors; + } + + /** + * vendor list + */ + @XmlElement(name = "vendor") + private ArrayList vendors; +} + +/** + * class for CUSTOMERS_XML's root + */ +@XmlRootElement(name = "customers") +class Customers implements XMLList { + + /** + * node customers only contains customer list + */ + @Override + public List getList() { + return customers; + } + + /** + * customer list + */ + @XmlElement(name = "customer") + private ArrayList customers; +} + +public class DataUtilities { + + /** + * xml file name for Customers object + */ + + private final static String CUSTOMERS_XML = "Customers.xml"; + + /** + * xml file name for Products object + */ + private final static String PRODUCTS_XML = "Products.xml"; + + /** + * xml file name for Products object + */ + private final static String VENDORS_XML = "Vendors.xml"; + + /** + * Lazy initiate static inner class for + */ + private static class UtilitiesHolder { + + static DataUtilities instance = new DataUtilities(); + } + + /** + * private constructor is needed for singleton + */ + private DataUtilities() { + } + + //products + private List productList; + + //customer + private List customerList; + + //vendors + private List vendorList; + + /** + * Lazy initial to get product list + * + * @return initiated product list + */ + public List getProductList() { + if (productList == null) { + createLists(); + } + return productList; + } + + /** + * Lazy initial to get customer list + * + * @return initiated customer list + */ + public List getCustomerList() { + if (customerList == null) { + createLists(); + } + return customerList; + } + + /** + * Lazy initial to get vendor list + * + * @return initiated vendor list + */ + public List getVendorList() { + if (vendorList == null) { + createLists(); + } + return vendorList; + } + + /** + * convert xml files to java objects + */ + private void createLists() { + customerList = xmlToObject(Customers.class, CUSTOMERS_XML); + productList = xmlToObject(Products.class, PRODUCTS_XML); + vendorList = xmlToObject(Vendors.class, VENDORS_XML); + } + + /** + * Convert a xml file to instance of class by given file name + * + * @param clazz to be converted java object's class + * @param file xml file name + * @return a list of object that xml's root contains + */ + private > List xmlToObject(Class clazz, + String file) { + try { + JAXBContext context = JAXBContext.newInstance(clazz); + Unmarshaller um = context.createUnmarshaller(); + @SuppressWarnings("unchecked") + V cs = (V) um.unmarshal(new File(file)); + return cs.getList(); + } catch (JAXBException ex) { + throw new RuntimeException(ex); + } + } + + /** + * static factory method for singleton + * + * @return a DataUtitlities signgleton instance + */ + public static DataUtilities getUtilities() { + return UtilitiesHolder.instance; + } +} --- /dev/null 2014-02-02 21:38:51.000000000 +0800 +++ new/src/share/sample/stream/data/Order.java 2014-02-02 21:38:51.000000000 +0800 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream.data; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * Order meta data class + * + * @author tyan + */ +@XmlRootElement(name = "order") +public class Order { + + /** + * @return id of order. + */ + @XmlElement(name = "id") + public int getOrderId() { + return orderId; + } + + /** + * Set orderId + * + * @param orderId order's id + */ + public void setOrderId(int orderId) { + this.orderId = orderId; + } + + /** + * @return string of order's date + */ + public String getOrderdate() { + return dtf.format(orderdate); + } + + /** + * @return order date + */ + public LocalDateTime getLocalOrderdate() { + return orderdate; + } + + /** + * Set orderdate + * + * @param orderdate order date + */ + public void setOrderdate(String orderdate) { + this.orderdate = LocalDateTime.parse(orderdate, dtf); + } + + /** + * @return total number of order + */ + public double getTotal() { + return total; + } + + /** + * Set total number + * + * @param total total number of this odder + */ + public void setTotal(double total) { + this.total = total; + } + + /** + * Id of order. + */ + private int orderId; + + /** + * order date. + */ + private LocalDateTime orderdate; + + /** + * Total number of order. + */ + private double total; + + /** + * Formatter for convert orderdate and String + */ + private final DateTimeFormatter dtf + = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); +} --- /dev/null 2014-02-02 21:38:52.000000000 +0800 +++ new/src/share/sample/stream/data/Product.java 2014-02-02 21:38:52.000000000 +0800 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream.data; + +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * Product meta data class + * + * @author tyan + */ +@XmlRootElement(name = "product") +@XmlType(propOrder = {"productID", "productName", "category", "unitPrice", + "unitsInStock"}) +public class Product { + + private int productID; + private String productName; + private String category; + private double unitPrice; + private int unitsInStock; + + /** + * @return the productID + */ + public int getProductID() { + return productID; + } + + /** + * @param productID the productID to set + */ + public void setProductID(int productID) { + this.productID = productID; + } + + /** + * @return the productName + */ + public String getProductName() { + return productName; + } + + /** + * @param productName the productName to set + */ + public void setProductName(String productName) { + this.productName = productName; + } + + /** + * @return the category + */ + public String getCategory() { + return category; + } + + /** + * @param category the category to set + */ + public void setCategory(String category) { + this.category = category; + } + + /** + * @return the unitPrice + */ + public double getUnitPrice() { + return unitPrice; + } + + /** + * @param unitPrice the unitPrice to set + */ + public void setUnitPrice(double unitPrice) { + this.unitPrice = unitPrice; + } + + /** + * @return the unitsInStock + */ + public int getUnitsInStock() { + return unitsInStock; + } + + /** + * @param unitsInStock the unitsInStock to set + */ + public void setUnitsInStock(int unitsInStock) { + this.unitsInStock = unitsInStock; + } +} --- /dev/null 2014-02-02 21:38:53.000000000 +0800 +++ new/src/share/sample/stream/data/Vendor.java 2014-02-02 21:38:53.000000000 +0800 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream.data; + +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * Vendor meta data class, it's possible some vendor is customer as well. + * + * @author tyan + */ +public @XmlRootElement(name = "vendor") +@XmlType(propOrder = {"vendorName", "address", "city", "country"}) +class Vendor { + + private String vendorName; + private String address; + private String city; + private String country; + + /** + * @return the vendorName + */ + public String getVendorName() { + return vendorName; + } + + /** + * @param vendorName the vendorName to set + */ + public void setVendorName(String vendorName) { + this.vendorName = vendorName; + } + + /** + * @return the address + */ + public String getAddress() { + return address; + } + + /** + * @param address the address to set + */ + public void setAddress(String address) { + this.address = address; + } + + /** + * @return the city + */ + public String getCity() { + return city; + } + + /** + * @param city the city to set + */ + public void setCity(String city) { + this.city = city; + } + + /** + * @return the country + */ + public String getCountry() { + return country; + } + + /** + * @param country the country to set + */ + public void setCountry(String country) { + this.country = country; + } +} --- /dev/null 2014-02-02 21:38:54.000000000 +0800 +++ new/src/share/sample/stream/parallel/Fibonacci.java 2014-02-02 21:38:53.000000000 +0800 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream.parallel; + +import java.util.stream.Stream; + +/** + * This demo shows how to use the parallel calculation to calculate Fibonacci + * sequence. This is a 2-dimensional system of linear difference equations that + * describes the Fibonacci sequence. + * + * @author tyan + */ +public class Fibonacci { + /** + * First Fibonacci number. + */ + private final static long FIBONACCI_1 = 1; + + /** + * Second Fibonacci number. + */ + private final static long FIBONACCI_2 = 1; + + /** + * A base matrix that will be used to calculate Fibonacci sequence. + */ + private final static long[][] BASE + = new long[][]{ + {FIBONACCI_2, FIBONACCI_1}, + {FIBONACCI_1, 0} + } ; + + /** + * @param args argument to run program + */ + public static void main(String[] args) { + try { + if (args.length != 1) { + throw new Exception("Only accept one argument"); + } + int position = Integer.parseInt(args[0]); + if (position < 3) { + throw new Exception("Postiion must be greater than 3"); + } + System.out.printf("The %dth fibonacci number is %d\n" , position, + power(BASE, position)[0][1]); + } catch (Exception nfe) { + usage(); + } + } + + /** + * Matrix binaries operation multiplication. + * @param matrix1 matrix to be multiplied. + * @param matrix2 matrix to multiply. + * @return A new generated matrix which has same number of rows as matrix1 + * and same number of columns as matrix2. + */ + private static long[][] times(long[][] matrix1, long[][] matrix2) { + long[][] result = new long[2][2]; + for(int row = 0; row < matrix1.length; row++) { + for(int col =0; col < matrix2[row].length; col++) { + for(int col1 =0; col1 < matrix1[row].length; col1++) { + result[row][col] += matrix1[row][col1] * matrix2[col1][col]; + } + } + } + return result; + } + + /** + * Power operation to matrix. Requirement for power operation is matrix must + * have same number row and column. + * @param matrix base + * @param n the exponent + * @return the value of the first argument raised to the power of the second + * argument. + */ + private static long[][] power(long[][] matrix, int n) { + return Stream.generate(() -> matrix). + limit(n). + reduce(Fibonacci::times). + get(); + } + + /** + * Usage of this program + */ + public static void usage() { + System.out.println("Usage: java Fibonacci Position"); + System.out.println("Postiion must be a integer greater than 3"); + } +} --- /dev/null 2014-02-02 21:38:55.000000000 +0800 +++ new/src/share/sample/stream/parallel/ImageTransform.java 2014-02-02 21:38:54.000000000 +0800 @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream.parallel; + +import java.awt.image.BufferedImage; +import static java.awt.image.BufferedImage.TYPE_INT_RGB; +import java.io.File; +import java.util.stream.IntStream; +import javax.imageio.ImageIO; +import static stream.parallel.RandomPrimeNumber.usage; + +/** + * This demo shows parallel geometrical transformations of images.The operations + * of image include rotation, shift, scale, inversion. + * + * @author tyan + */ +public class ImageTransform { + + public static void main(String[] args) { + try { + if (args.length < 5) { + usage(); + return; + } + int argPos = 0; + int oprand = 0; + String command = ""; + String inputFile = "", outputFile = ""; + boolean yes = true; + while (argPos < args.length) { + switch (args[argPos++]) { + case "-ls": + case "-rs": + yes = args[argPos - 1].equals("-ls"); + oprand = Integer.parseInt(args[argPos++]); + command = "shift"; + break; + case "-cl": + case "-ccl": + yes = args[argPos - 1].equals("-cl"); + oprand = Integer.parseInt(args[argPos++]); + command = "rotate"; + break; + case "-zo": + oprand = Integer.parseInt(args[argPos++]); + command = "zoom"; + break; + case "-iv": + command = "invert"; + break; + case "-i": + inputFile = args[argPos++]; + break; + case "-o": + outputFile = args[argPos++]; + break; + default: + usage(); + return; + } + } + if (inputFile.equals("") || outputFile.equals("")) { + throw new Exception("Input/Output file is needed"); + } + File inFile = new File(inputFile); + File outFile = new File(outputFile); + BufferedImage in = ImageIO.read(inFile); + int newWidth = in.getWidth(); + int newHeight = in.getHeight(); + if (command.equals("zoom")) { + double magnitude = oprand / 100.0; + newWidth = (int) (newWidth * magnitude); + newHeight = (int) (newHeight * magnitude); + } else if (command.equals("rorate")) { + int max = Math.max(newWidth, newWidth); + newWidth = max; + newHeight = max; + } + BufferedImage out = new BufferedImage(newWidth, newHeight, TYPE_INT_RGB); + if(!command.equals("invert") && oprand <= 0) { + throw new Exception("Value must be a positive number"); + } + switch (command) { + case "shift": + shift(in, out, yes, oprand); + break; + case "rotate": + rotate(in, out, yes, oprand); + break; + case "zoom": + zoom(in, out, oprand / 100.0); + break; + case "invert": + invert(in, out); + break; + } + ImageIO.write(out, "jpg", outFile); + } catch (Exception ex) { + usage(); + } + } + + /** + * Rotate an image as given angle. + * @param in input image + * @param out output image + * @param clockwise true clockwise + * false counter-clockwise + * @param angle angle that image will rotate + */ + public static void rotate(BufferedImage in, BufferedImage out, + boolean clockwise, int angle) { + int width = (int) in.getWidth(); + int height = (int) in.getHeight(); + int centerX = width / 2; + int centerY = height / 2; + double rotateV = (clockwise ? 360 - angle : angle) / 180.0 * Math.PI; + IntStream.range(0, width).parallel().forEach(x -> { + IntStream.range(0, height).parallel().forEach(y -> { + int newX = (int) (centerX + (x - centerX) * Math.cos(rotateV) + + (y - centerY) * Math.sin(rotateV)); + int newY = (int) (centerY + (x - centerX) * Math.sin(rotateV) + + (y - centerY) * Math.cos(rotateV)); + if (newX >= 0 && newX < width && newY >= 0 && newY < height) { + out.setRGB(newX, newY, in.getRGB(x, y)); + } + }); + }); + } + + /** + * Shift an image horizontally. + * @param in input image + * @param out output image + * @param left true left shift + * false right shift + * @param length size that image shifts + */ + public static void shift(BufferedImage in, BufferedImage out, + boolean left, int length) { + int width = (int) out.getWidth(); + int height = (int) out.getHeight(); + int leftShift = left ? length % width : width - length % width; + IntStream.range(0, width).parallel().forEach(x -> { + IntStream.range(0, height).parallel().forEach(y -> { + int newX = x >= leftShift ? x - leftShift : width + x - leftShift; + out.setRGB(newX, y, in.getRGB(x, y)); + }); + }); + } + + /** + * Zoom in/out an image. + * @param in input image + * @param out output image + * @param magnitude scale of original image. + */ + public static void zoom(BufferedImage in, BufferedImage out, + double magnitude) { + int width = (int) out.getWidth(); + int height = (int) out.getHeight(); + IntStream.range(0, width).parallel().forEach(x -> { + IntStream.range(0, height).parallel().forEach(y -> { + int oldX = (int) (x / magnitude); + int oldY = (int) (y / magnitude); + if (oldX < in.getWidth() && oldY < in.getHeight()) { + out.setRGB(x, y, in.getRGB(oldX, oldY)); + } + }); + }); + } + + /** + * Invert color of an image. + * @param in input image + * @param out output image + */ + public static void invert(BufferedImage in, BufferedImage out) { + int width = (int) out.getWidth(); + int height = (int) out.getHeight(); + IntStream.range(0, width).parallel().forEach(x -> { + IntStream.range(0, height).parallel().forEach(y -> { + out.setRGB(x, y, in.getRGB(x, y) ^ 0xffffff); + }); + }); + } + + /** + * Usage of this program + */ + public static void usage() { + System.out.println("Usage: java ImageTransform {-rs size|-ls size|" + + "-cl angle|-ccl angle|-zo percentage|-zo precentage|-iv} " + + "-i InputFile -o OutputFile"); + } +} --- /dev/null 2014-02-02 21:38:56.000000000 +0800 +++ new/src/share/sample/stream/parallel/MonteCarloPI.java 2014-02-02 21:38:55.000000000 +0800 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream.parallel; + +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.LongStream; + +/** + * This demo shows how to use the parallel mode and the Monte Carlo method to + * calculate the value of PI + * + * @author tyan + */ +public class MonteCarloPI { + + public static void main(String[] args) { + System.out.println("This might take several minutes, " + + "depending on your system"); + LongStream.iterate(10l, l -> 10 * l). + limit(10). + forEach(times -> { + System.out.printf( + "The value of PI is %1.14f after %,d times calculation\n", + pi(times), times); + }); + } + + /** + * Use the Monte Carlo method to calculate the value of PI. basic algorithm + * is: 1. Draw a square on the ground, then inscribe a circle within it. 2. + * Scatter some objects of uniform size (grains of rice or sand) over the + * square. 3. Count the total number of objects inside the circle and the + * total number of objects overall. 4. The ratio of the two total is an + * estimate of the ratio of the two areas, which is PI/4. Multiply the + * result by 4 to estimate PI. + * + * @param x how many times randomly selected a point + * @return value of π by x times calculation + */ + private static double pi(long N) { + long M = LongStream.range(0, N).parallel().filter(sr -> { + // Random picked up point to check if it's in the circle. + double x = ThreadLocalRandom.current().nextDouble(-1, 1); + double y = ThreadLocalRandom.current().nextDouble(-1, 1); + + return x * x + y * y < 1.0 * 1.0; // Not using + }).count(); + return 4.0 * M / N; + } + + /** + * Use ThreadLocalRandom to simulate that whether a point is inside the + * circle or outside the circle + * + * @return 1 randomly selected point is inside the circle 0 randomly + * selected point is outside the circle + */ + private static long hit() { + ThreadLocalRandom lr = ThreadLocalRandom.current(); + double x = lr.nextDouble(1.0); + double y = lr.nextDouble(1.0); + return Math.sqrt(y * y + x * x) <= 1.0 ? 1 : 0; + } +} --- /dev/null 2014-02-02 21:38:57.000000000 +0800 +++ new/src/share/sample/stream/parallel/RandomPrimeNumber.java 2014-02-02 21:38:56.000000000 +0800 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream.parallel; + +import java.math.BigInteger; +import java.util.Random; +import java.util.stream.LongStream; + +/** + * This demo shows how to use the parallel mode to find several number of + * unknown length�prime number. The process easily use new Random.LongStream + * generates a desired length stream. Following with filter operation. Here + * input length is desirable long stream length instead of number of prime + * number. + * + * @author tyan + */ +public class RandomPrimeNumber { + /** + * By default we only calculate at most 64 numbers once.. + */ + private final static long RANGE_SIZE = 1 << 6; + + /** + * Try to get length from command line. Use the length to create random long + * stream, that integer's digit is length. + * + * @param args This has to be a 1-element or 2-elements array, The first + * element must be a positive number, which equals to length of generated + * prime number stream. Second element is optional, it will be used as how + * many prime number that will be generated if it's set. + */ + public static void main(String[] args) { + if (args.length != 1 && args.length != 2) { + usage(); + return; + } + try { + int length = Integer.parseInt(args[0]); + if (length > 16) { + System.out.println("Can calculate maximun only l6 digits " + + "prime number"); + return; + } + long numberOfPrime = RANGE_SIZE; + if (args.length == 2) { + numberOfPrime = Long.parseLong(args[1]); + } + long minNDigit = BigInteger.valueOf(10L).pow(length - 1).longValue(); + long maxNDigit = BigInteger.valueOf(10L).pow(length).longValue(); + + new Random(System.currentTimeMillis()). + longs(numberOfPrime, minNDigit, maxNDigit). + filter(N -> isPrime(N)). + forEach(System.out::println); + } catch (NumberFormatException nfe) { + usage(); + } + } + + /** + * Decide if a BigInteger is a prime number + * + * @param integer a number + * @return true if integer is a prime number false if integer is not a prime + * number + */ + private static boolean isPrime(long number) { + //This is a parall version that checks if a number is a prime number + return !LongStream.range(2L, Math.round(Math.sqrt(number))).parallel(). + anyMatch(divisor -> number % divisor == 0); + } + + /** + * Usage of this program + */ + public static void usage() { + System.out.println("Usage: java RandomPrimeNumber lentgh[size]"); + System.out.println("length is a positive integer not greater than 16"); + System.out.println("size is a positive integer"); + } +}