├── .gitignore ├── CHANGELOG ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── build.gradle ├── genlib ├── __init__.py ├── gen.py └── mako_template.py ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── third_party └── openjdk ├── LICENSE ├── METADATA ├── common ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── google │ └── chkstream │ └── ChkStreamWrappedException.java ├── java8 ├── build.gradle └── src │ └── test │ └── java │ └── com │ └── google │ └── chkstream │ ├── ChkStreamFunctionalTest.java │ └── ChkStreamThrowTest.java ├── streamsupport ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── google │ │ └── chkstream │ │ └── lang │ │ └── AutoCloseable.java │ └── test │ └── java │ └── com │ └── google │ └── chkstream │ ├── ChkStreamFunctionalTest.java │ └── ChkStreamThrowTest.java └── tmpl └── com └── google └── chkstream ├── ChkPrimitiveStream.tmpl.java ├── ChkStream.tmpl.java ├── ChkStreams.tmpl.java ├── function ├── ChkConsumers.tmpl.java ├── ChkFunctions.tmpl.java ├── ChkPredicates.tmpl.java ├── ChkRunnables.tmpl.java └── FunctionUtils.tmpl.java └── package-info.java /.gitignore: -------------------------------------------------------------------------------- 1 | /.gradle/ 2 | .settings/ 3 | bin/ 4 | build/ 5 | generated/ 6 | 7 | *.pyc 8 | .classpath 9 | .directory 10 | .project 11 | .pydevproject 12 | env.sh 13 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | v1.1.0: Support for primitive stream specializations. 2 | 3 | v1.0.0: Initial release. 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to any Google project must be accompanied by a Contributor License 9 | Agreement. This is necessary because you own the copyright to your changes, even 10 | after your contribution becomes part of this project. So this agreement simply 11 | gives us permission to use and redistribute your contributions as part of the 12 | project. Head over to to see your current 13 | agreements on file or to sign a new one. 14 | 15 | You generally only need to submit a CLA once, so if you've already submitted one 16 | (even if it was for a different project), you probably don't need to do it 17 | again. 18 | 19 | ## Code reviews 20 | 21 | All submissions, including submissions by project members, require review. We 22 | use GitHub pull requests for this purpose. Consult [GitHub Help] for more 23 | information on using pull requests. 24 | 25 | [GitHub Help]: https://help.github.com/articles/about-pull-requests/ 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The GNU General Public License (GPL) 2 | 3 | Version 2, June 1991 4 | 5 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 6 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7 | 8 | Everyone is permitted to copy and distribute verbatim copies of this license 9 | document, but changing it is not allowed. 10 | 11 | Preamble 12 | 13 | The licenses for most software are designed to take away your freedom to share 14 | and change it. By contrast, the GNU General Public License is intended to 15 | guarantee your freedom to share and change free software--to make sure the 16 | software is free for all its users. This General Public License applies to 17 | most of the Free Software Foundation's software and to any other program whose 18 | authors commit to using it. (Some other Free Software Foundation software is 19 | covered by the GNU Library General Public License instead.) You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not price. Our 23 | General Public Licenses are designed to make sure that you have the freedom to 24 | distribute copies of free software (and charge for this service if you wish), 25 | that you receive source code or can get it if you want it, that you can change 26 | the software or use pieces of it in new free programs; and that you know you 27 | can do these things. 28 | 29 | To protect your rights, we need to make restrictions that forbid anyone to deny 30 | you these rights or to ask you to surrender the rights. These restrictions 31 | translate to certain responsibilities for you if you distribute copies of the 32 | software, or if you modify it. 33 | 34 | For example, if you distribute copies of such a program, whether gratis or for 35 | a fee, you must give the recipients all the rights that you have. You must 36 | make sure that they, too, receive or can get the source code. And you must 37 | show them these terms so they know their rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and (2) 40 | offer you this license which gives you legal permission to copy, distribute 41 | and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain that 44 | everyone understands that there is no warranty for this free software. If the 45 | software is modified by someone else and passed on, we want its recipients to 46 | know that what they have is not the original, so that any problems introduced 47 | by others will not reflect on the original authors' reputations. 48 | 49 | Finally, any free program is threatened constantly by software patents. We 50 | wish to avoid the danger that redistributors of a free program will 51 | individually obtain patent licenses, in effect making the program proprietary. 52 | To prevent this, we have made it clear that any patent must be licensed for 53 | everyone's free use or not licensed at all. 54 | 55 | The precise terms and conditions for copying, distribution and modification 56 | follow. 57 | 58 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 59 | 60 | 0. This License applies to any program or other work which contains a notice 61 | placed by the copyright holder saying it may be distributed under the terms of 62 | this General Public License. The "Program", below, refers to any such program 63 | or work, and a "work based on the Program" means either the Program or any 64 | derivative work under copyright law: that is to say, a work containing the 65 | Program or a portion of it, either verbatim or with modifications and/or 66 | translated into another language. (Hereinafter, translation is included 67 | without limitation in the term "modification".) Each licensee is addressed as 68 | "you". 69 | 70 | Activities other than copying, distribution and modification are not covered by 71 | this License; they are outside its scope. The act of running the Program is 72 | not restricted, and the output from the Program is covered only if its contents 73 | constitute a work based on the Program (independent of having been made by 74 | running the Program). Whether that is true depends on what the Program does. 75 | 76 | 1. You may copy and distribute verbatim copies of the Program's source code as 77 | you receive it, in any medium, provided that you conspicuously and 78 | appropriately publish on each copy an appropriate copyright notice and 79 | disclaimer of warranty; keep intact all the notices that refer to this License 80 | and to the absence of any warranty; and give any other recipients of the 81 | Program a copy of this License along with the Program. 82 | 83 | You may charge a fee for the physical act of transferring a copy, and you may 84 | at your option offer warranty protection in exchange for a fee. 85 | 86 | 2. You may modify your copy or copies of the Program or any portion of it, thus 87 | forming a work based on the Program, and copy and distribute such modifications 88 | or work under the terms of Section 1 above, provided that you also meet all of 89 | these conditions: 90 | 91 | a) You must cause the modified files to carry prominent notices stating 92 | that you changed the files and the date of any change. 93 | 94 | b) You must cause any work that you distribute or publish, that in whole or 95 | in part contains or is derived from the Program or any part thereof, to be 96 | licensed as a whole at no charge to all third parties under the terms of 97 | this License. 98 | 99 | c) If the modified program normally reads commands interactively when run, 100 | you must cause it, when started running for such interactive use in the 101 | most ordinary way, to print or display an announcement including an 102 | appropriate copyright notice and a notice that there is no warranty (or 103 | else, saying that you provide a warranty) and that users may redistribute 104 | the program under these conditions, and telling the user how to view a copy 105 | of this License. (Exception: if the Program itself is interactive but does 106 | not normally print such an announcement, your work based on the Program is 107 | not required to print an announcement.) 108 | 109 | These requirements apply to the modified work as a whole. If identifiable 110 | sections of that work are not derived from the Program, and can be reasonably 111 | considered independent and separate works in themselves, then this License, and 112 | its terms, do not apply to those sections when you distribute them as separate 113 | works. But when you distribute the same sections as part of a whole which is a 114 | work based on the Program, the distribution of the whole must be on the terms 115 | of this License, whose permissions for other licensees extend to the entire 116 | whole, and thus to each and every part regardless of who wrote it. 117 | 118 | Thus, it is not the intent of this section to claim rights or contest your 119 | rights to work written entirely by you; rather, the intent is to exercise the 120 | right to control the distribution of derivative or collective works based on 121 | the Program. 122 | 123 | In addition, mere aggregation of another work not based on the Program with the 124 | Program (or with a work based on the Program) on a volume of a storage or 125 | distribution medium does not bring the other work under the scope of this 126 | License. 127 | 128 | 3. You may copy and distribute the Program (or a work based on it, under 129 | Section 2) in object code or executable form under the terms of Sections 1 and 130 | 2 above provided that you also do one of the following: 131 | 132 | a) Accompany it with the complete corresponding machine-readable source 133 | code, which must be distributed under the terms of Sections 1 and 2 above 134 | on a medium customarily used for software interchange; or, 135 | 136 | b) Accompany it with a written offer, valid for at least three years, to 137 | give any third party, for a charge no more than your cost of physically 138 | performing source distribution, a complete machine-readable copy of the 139 | corresponding source code, to be distributed under the terms of Sections 1 140 | and 2 above on a medium customarily used for software interchange; or, 141 | 142 | c) Accompany it with the information you received as to the offer to 143 | distribute corresponding source code. (This alternative is allowed only 144 | for noncommercial distribution and only if you received the program in 145 | object code or executable form with such an offer, in accord with 146 | Subsection b above.) 147 | 148 | The source code for a work means the preferred form of the work for making 149 | modifications to it. For an executable work, complete source code means all 150 | the source code for all modules it contains, plus any associated interface 151 | definition files, plus the scripts used to control compilation and installation 152 | of the executable. However, as a special exception, the source code 153 | distributed need not include anything that is normally distributed (in either 154 | source or binary form) with the major components (compiler, kernel, and so on) 155 | of the operating system on which the executable runs, unless that component 156 | itself accompanies the executable. 157 | 158 | If distribution of executable or object code is made by offering access to copy 159 | from a designated place, then offering equivalent access to copy the source 160 | code from the same place counts as distribution of the source code, even though 161 | third parties are not compelled to copy the source along with the object code. 162 | 163 | 4. You may not copy, modify, sublicense, or distribute the Program except as 164 | expressly provided under this License. Any attempt otherwise to copy, modify, 165 | sublicense or distribute the Program is void, and will automatically terminate 166 | your rights under this License. However, parties who have received copies, or 167 | rights, from you under this License will not have their licenses terminated so 168 | long as such parties remain in full compliance. 169 | 170 | 5. You are not required to accept this License, since you have not signed it. 171 | However, nothing else grants you permission to modify or distribute the Program 172 | or its derivative works. These actions are prohibited by law if you do not 173 | accept this License. Therefore, by modifying or distributing the Program (or 174 | any work based on the Program), you indicate your acceptance of this License to 175 | do so, and all its terms and conditions for copying, distributing or modifying 176 | the Program or works based on it. 177 | 178 | 6. Each time you redistribute the Program (or any work based on the Program), 179 | the recipient automatically receives a license from the original licensor to 180 | copy, distribute or modify the Program subject to these terms and conditions. 181 | You may not impose any further restrictions on the recipients' exercise of the 182 | rights granted herein. You are not responsible for enforcing compliance by 183 | third parties to this License. 184 | 185 | 7. If, as a consequence of a court judgment or allegation of patent 186 | infringement or for any other reason (not limited to patent issues), conditions 187 | are imposed on you (whether by court order, agreement or otherwise) that 188 | contradict the conditions of this License, they do not excuse you from the 189 | conditions of this License. If you cannot distribute so as to satisfy 190 | simultaneously your obligations under this License and any other pertinent 191 | obligations, then as a consequence you may not distribute the Program at all. 192 | For example, if a patent license would not permit royalty-free redistribution 193 | of the Program by all those who receive copies directly or indirectly through 194 | you, then the only way you could satisfy both it and this License would be to 195 | refrain entirely from distribution of the Program. 196 | 197 | If any portion of this section is held invalid or unenforceable under any 198 | particular circumstance, the balance of the section is intended to apply and 199 | the section as a whole is intended to apply in other circumstances. 200 | 201 | It is not the purpose of this section to induce you to infringe any patents or 202 | other property right claims or to contest validity of any such claims; this 203 | section has the sole purpose of protecting the integrity of the free software 204 | distribution system, which is implemented by public license practices. Many 205 | people have made generous contributions to the wide range of software 206 | distributed through that system in reliance on consistent application of that 207 | system; it is up to the author/donor to decide if he or she is willing to 208 | distribute software through any other system and a licensee cannot impose that 209 | choice. 210 | 211 | This section is intended to make thoroughly clear what is believed to be a 212 | consequence of the rest of this License. 213 | 214 | 8. If the distribution and/or use of the Program is restricted in certain 215 | countries either by patents or by copyrighted interfaces, the original 216 | copyright holder who places the Program under this License may add an explicit 217 | geographical distribution limitation excluding those countries, so that 218 | distribution is permitted only in or among countries not thus excluded. In 219 | such case, this License incorporates the limitation as if written in the body 220 | of this License. 221 | 222 | 9. The Free Software Foundation may publish revised and/or new versions of the 223 | General Public License from time to time. Such new versions will be similar in 224 | spirit to the present version, but may differ in detail to address new problems 225 | or concerns. 226 | 227 | Each version is given a distinguishing version number. If the Program 228 | specifies a version number of this License which applies to it and "any later 229 | version", you have the option of following the terms and conditions either of 230 | that version or of any later version published by the Free Software Foundation. 231 | If the Program does not specify a version number of this License, you may 232 | choose any version ever published by the Free Software Foundation. 233 | 234 | 10. If you wish to incorporate parts of the Program into other free programs 235 | whose distribution conditions are different, write to the author to ask for 236 | permission. For software which is copyrighted by the Free Software Foundation, 237 | write to the Free Software Foundation; we sometimes make exceptions for this. 238 | Our decision will be guided by the two goals of preserving the free status of 239 | all derivatives of our free software and of promoting the sharing and reuse of 240 | software generally. 241 | 242 | NO WARRANTY 243 | 244 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR 245 | THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE 246 | STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE 247 | PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, 248 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 249 | FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND 250 | PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, 251 | YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 252 | 253 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL 254 | ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE 255 | PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 256 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR 257 | INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA 258 | BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 259 | FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER 260 | OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 261 | 262 | END OF TERMS AND CONDITIONS 263 | 264 | How to Apply These Terms to Your New Programs 265 | 266 | If you develop a new program, and you want it to be of the greatest possible 267 | use to the public, the best way to achieve this is to make it free software 268 | which everyone can redistribute and change under these terms. 269 | 270 | To do so, attach the following notices to the program. It is safest to attach 271 | them to the start of each source file to most effectively convey the exclusion 272 | of warranty; and each file should have at least the "copyright" line and a 273 | pointer to where the full notice is found. 274 | 275 | One line to give the program's name and a brief idea of what it does. 276 | 277 | Copyright (C) 278 | 279 | This program is free software; you can redistribute it and/or modify it 280 | under the terms of the GNU General Public License as published by the Free 281 | Software Foundation; either version 2 of the License, or (at your option) 282 | any later version. 283 | 284 | This program is distributed in the hope that it will be useful, but WITHOUT 285 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 286 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 287 | more details. 288 | 289 | You should have received a copy of the GNU General Public License along 290 | with this program; if not, write to the Free Software Foundation, Inc., 59 291 | Temple Place, Suite 330, Boston, MA 02111-1307 USA 292 | 293 | Also add information on how to contact you by electronic and paper mail. 294 | 295 | If the program is interactive, make it output a short notice like this when it 296 | starts in an interactive mode: 297 | 298 | Gnomovision version 69, Copyright (C) year name of author Gnomovision comes 299 | with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free 300 | software, and you are welcome to redistribute it under certain conditions; 301 | type 'show c' for details. 302 | 303 | The hypothetical commands 'show w' and 'show c' should show the appropriate 304 | parts of the General Public License. Of course, the commands you use may be 305 | called something other than 'show w' and 'show c'; they could even be 306 | mouse-clicks or menu items--whatever suits your program. 307 | 308 | You should also get your employer (if you work as a programmer) or your school, 309 | if any, to sign a "copyright disclaimer" for the program, if necessary. Here 310 | is a sample; alter the names: 311 | 312 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 313 | 'Gnomovision' (which makes passes at compilers) written by James Hacker. 314 | 315 | signature of Ty Coon, 1 April 1989 316 | 317 | Ty Coon, President of Vice 318 | 319 | This General Public License does not permit incorporating your program into 320 | proprietary programs. If your program is a subroutine library, you may 321 | consider it more useful to permit linking proprietary applications with the 322 | library. If this is what you want to do, use the GNU Library General Public 323 | License instead of this License. 324 | 325 | 326 | "CLASSPATH" EXCEPTION TO THE GPL 327 | 328 | Certain source files distributed by Oracle America and/or its affiliates are 329 | subject to the following clarification and special exception to the GPL, but 330 | only where Oracle has expressly included in the particular source file's header 331 | the words "Oracle designates this particular file as subject to the "Classpath" 332 | exception as provided by Oracle in the LICENSE file that accompanied this code." 333 | 334 | Linking this library statically or dynamically with other modules is making 335 | a combined work based on this library. Thus, the terms and conditions of 336 | the GNU General Public License cover the whole combination. 337 | 338 | As a special exception, the copyright holders of this library give you 339 | permission to link this library with independent modules to produce an 340 | executable, regardless of the license terms of these independent modules, 341 | and to copy and distribute the resulting executable under terms of your 342 | choice, provided that you also meet, for each linked independent module, 343 | the terms and conditions of the license of that module. An independent 344 | module is a module which is not derived from or based on this library. If 345 | you modify this library, you may extend this exception to your version of 346 | the library, but you are not obligated to do so. If you do not wish to do 347 | so, delete this exception statement from your version. 348 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Checked Exception Streams 2 | 3 | **Checked Exception Streams** (ChkStreams) adds checked exception support to the 4 | Java 8 Stream API. 5 | 6 | ChkStreams is not an official Google product. 7 | 8 | 9 | ## Overview 10 | 11 | Have you ever wanted to write something like this, but been foiled by the 12 | dreaded `Unhandled exception type IOException`? 13 | 14 | ```java 15 | filenames.parallelStream() 16 | .map(Files::readFully) 17 | .collect(toList()); 18 | ``` 19 | 20 | Be foiled no more! 21 | 22 | ```java 23 | ChkStreams.of(filenames.parallelStream()) 24 | .canThrow(IOException.class) 25 | .map(Files::readFully) 26 | .collect(toList()); 27 | ``` 28 | 29 | 30 | ## Usage 31 | 32 | ChkStreams extends the existing Java 8 Stream API. To use it, simply: 33 | 34 | 1. Wrap any `Stream` using `ChkStreams.of(Stream)` to get a `ChkStream`. 35 | 2. Declare one or more checked exceptions by calling 36 | `ChkStream#canThrow(Exception)`, so that subsequent stream operations will 37 | allow that `Exception`. 38 | 3. Use the same Stream API you're used to (except now your lambdas can throw the 39 | declared exceptions!) 40 | 4. Handle the checked exceptions in the usual way (catch or declare thrown) in 41 | any method that invokes a **terminal** operation on the stream. 42 | 43 | 44 | ## Features 45 | 46 | * Adds checked exception support to the familiar Streams API! 47 | * Exceptions are enforced by the compiler in the usual way, and need only be 48 | handled when invoking terminal operations. 49 | * Can be converted to/from regular Java `Stream`s (See `ChkStreams#of(Stream)` 50 | and `ChkStream#toStream()`). Regular streams obtained from 51 | `ChkStream#toStream()` will throw unchecked exceptions (specifically 52 | `ChkStreamWrappedException`) when checked exceptions occur in the stream. 53 | * All primitive specializations of `Stream` are supported without boxing (See 54 | `ChkStreams#ofInt(IntStream)`). 55 | * (Optional) support for the 56 | [StreamSupport backport](https://streamsupport.sourceforge.io/) and 57 | [Retrolambda](https://github.com/orfjackal/retrolambda). Enjoy the power of 58 | `ChkStream` on Java 6+ and Android! 59 | * May cause you to barf rainbows. 60 | 61 | 62 | ## Limitations 63 | 64 | * A maximum of 5 checked exceptions may be added to a `ChkStream`. 65 | * No interfaces in common with `Stream` or between `ChkStream`s with different 66 | numbers of exceptions. 67 | 68 | 69 | ## License 70 | 71 | This project is licensed under the GNU GPLv2 with Classpath Exception, which is 72 | the same license as OpenJDK itself. 73 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | subprojects { 2 | repositories { 3 | mavenCentral() 4 | } 5 | gradle.projectsEvaluated { 6 | tasks.withType(JavaCompile) { 7 | options.compilerArgs << "-Xlint:all" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /genlib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/chkstream/d99e40b9f5a2a729c3789bdb26386e9228de01e8/genlib/__init__.py -------------------------------------------------------------------------------- /genlib/gen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2.7 2 | # Copyright 2017 Google. 3 | # 4 | # This file is licensed under the GPLv2+Classpath Exception, which full text 5 | # is found in the LICENSE file at the root of this project. 6 | # 7 | # Google designates this particular file as subject to the "Classpath" 8 | # exception as provided in the LICENSE file that accompanied this code. 9 | 10 | """A script to format source code templates using Mako.""" 11 | 12 | __author__ = 'Alexander Dorokhine' 13 | 14 | import logging 15 | import os 16 | import shutil 17 | 18 | import mako_template 19 | 20 | 21 | MIN_EXCEPTIONS = 1 22 | MAX_EXCEPTIONS = 5 23 | 24 | PROJECTS = ('third_party/openjdk',) 25 | ROOT_PKG_DIR = 'com/google/chkstream' 26 | GEN_SRC_DIR = 'src/main/generated' 27 | 28 | STREAM_IMPLS = ['java8', 'streamsupport'] 29 | SPECIALIZATIONS = ['Int', 'Long', 'Double'] 30 | 31 | 32 | class Error(Exception): 33 | pass 34 | 35 | 36 | def _GetOutputDir(project_root, tmpl_dir, input_file, stream_impl=None): 37 | """Gets the destination dir for an output file given an input file. 38 | 39 | The output is relative to the root project. 40 | """ 41 | root_pkg_tmpl_dir = os.path.join(tmpl_dir, ROOT_PKG_DIR) 42 | package_path = os.path.relpath(input_file, root_pkg_tmpl_dir) 43 | package_dir = os.path.dirname(package_path) 44 | if stream_impl: 45 | output_dir = os.path.join( 46 | project_root, stream_impl, GEN_SRC_DIR, ROOT_PKG_DIR, stream_impl, 47 | package_dir) 48 | else: 49 | output_dir = os.path.join( 50 | project_root, 'common', GEN_SRC_DIR, ROOT_PKG_DIR, package_dir) 51 | output_dir = os.path.normpath(output_dir) 52 | return output_dir 53 | 54 | 55 | def CleanAll(): 56 | for project in PROJECTS: 57 | for dirpath, dirnames, filenames in os.walk(project): 58 | for dirname in dirnames: 59 | if dirname == 'generated': 60 | folder = os.path.join(dirpath, dirname) 61 | if os.path.exists(folder): 62 | logging.info('Cleaning folder "%s"', folder) 63 | shutil.rmtree(folder) 64 | 65 | 66 | def GenAll(): 67 | for project in PROJECTS: 68 | GenProject(project, os.path.join(project, 'tmpl/')) 69 | 70 | 71 | def GenProject(project_root, tmpl_dir): 72 | for dirpath, dirnames, filenames in os.walk(tmpl_dir): 73 | for filename in filenames: 74 | input_file = os.path.join(dirpath, filename) 75 | template = mako_template.MakoTemplate(input_file) 76 | if template.GetTemplateAttr('split'): 77 | GenOneSplitFile(project_root, tmpl_dir, template) 78 | else: 79 | GenOneSingleFile(project_root, tmpl_dir, template) 80 | 81 | 82 | def GenOneSingleFile(project_root, tmpl_dir, template): 83 | stream_impls = ( 84 | STREAM_IMPLS if template.GetTemplateAttr('for_each_stream_impl') 85 | else [None]) 86 | for stream_impl in stream_impls: 87 | output_dir = _GetOutputDir( 88 | project_root, tmpl_dir, template.path, stream_impl) 89 | output_filename = os.path.basename(template.path) 90 | if output_filename.endswith('.tmpl.java'): 91 | output_filename = output_filename[:-len('.tmpl.java')] + '.java' 92 | output_path = os.path.join(output_dir, output_filename) 93 | logging.info('Generating %s', output_path) 94 | template.Bind( 95 | MIN_EXCEPTIONS=MIN_EXCEPTIONS, 96 | MAX_EXCEPTIONS=MAX_EXCEPTIONS, 97 | STREAM_IMPLS=STREAM_IMPLS, 98 | SPECIALIZATIONS=SPECIALIZATIONS, 99 | stream_impl=stream_impl) 100 | template.Output(output_path) 101 | 102 | 103 | def GenOneSplitFile(project_root, tmpl_dir, template): 104 | stream_impls = ( 105 | STREAM_IMPLS if template.GetTemplateAttr('for_each_stream_impl') 106 | else [None]) 107 | specializations = ( 108 | SPECIALIZATIONS if template.GetTemplateAttr('for_each_specialization') 109 | else [None]) 110 | for stream_impl in STREAM_IMPLS: 111 | for specialization in SPECIALIZATIONS: 112 | for num_exceptions in xrange(MIN_EXCEPTIONS, MAX_EXCEPTIONS + 1): 113 | template.Bind( 114 | MIN_EXCEPTIONS=MIN_EXCEPTIONS, 115 | MAX_EXCEPTIONS=MAX_EXCEPTIONS, 116 | STREAM_IMPLS=STREAM_IMPLS, 117 | SPECIALIZATIONS=SPECIALIZATIONS, 118 | num_e=num_exceptions, 119 | stream_impl=stream_impl, 120 | specialization=specialization) 121 | output_filename = template.module.get_filename( 122 | num_exceptions, MIN_EXCEPTIONS, specialization) 123 | output_dir = _GetOutputDir( 124 | project_root, tmpl_dir, template.path, stream_impl) 125 | output_path = os.path.join(output_dir, output_filename) 126 | logging.info('Generating %s', output_path) 127 | template.Output(output_path) 128 | 129 | 130 | if __name__ == '__main__': 131 | logging.basicConfig(level=logging.INFO) 132 | CleanAll() 133 | GenAll() 134 | -------------------------------------------------------------------------------- /genlib/mako_template.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google. 2 | # 3 | # This file is licensed under the GPLv2+Classpath Exception, which full text 4 | # is found in the LICENSE file at the root of this project. 5 | # 6 | # Google designates this particular file as subject to the "Classpath" 7 | # exception as provided in the LICENSE file that accompanied this code. 8 | 9 | import logging 10 | import os 11 | from mako import lookup as mako_lookup 12 | from mako import template as mako_template 13 | 14 | 15 | class MakoTemplate(object): 16 | """An API to interact with a mako template file on disk.""" 17 | 18 | def __init__(self, path): 19 | self.path = path 20 | logging.info('Parsing template %s', path) 21 | with open(path, 'rb') as fh: 22 | self._string = fh.read() 23 | # Load the template into mako 24 | lookup = mako_lookup.TemplateLookup() 25 | self._mako_template = mako_template.Template( 26 | self._string, lookup=lookup, format_exceptions=True) 27 | # print template.code 28 | self.module = self._mako_template.module 29 | 30 | def GetTemplateAttr(self, name, default=None): 31 | return getattr(self.module, name, default) 32 | 33 | def Bind(self, **kwargs): 34 | self._bound_params = kwargs 35 | 36 | def Output(self, output_path): 37 | formatted = self._mako_template.render(**self._bound_params) 38 | output_dir = os.path.dirname(output_path) 39 | if not os.path.exists(output_dir): 40 | os.makedirs(output_dir) 41 | with open(output_path, 'w') as fh: 42 | fh.write(formatted) 43 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/chkstream/d99e40b9f5a2a729c3789bdb26386e9228de01e8/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Apr 03 22:44:10 PDT 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-bin.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ( 2 | ':third_party:openjdk:common', 3 | ':third_party:openjdk:java8', 4 | ':third_party:openjdk:streamsupport' 5 | ) 6 | -------------------------------------------------------------------------------- /third_party/openjdk/LICENSE: -------------------------------------------------------------------------------- 1 | The GNU General Public License (GPL) 2 | 3 | Version 2, June 1991 4 | 5 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 6 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7 | 8 | Everyone is permitted to copy and distribute verbatim copies of this license 9 | document, but changing it is not allowed. 10 | 11 | Preamble 12 | 13 | The licenses for most software are designed to take away your freedom to share 14 | and change it. By contrast, the GNU General Public License is intended to 15 | guarantee your freedom to share and change free software--to make sure the 16 | software is free for all its users. This General Public License applies to 17 | most of the Free Software Foundation's software and to any other program whose 18 | authors commit to using it. (Some other Free Software Foundation software is 19 | covered by the GNU Library General Public License instead.) You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not price. Our 23 | General Public Licenses are designed to make sure that you have the freedom to 24 | distribute copies of free software (and charge for this service if you wish), 25 | that you receive source code or can get it if you want it, that you can change 26 | the software or use pieces of it in new free programs; and that you know you 27 | can do these things. 28 | 29 | To protect your rights, we need to make restrictions that forbid anyone to deny 30 | you these rights or to ask you to surrender the rights. These restrictions 31 | translate to certain responsibilities for you if you distribute copies of the 32 | software, or if you modify it. 33 | 34 | For example, if you distribute copies of such a program, whether gratis or for 35 | a fee, you must give the recipients all the rights that you have. You must 36 | make sure that they, too, receive or can get the source code. And you must 37 | show them these terms so they know their rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and (2) 40 | offer you this license which gives you legal permission to copy, distribute 41 | and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain that 44 | everyone understands that there is no warranty for this free software. If the 45 | software is modified by someone else and passed on, we want its recipients to 46 | know that what they have is not the original, so that any problems introduced 47 | by others will not reflect on the original authors' reputations. 48 | 49 | Finally, any free program is threatened constantly by software patents. We 50 | wish to avoid the danger that redistributors of a free program will 51 | individually obtain patent licenses, in effect making the program proprietary. 52 | To prevent this, we have made it clear that any patent must be licensed for 53 | everyone's free use or not licensed at all. 54 | 55 | The precise terms and conditions for copying, distribution and modification 56 | follow. 57 | 58 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 59 | 60 | 0. This License applies to any program or other work which contains a notice 61 | placed by the copyright holder saying it may be distributed under the terms of 62 | this General Public License. The "Program", below, refers to any such program 63 | or work, and a "work based on the Program" means either the Program or any 64 | derivative work under copyright law: that is to say, a work containing the 65 | Program or a portion of it, either verbatim or with modifications and/or 66 | translated into another language. (Hereinafter, translation is included 67 | without limitation in the term "modification".) Each licensee is addressed as 68 | "you". 69 | 70 | Activities other than copying, distribution and modification are not covered by 71 | this License; they are outside its scope. The act of running the Program is 72 | not restricted, and the output from the Program is covered only if its contents 73 | constitute a work based on the Program (independent of having been made by 74 | running the Program). Whether that is true depends on what the Program does. 75 | 76 | 1. You may copy and distribute verbatim copies of the Program's source code as 77 | you receive it, in any medium, provided that you conspicuously and 78 | appropriately publish on each copy an appropriate copyright notice and 79 | disclaimer of warranty; keep intact all the notices that refer to this License 80 | and to the absence of any warranty; and give any other recipients of the 81 | Program a copy of this License along with the Program. 82 | 83 | You may charge a fee for the physical act of transferring a copy, and you may 84 | at your option offer warranty protection in exchange for a fee. 85 | 86 | 2. You may modify your copy or copies of the Program or any portion of it, thus 87 | forming a work based on the Program, and copy and distribute such modifications 88 | or work under the terms of Section 1 above, provided that you also meet all of 89 | these conditions: 90 | 91 | a) You must cause the modified files to carry prominent notices stating 92 | that you changed the files and the date of any change. 93 | 94 | b) You must cause any work that you distribute or publish, that in whole or 95 | in part contains or is derived from the Program or any part thereof, to be 96 | licensed as a whole at no charge to all third parties under the terms of 97 | this License. 98 | 99 | c) If the modified program normally reads commands interactively when run, 100 | you must cause it, when started running for such interactive use in the 101 | most ordinary way, to print or display an announcement including an 102 | appropriate copyright notice and a notice that there is no warranty (or 103 | else, saying that you provide a warranty) and that users may redistribute 104 | the program under these conditions, and telling the user how to view a copy 105 | of this License. (Exception: if the Program itself is interactive but does 106 | not normally print such an announcement, your work based on the Program is 107 | not required to print an announcement.) 108 | 109 | These requirements apply to the modified work as a whole. If identifiable 110 | sections of that work are not derived from the Program, and can be reasonably 111 | considered independent and separate works in themselves, then this License, and 112 | its terms, do not apply to those sections when you distribute them as separate 113 | works. But when you distribute the same sections as part of a whole which is a 114 | work based on the Program, the distribution of the whole must be on the terms 115 | of this License, whose permissions for other licensees extend to the entire 116 | whole, and thus to each and every part regardless of who wrote it. 117 | 118 | Thus, it is not the intent of this section to claim rights or contest your 119 | rights to work written entirely by you; rather, the intent is to exercise the 120 | right to control the distribution of derivative or collective works based on 121 | the Program. 122 | 123 | In addition, mere aggregation of another work not based on the Program with the 124 | Program (or with a work based on the Program) on a volume of a storage or 125 | distribution medium does not bring the other work under the scope of this 126 | License. 127 | 128 | 3. You may copy and distribute the Program (or a work based on it, under 129 | Section 2) in object code or executable form under the terms of Sections 1 and 130 | 2 above provided that you also do one of the following: 131 | 132 | a) Accompany it with the complete corresponding machine-readable source 133 | code, which must be distributed under the terms of Sections 1 and 2 above 134 | on a medium customarily used for software interchange; or, 135 | 136 | b) Accompany it with a written offer, valid for at least three years, to 137 | give any third party, for a charge no more than your cost of physically 138 | performing source distribution, a complete machine-readable copy of the 139 | corresponding source code, to be distributed under the terms of Sections 1 140 | and 2 above on a medium customarily used for software interchange; or, 141 | 142 | c) Accompany it with the information you received as to the offer to 143 | distribute corresponding source code. (This alternative is allowed only 144 | for noncommercial distribution and only if you received the program in 145 | object code or executable form with such an offer, in accord with 146 | Subsection b above.) 147 | 148 | The source code for a work means the preferred form of the work for making 149 | modifications to it. For an executable work, complete source code means all 150 | the source code for all modules it contains, plus any associated interface 151 | definition files, plus the scripts used to control compilation and installation 152 | of the executable. However, as a special exception, the source code 153 | distributed need not include anything that is normally distributed (in either 154 | source or binary form) with the major components (compiler, kernel, and so on) 155 | of the operating system on which the executable runs, unless that component 156 | itself accompanies the executable. 157 | 158 | If distribution of executable or object code is made by offering access to copy 159 | from a designated place, then offering equivalent access to copy the source 160 | code from the same place counts as distribution of the source code, even though 161 | third parties are not compelled to copy the source along with the object code. 162 | 163 | 4. You may not copy, modify, sublicense, or distribute the Program except as 164 | expressly provided under this License. Any attempt otherwise to copy, modify, 165 | sublicense or distribute the Program is void, and will automatically terminate 166 | your rights under this License. However, parties who have received copies, or 167 | rights, from you under this License will not have their licenses terminated so 168 | long as such parties remain in full compliance. 169 | 170 | 5. You are not required to accept this License, since you have not signed it. 171 | However, nothing else grants you permission to modify or distribute the Program 172 | or its derivative works. These actions are prohibited by law if you do not 173 | accept this License. Therefore, by modifying or distributing the Program (or 174 | any work based on the Program), you indicate your acceptance of this License to 175 | do so, and all its terms and conditions for copying, distributing or modifying 176 | the Program or works based on it. 177 | 178 | 6. Each time you redistribute the Program (or any work based on the Program), 179 | the recipient automatically receives a license from the original licensor to 180 | copy, distribute or modify the Program subject to these terms and conditions. 181 | You may not impose any further restrictions on the recipients' exercise of the 182 | rights granted herein. You are not responsible for enforcing compliance by 183 | third parties to this License. 184 | 185 | 7. If, as a consequence of a court judgment or allegation of patent 186 | infringement or for any other reason (not limited to patent issues), conditions 187 | are imposed on you (whether by court order, agreement or otherwise) that 188 | contradict the conditions of this License, they do not excuse you from the 189 | conditions of this License. If you cannot distribute so as to satisfy 190 | simultaneously your obligations under this License and any other pertinent 191 | obligations, then as a consequence you may not distribute the Program at all. 192 | For example, if a patent license would not permit royalty-free redistribution 193 | of the Program by all those who receive copies directly or indirectly through 194 | you, then the only way you could satisfy both it and this License would be to 195 | refrain entirely from distribution of the Program. 196 | 197 | If any portion of this section is held invalid or unenforceable under any 198 | particular circumstance, the balance of the section is intended to apply and 199 | the section as a whole is intended to apply in other circumstances. 200 | 201 | It is not the purpose of this section to induce you to infringe any patents or 202 | other property right claims or to contest validity of any such claims; this 203 | section has the sole purpose of protecting the integrity of the free software 204 | distribution system, which is implemented by public license practices. Many 205 | people have made generous contributions to the wide range of software 206 | distributed through that system in reliance on consistent application of that 207 | system; it is up to the author/donor to decide if he or she is willing to 208 | distribute software through any other system and a licensee cannot impose that 209 | choice. 210 | 211 | This section is intended to make thoroughly clear what is believed to be a 212 | consequence of the rest of this License. 213 | 214 | 8. If the distribution and/or use of the Program is restricted in certain 215 | countries either by patents or by copyrighted interfaces, the original 216 | copyright holder who places the Program under this License may add an explicit 217 | geographical distribution limitation excluding those countries, so that 218 | distribution is permitted only in or among countries not thus excluded. In 219 | such case, this License incorporates the limitation as if written in the body 220 | of this License. 221 | 222 | 9. The Free Software Foundation may publish revised and/or new versions of the 223 | General Public License from time to time. Such new versions will be similar in 224 | spirit to the present version, but may differ in detail to address new problems 225 | or concerns. 226 | 227 | Each version is given a distinguishing version number. If the Program 228 | specifies a version number of this License which applies to it and "any later 229 | version", you have the option of following the terms and conditions either of 230 | that version or of any later version published by the Free Software Foundation. 231 | If the Program does not specify a version number of this License, you may 232 | choose any version ever published by the Free Software Foundation. 233 | 234 | 10. If you wish to incorporate parts of the Program into other free programs 235 | whose distribution conditions are different, write to the author to ask for 236 | permission. For software which is copyrighted by the Free Software Foundation, 237 | write to the Free Software Foundation; we sometimes make exceptions for this. 238 | Our decision will be guided by the two goals of preserving the free status of 239 | all derivatives of our free software and of promoting the sharing and reuse of 240 | software generally. 241 | 242 | NO WARRANTY 243 | 244 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR 245 | THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE 246 | STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE 247 | PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, 248 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 249 | FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND 250 | PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, 251 | YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 252 | 253 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL 254 | ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE 255 | PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 256 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR 257 | INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA 258 | BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 259 | FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER 260 | OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 261 | 262 | END OF TERMS AND CONDITIONS 263 | 264 | How to Apply These Terms to Your New Programs 265 | 266 | If you develop a new program, and you want it to be of the greatest possible 267 | use to the public, the best way to achieve this is to make it free software 268 | which everyone can redistribute and change under these terms. 269 | 270 | To do so, attach the following notices to the program. It is safest to attach 271 | them to the start of each source file to most effectively convey the exclusion 272 | of warranty; and each file should have at least the "copyright" line and a 273 | pointer to where the full notice is found. 274 | 275 | One line to give the program's name and a brief idea of what it does. 276 | 277 | Copyright (C) 278 | 279 | This program is free software; you can redistribute it and/or modify it 280 | under the terms of the GNU General Public License as published by the Free 281 | Software Foundation; either version 2 of the License, or (at your option) 282 | any later version. 283 | 284 | This program is distributed in the hope that it will be useful, but WITHOUT 285 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 286 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 287 | more details. 288 | 289 | You should have received a copy of the GNU General Public License along 290 | with this program; if not, write to the Free Software Foundation, Inc., 59 291 | Temple Place, Suite 330, Boston, MA 02111-1307 USA 292 | 293 | Also add information on how to contact you by electronic and paper mail. 294 | 295 | If the program is interactive, make it output a short notice like this when it 296 | starts in an interactive mode: 297 | 298 | Gnomovision version 69, Copyright (C) year name of author Gnomovision comes 299 | with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free 300 | software, and you are welcome to redistribute it under certain conditions; 301 | type 'show c' for details. 302 | 303 | The hypothetical commands 'show w' and 'show c' should show the appropriate 304 | parts of the General Public License. Of course, the commands you use may be 305 | called something other than 'show w' and 'show c'; they could even be 306 | mouse-clicks or menu items--whatever suits your program. 307 | 308 | You should also get your employer (if you work as a programmer) or your school, 309 | if any, to sign a "copyright disclaimer" for the program, if necessary. Here 310 | is a sample; alter the names: 311 | 312 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 313 | 'Gnomovision' (which makes passes at compilers) written by James Hacker. 314 | 315 | signature of Ty Coon, 1 April 1989 316 | 317 | Ty Coon, President of Vice 318 | 319 | This General Public License does not permit incorporating your program into 320 | proprietary programs. If your program is a subroutine library, you may 321 | consider it more useful to permit linking proprietary applications with the 322 | library. If this is what you want to do, use the GNU Library General Public 323 | License instead of this License. 324 | 325 | 326 | "CLASSPATH" EXCEPTION TO THE GPL 327 | 328 | Certain source files distributed by Oracle America and/or its affiliates are 329 | subject to the following clarification and special exception to the GPL, but 330 | only where Oracle has expressly included in the particular source file's header 331 | the words "Oracle designates this particular file as subject to the "Classpath" 332 | exception as provided by Oracle in the LICENSE file that accompanied this code." 333 | 334 | Linking this library statically or dynamically with other modules is making 335 | a combined work based on this library. Thus, the terms and conditions of 336 | the GNU General Public License cover the whole combination. 337 | 338 | As a special exception, the copyright holders of this library give you 339 | permission to link this library with independent modules to produce an 340 | executable, regardless of the license terms of these independent modules, 341 | and to copy and distribute the resulting executable under terms of your 342 | choice, provided that you also meet, for each linked independent module, 343 | the terms and conditions of the license of that module. An independent 344 | module is a module which is not derived from or based on this library. If 345 | you modify this library, you may extend this exception to your version of 346 | the library, but you are not obligated to do so. If you do not wish to do 347 | so, delete this exception statement from your version. 348 | -------------------------------------------------------------------------------- /third_party/openjdk/METADATA: -------------------------------------------------------------------------------- 1 | name: "OpenJDK" 2 | description: 3 | "OpenJDK (Open Java Development Kit) is a free and open source " 4 | "implementation of the Java Platform, Standard Edition (Java SE)." 5 | 6 | third_party { 7 | url { 8 | type: HOMEPAGE 9 | value: "http://openjdk.java.net/" 10 | } 11 | url { 12 | type: ARCHIVE 13 | value: "http://www.java.net/download/openjdk/jdk8/promoted/b132/openjdk-8-src-b132-03_mar_2014.zip" 14 | } 15 | version: "b132" 16 | last_upgrade_date { year: 2017 month: 03 day: 31 } 17 | local_modifications: 18 | "- Only certain files relevant to Streams have been retained.\n" 19 | "- The files have been significantly changed to adapt them to a templating " 20 | " engine and allow them to throw checked exceptions." 21 | } 22 | -------------------------------------------------------------------------------- /third_party/openjdk/common/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'maven-publish' 3 | 4 | sourceSets { 5 | main { 6 | java.srcDir file('src/main/generated') 7 | } 8 | } 9 | 10 | sourceCompatibility = 1.6 11 | targetCompatibility = 1.6 12 | 13 | task srcJar(type: Jar, dependsOn: classes) { 14 | classifier = 'src' 15 | from sourceSets.main.allSource 16 | } 17 | 18 | task javadocJar(type: Jar, dependsOn: javadoc) { 19 | classifier = 'javadoc' 20 | from javadoc.destinationDir 21 | } 22 | 23 | artifacts { 24 | archives srcJar 25 | archives javadocJar 26 | } 27 | 28 | publishing { 29 | publications { 30 | maven(MavenPublication) { 31 | groupId 'com.google.chkstream' 32 | artifactId 'chkstream-common' 33 | version '1.0.0-SNAPSHOT' 34 | 35 | from components.java 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /third_party/openjdk/common/src/main/java/com/google/chkstream/ChkStreamWrappedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google. 3 | * 4 | * This file is licensed under the GPLv2+Classpath Exception, which full text 5 | * is found in the LICENSE file at the root of this project. 6 | * 7 | * Google designates this particular file as subject to the "Classpath" 8 | * exception as provided in the LICENSE file that accompanied this code. 9 | */ 10 | package com.google.chkstream; 11 | 12 | /** 13 | * A {@link RuntimeException} that wraps another {@link Exception} type. 14 | * 15 | *

This wrapper is transparently handled by the {@link ChkStream} 16 | * infrastructure. You should not be seeing it thrown out of @{link ChkStream} 17 | * methods, unless you call {@link ChkStream#toStream()} to get the underlying 18 | * raw {@link Stream} from a {@link ChkStream}. 19 | * 20 | * @author Alexander Dorokhine 21 | */ 22 | public class ChkStreamWrappedException extends RuntimeException { 23 | private static final long serialVersionUID = 1L; 24 | public ChkStreamWrappedException(Exception e) { 25 | super(e); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /third_party/openjdk/java8/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'maven-publish' 3 | 4 | sourceSets { 5 | main { 6 | java.srcDir file('src/main/generated') 7 | } 8 | } 9 | 10 | sourceCompatibility = 1.8 11 | targetCompatibility = 1.8 12 | 13 | dependencies { 14 | api project(':third_party:openjdk:common') 15 | 16 | testImplementation group: 'com.google.truth', name: 'truth', version: '0.32' 17 | testImplementation group: 'junit', name: 'junit', version: '4.11' 18 | } 19 | 20 | task srcJar(type: Jar, dependsOn: classes) { 21 | classifier = 'src' 22 | from sourceSets.main.allSource 23 | } 24 | 25 | task javadocJar(type: Jar, dependsOn: javadoc) { 26 | classifier = 'javadoc' 27 | from javadoc.destinationDir 28 | } 29 | 30 | artifacts { 31 | archives srcJar 32 | archives javadocJar 33 | } 34 | 35 | publishing { 36 | publications { 37 | maven(MavenPublication) { 38 | groupId 'com.google.chkstream' 39 | artifactId 'chkstream-java8' 40 | version '1.0.0-SNAPSHOT' 41 | 42 | from components.java 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /third_party/openjdk/java8/src/test/java/com/google/chkstream/ChkStreamFunctionalTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google. 3 | * 4 | * This file is licensed under the GPLv2+Classpath Exception, which full text 5 | * is found in the LICENSE file at the root of this project. 6 | * 7 | * Google designates this particular file as subject to the "Classpath" 8 | * exception as provided in the LICENSE file that accompanied this code. 9 | */ 10 | package com.google.chkstream; 11 | 12 | import static com.google.common.truth.Truth.assertThat; 13 | import static org.junit.Assert.*; 14 | 15 | import java.io.IOException; 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | import java.util.stream.Collectors; 19 | import java.util.stream.IntStream; 20 | import java.util.stream.Stream; 21 | 22 | import org.junit.Test; 23 | 24 | import com.google.chkstream.java8.ChkStream; 25 | import com.google.chkstream.java8.ChkStreams; 26 | 27 | /** Tests for the streaming functionality (maps and transforms) of ChkStream. */ 28 | public class ChkStreamFunctionalTest { 29 | 30 | // Tests for transforms (non-sinks) 31 | 32 | @Test 33 | public void testMap() { 34 | assertThat( 35 | wrap(Stream.of(1, 2, 3)) 36 | .map(x -> x * 10) 37 | .collect(Collectors.toList())) 38 | .containsExactly(10, 20, 30).inOrder(); 39 | } 40 | 41 | @Test 42 | public void testFlatMap_Stream() throws IOException { 43 | List results = 44 | ChkStreams.of(Stream.of(1, 2, 3)) 45 | .canThrow(IOException.class) 46 | .flatMap(x -> Stream.of("yay " + x, "ok " + x, "nay " + x)) 47 | .collect(Collectors.toList()); 48 | assertThat(results).containsExactly( 49 | "yay 1", "ok 1", "nay 1", 50 | "yay 2", "ok 2", "nay 2", 51 | "yay 3", "ok 3", "nay 3").inOrder(); 52 | } 53 | 54 | @Test 55 | public void testFlatMap_SameChkStream() throws IOException { 56 | List results = 57 | ChkStreams.of(Stream.of(1, 2, 3)) 58 | .canThrow(IOException.class) 59 | .flatMapChk( 60 | x -> 61 | ChkStreams.of(Stream.of("yay " + x, "ok " + x, "nay " + x)) 62 | .canThrow(IOException.class) 63 | ).collect(Collectors.toList()); 64 | assertThat(results).containsExactly( 65 | "yay 1", "ok 1", "nay 1", 66 | "yay 2", "ok 2", "nay 2", 67 | "yay 3", "ok 3", "nay 3").inOrder(); 68 | } 69 | 70 | @Test 71 | public void testFilter() { 72 | assertThat( 73 | wrap(Stream.of(1, 2, 3, 4)) 74 | .filter(x -> x % 2 == 0) 75 | .collect(Collectors.toList()) 76 | ).containsExactly(2, 4).inOrder(); 77 | } 78 | 79 | @Test 80 | public void testConcatSameType() throws IOException { 81 | ChkStream stream = 82 | wrap(Stream.of(1, 2, 3)) 83 | .map(x -> x + 10) 84 | .concat(wrap(Stream.of(4, 5, 6)).map(x -> x + 20)); 85 | List results = stream.collect(Collectors.toList()); 86 | assertThat(results).containsExactly(11, 12, 13, 24, 25, 26).inOrder(); 87 | } 88 | 89 | @Test 90 | public void testConcatSafeType() throws IOException { 91 | ChkStream stream = 92 | wrap(Stream.of(1, 2, 3)) 93 | .map(x -> x + 10) 94 | .concat(Stream.of(4, 5, 6).map(x -> x + 20)); 95 | List results = stream.collect(Collectors.toList()); 96 | assertThat(results).containsExactly(11, 12, 13, 24, 25, 26).inOrder(); 97 | } 98 | 99 | @Test 100 | public void testSort() { 101 | assertThat( 102 | wrap(Stream.of(50, 20, 100, 75)) 103 | .sorted() 104 | .collect(Collectors.toList()) 105 | ).containsExactly(20, 50, 75, 100).inOrder(); 106 | } 107 | 108 | @Test 109 | public void testSortWithComparator() { 110 | assertThat( 111 | wrap(Stream.of(50, 20, 100, 75)) 112 | .sorted((a, b) -> b - a) 113 | .collect(Collectors.toList()) 114 | ).containsExactly(100, 75, 50, 20).inOrder(); 115 | } 116 | 117 | @Test 118 | public void testSortNonComparable() { 119 | ChkStream stream = 120 | wrap(Stream.of(new IOException("x"), new IOException("y"))) 121 | .sorted(); 122 | try { 123 | stream.collect(Collectors.toList()); 124 | fail(); 125 | } catch (ClassCastException e) {} 126 | } 127 | 128 | // Tests for sinks 129 | 130 | @Test 131 | public void testForEach() { 132 | List list = new ArrayList<>(); 133 | wrap(Stream.of(1, 2, 3, 4)).forEach(x -> list.add(x)); 134 | assertThat(list).containsExactly(1, 2, 3, 4).inOrder(); 135 | } 136 | 137 | 138 | @Test 139 | public void testCount() { 140 | assertEquals(4, wrap(Stream.of(1, 2, 3, 4)).count()); 141 | } 142 | 143 | @Test 144 | public void testMin() { 145 | assertThat( 146 | wrap(Stream.of(50, 20, 100, 75)).min(Integer::compareTo).get() 147 | ).isEqualTo(20); 148 | } 149 | 150 | @Test 151 | public void testMinEmpty() { 152 | assertThat( 153 | wrap(Stream.empty()) 154 | .min(Integer::compareTo) 155 | .isPresent() 156 | ).isFalse(); 157 | } 158 | 159 | @Test 160 | public void testMax() { 161 | assertThat( 162 | wrap(Stream.of(50, 20, 100, 75)).max(Integer::compareTo).get() 163 | ).isEqualTo(100); 164 | } 165 | 166 | @Test 167 | public void testMaxEmpty() { 168 | assertThat( 169 | wrap(Stream.empty()).max(Integer::compareTo).isPresent() 170 | ).isFalse(); 171 | } 172 | 173 | @Test 174 | public void testAllMatch() { 175 | assertThat( 176 | wrap(Stream.of(1, 2, 3)).allMatch(x -> x <= 3)).isTrue(); 177 | assertThat( 178 | wrap(Stream.of(1, 2, 3)).allMatch(x -> x <= 2)).isFalse(); 179 | 180 | // Make sure it short circuits 181 | assertThat( 182 | wrap(Stream.of(1, 4, 3)) 183 | .filter(x -> { 184 | // Make sure it never sees this line due to short circuit 185 | assertThat(x).isNotEqualTo(3); 186 | return true; 187 | }) 188 | .allMatch(x -> x <= 3)).isFalse(); 189 | 190 | // Vacuously true 191 | assertThat(wrap(Stream.empty()).allMatch(x -> false)).isTrue(); 192 | } 193 | 194 | @Test 195 | public void testAnyMatch() { 196 | assertThat( 197 | wrap(Stream.of(1, 2, 3)).anyMatch(x -> x <= 3)).isTrue(); 198 | assertThat( 199 | wrap(Stream.of(1, 2, 3)).anyMatch(x -> x <= 0)).isFalse(); 200 | 201 | // Make sure it short circuits 202 | assertThat( 203 | wrap(Stream.of(1, 4, 3)) 204 | .filter(x -> { 205 | // Make sure it never sees this line due to short circuit 206 | assertThat(x).isNotEqualTo(3); 207 | return true; 208 | }) 209 | .anyMatch(x -> x == 4)).isTrue(); 210 | 211 | // Vacuously false 212 | assertThat(wrap(Stream.empty()).anyMatch(x -> false)).isFalse(); 213 | } 214 | 215 | @Test 216 | public void testNoneMatch() { 217 | assertThat( 218 | wrap(Stream.of(1, 2, 3)).noneMatch(x -> x <= 0)).isTrue(); 219 | assertThat( 220 | wrap(Stream.of(1, 2, 3)).noneMatch(x -> x <= 3)).isFalse(); 221 | 222 | // Make sure it short circuits 223 | assertThat( 224 | wrap(Stream.of(1, 4, 3)) 225 | .filter(x -> { 226 | // Make sure it never sees this line due to short circuit 227 | assertThat(x).isNotEqualTo(3); 228 | return true; 229 | }) 230 | .noneMatch(x -> x == 4)).isFalse(); 231 | 232 | // Vacuously true 233 | assertThat(wrap(Stream.empty()).noneMatch(x -> false)).isTrue(); 234 | } 235 | 236 | @Test 237 | public void testConcat() { 238 | ChkStream a = 239 | wrap(Stream.of(1, 2, 3)).map(x -> x * 10); 240 | ChkStream b = 241 | wrap(Stream.of(4, 5, 6)).map(x -> x * 100); 242 | assertThat(a.concat(b).collect(Collectors.toList())) 243 | .containsExactly(10, 20, 30, 400, 500, 600).inOrder(); 244 | } 245 | 246 | @Test 247 | public void testPrimitive() throws IOException { 248 | double avg = ChkStreams.ofInt(IntStream.range(5, 10)) 249 | .canThrow(IOException.class) 250 | .average().getAsDouble(); 251 | assertThat(avg).isWithin(0.01).of(7); 252 | } 253 | 254 | private static ChkStream wrap(Stream stream) { 255 | return ChkStreams.of(stream).canThrow(RuntimeException.class); 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /third_party/openjdk/java8/src/test/java/com/google/chkstream/ChkStreamThrowTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google. 3 | * 4 | * This file is licensed under the GPLv2+Classpath Exception, which full text 5 | * is found in the LICENSE file at the root of this project. 6 | * 7 | * Google designates this particular file as subject to the "Classpath" 8 | * exception as provided in the LICENSE file that accompanied this code. 9 | */ 10 | package com.google.chkstream; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | import java.io.FileNotFoundException; 15 | import java.io.IOException; 16 | import java.util.stream.Stream; 17 | 18 | import org.junit.Test; 19 | 20 | import com.google.chkstream.function.ChkFunctions.ChkFunction; 21 | import com.google.chkstream.java8.ChkStream_Throw2; 22 | import com.google.chkstream.java8.ChkStreams; 23 | 24 | public class ChkStreamThrowTest { 25 | @Test 26 | public void testCanThrow1() { 27 | try { 28 | ChkStreams.of(Stream.of(1)).canThrow(IOException.class).map(x -> { 29 | throw new IOException("Simulated error: " + x); 30 | }).toArray(); 31 | fail(); 32 | } catch (IOException e) { 33 | assertEquals("Simulated error: 1", e.getMessage()); 34 | } 35 | } 36 | 37 | @Test 38 | public void testCanThrow2() { 39 | try { 40 | ChkStreams.of(Stream.of(1)) 41 | .canThrow(IOException.class) 42 | .canThrow(InterruptedException.class) 43 | .map(x -> { 44 | if (x == 1) { 45 | throw new InterruptedException( 46 | "Simulated interrupt error: " + x); 47 | } else { 48 | throw new IOException( 49 | "Simulated io error: " + x); 50 | } 51 | }).toArray(); 52 | fail(); 53 | } catch (InterruptedException e) { 54 | assertEquals("Simulated interrupt error: 1", e.getMessage()); 55 | } catch (IOException e) { 56 | fail(); 57 | } 58 | } 59 | 60 | @Test 61 | public void testConcatAndThrow() throws Exception { 62 | ChkStream_Throw2 a = 63 | ChkStreams.of(Stream.of(1, 2)) 64 | .canThrow(IOException.class) 65 | .canThrow(InterruptedException.class); 66 | ChkStream_Throw2 b = 67 | ChkStreams.of(Stream.of(10, 20)) 68 | .canThrow(IOException.class) 69 | .canThrow(InterruptedException.class); 70 | ChkStream_Throw2 concat = 71 | a.concat(b); 72 | concat = concat.map( 73 | x -> { throw new InterruptedException("e"); }); 74 | try { 75 | concat.toArray(); 76 | fail(); 77 | } catch (InterruptedException e) {} 78 | } 79 | 80 | @Test 81 | public void testCanThrowDerived() throws IOException { 82 | try { 83 | ChkStreams.of(Stream.of(1)).canThrow(IOException.class).map( 84 | new ChkFunction() { 85 | @Override 86 | public Void apply(Integer t) throws FileNotFoundException { 87 | throw new FileNotFoundException( 88 | "Simulated error: " + t); 89 | } 90 | }).toArray(); 91 | fail(); 92 | } catch (FileNotFoundException e) { 93 | assertEquals("Simulated error: 1", e.getMessage()); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /third_party/openjdk/streamsupport/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | } 5 | 6 | dependencies { 7 | classpath 'me.tatarka:gradle-retrolambda:3.5.0' 8 | } 9 | } 10 | 11 | apply plugin: 'java-library' 12 | apply plugin: 'maven-publish' 13 | 14 | sourceSets { 15 | main { 16 | java.srcDir file('src/main/generated') 17 | } 18 | } 19 | 20 | testClasses { 21 | apply plugin: 'me.tatarka.retrolambda' 22 | } 23 | 24 | compileJava { 25 | sourceCompatibility = 1.6 26 | targetCompatibility = 1.6 27 | } 28 | 29 | compileTestJava { 30 | sourceCompatibility = 1.8 31 | targetCompatibility = 1.8 32 | } 33 | 34 | dependencies { 35 | api project(':third_party:openjdk:common') 36 | api group: 'net.sourceforge.streamsupport', name: 'streamsupport', version: '1.5.4' 37 | 38 | testImplementation group: 'com.google.truth', name: 'truth', version: '0.32' 39 | testImplementation group: 'junit', name: 'junit', version: '4.11' 40 | } 41 | 42 | task srcJar(type: Jar, dependsOn: classes) { 43 | classifier = 'src' 44 | from sourceSets.main.allSource 45 | } 46 | 47 | task javadocJar(type: Jar, dependsOn: javadoc) { 48 | classifier = 'javadoc' 49 | from javadoc.destinationDir 50 | } 51 | 52 | artifacts { 53 | archives srcJar 54 | archives javadocJar 55 | } 56 | 57 | publishing { 58 | publications { 59 | maven(MavenPublication) { 60 | groupId 'com.google.chkstream' 61 | artifactId 'chkstream-streamsupport' 62 | version '1.0.0-SNAPSHOT' 63 | 64 | from components.java 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /third_party/openjdk/streamsupport/src/main/java/com/google/chkstream/lang/AutoCloseable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | package com.google.chkstream.lang; 27 | 28 | /** 29 | * An object that may hold resources (such as file or socket handles) 30 | * until it is closed. The {@link #close()} method of an {@code AutoCloseable} 31 | * object is called automatically when exiting a {@code 32 | * try}-with-resources block for which the object has been declared in 33 | * the resource specification header. This construction ensures prompt 34 | * release, avoiding resource exhaustion exceptions and errors that 35 | * may otherwise occur. 36 | * 37 | * @apiNote 38 | *

It is possible, and in fact common, for a base class to 39 | * implement AutoCloseable even though not all of its subclasses or 40 | * instances will hold releasable resources. For code that must operate 41 | * in complete generality, or when it is known that the {@code AutoCloseable} 42 | * instance requires resource release, it is recommended to use {@code 43 | * try}-with-resources constructions. However, when using facilities such as 44 | * {@link java.util.stream.Stream} that support both I/O-based and 45 | * non-I/O-based forms, {@code try}-with-resources blocks are in 46 | * general unnecessary when using non-I/O-based forms. 47 | * 48 | * @author Josh Bloch 49 | * @since 1.7 50 | */ 51 | public interface AutoCloseable { 52 | /** 53 | * Closes this resource, relinquishing any underlying resources. 54 | * This method is invoked automatically on objects managed by the 55 | * {@code try}-with-resources statement. 56 | * 57 | *

While this interface method is declared to throw {@code 58 | * Exception}, implementers are strongly encouraged to 59 | * declare concrete implementations of the {@code close} method to 60 | * throw more specific exceptions, or to throw no exception at all 61 | * if the close operation cannot fail. 62 | * 63 | *

Cases where the close operation may fail require careful 64 | * attention by implementers. It is strongly advised to relinquish 65 | * the underlying resources and to internally mark the 66 | * resource as closed, prior to throwing the exception. The {@code 67 | * close} method is unlikely to be invoked more than once and so 68 | * this ensures that the resources are released in a timely manner. 69 | * Furthermore it reduces problems that could arise when the resource 70 | * wraps, or is wrapped, by another resource. 71 | * 72 | *

Implementers of this interface are also strongly advised 73 | * to not have the {@code close} method throw {@link 74 | * InterruptedException}. 75 | * 76 | * This exception interacts with a thread's interrupted status, 77 | * and runtime misbehavior is likely to occur if an {@code 78 | * InterruptedException} is {@linkplain Throwable#addSuppressed 79 | * suppressed}. 80 | * 81 | * More generally, if it would cause problems for an 82 | * exception to be suppressed, the {@code AutoCloseable.close} 83 | * method should not throw it. 84 | * 85 | *

Note that unlike the {@link java.io.Closeable#close close} 86 | * method of {@link java.io.Closeable}, this {@code close} method 87 | * is not required to be idempotent. In other words, 88 | * calling this {@code close} method more than once may have some 89 | * visible side effect, unlike {@code Closeable.close} which is 90 | * required to have no effect if called more than once. 91 | * 92 | * However, implementers of this interface are strongly encouraged 93 | * to make their {@code close} methods idempotent. 94 | * 95 | * @throws Exception if this resource cannot be closed 96 | */ 97 | void close() throws Exception; 98 | } 99 | -------------------------------------------------------------------------------- /third_party/openjdk/streamsupport/src/test/java/com/google/chkstream/ChkStreamFunctionalTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google. 3 | * 4 | * This file is licensed under the GPLv2+Classpath Exception, which full text 5 | * is found in the LICENSE file at the root of this project. 6 | * 7 | * Google designates this particular file as subject to the "Classpath" 8 | * exception as provided in the LICENSE file that accompanied this code. 9 | */ 10 | package com.google.chkstream; 11 | 12 | import static com.google.common.truth.Truth.assertThat; 13 | import static org.junit.Assert.*; 14 | 15 | import java.io.IOException; 16 | import java.sql.SQLException; 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | import org.junit.Test; 21 | 22 | import com.google.chkstream.streamsupport.ChkStream; 23 | import com.google.chkstream.streamsupport.ChkStreams; 24 | 25 | import java8.util.stream.Collectors; 26 | import java8.util.stream.IntStreams; 27 | import java8.util.stream.RefStreams; 28 | import java8.util.stream.Stream; 29 | 30 | /** Tests for the streaming functionality (maps and transforms) of ChkStream. */ 31 | public class ChkStreamFunctionalTest { 32 | 33 | // Tests for transforms (non-sinks) 34 | 35 | @Test 36 | public void testMap() { 37 | assertThat( 38 | wrap(RefStreams.of(1, 2, 3)) 39 | .map(x -> x * 10) 40 | .collect(Collectors.toList())) 41 | .containsExactly(10, 20, 30).inOrder(); 42 | } 43 | 44 | @Test 45 | public void testFlatMap_Stream() throws IOException { 46 | List results = 47 | ChkStreams.of(RefStreams.of(1, 2, 3)) 48 | .canThrow(IOException.class) 49 | .flatMap(x -> RefStreams.of("yay " + x, "ok " + x, "nay " + x)) 50 | .collect(Collectors.toList()); 51 | assertThat(results).containsExactly( 52 | "yay 1", "ok 1", "nay 1", 53 | "yay 2", "ok 2", "nay 2", 54 | "yay 3", "ok 3", "nay 3").inOrder(); 55 | } 56 | 57 | @Test 58 | public void testFlatMap_SameChkStream() throws IOException { 59 | List results = 60 | ChkStreams.of(RefStreams.of(1, 2, 3)) 61 | .canThrow(IOException.class) 62 | .flatMapChk( 63 | x -> 64 | ChkStreams.of(RefStreams.of("yay " + x, "ok " + x, "nay " + x)) 65 | .canThrow(IOException.class) 66 | ).collect(Collectors.toList()); 67 | assertThat(results).containsExactly( 68 | "yay 1", "ok 1", "nay 1", 69 | "yay 2", "ok 2", "nay 2", 70 | "yay 3", "ok 3", "nay 3").inOrder(); 71 | } 72 | 73 | @Test 74 | public void testFilter() { 75 | assertThat( 76 | wrap(RefStreams.of(1, 2, 3, 4)) 77 | .filter(x -> x % 2 == 0) 78 | .collect(Collectors.toList()) 79 | ).containsExactly(2, 4).inOrder(); 80 | } 81 | 82 | @Test 83 | public void testConcatSameType() throws IOException { 84 | ChkStream stream = 85 | wrap(RefStreams.of(1, 2, 3)) 86 | .map(x -> x + 10) 87 | .concat(wrap(RefStreams.of(4, 5, 6)).map(x -> x + 20)); 88 | List results = stream.collect(Collectors.toList()); 89 | assertThat(results).containsExactly(11, 12, 13, 24, 25, 26).inOrder(); 90 | } 91 | 92 | @Test 93 | public void testConcatSafeType() throws IOException { 94 | ChkStream stream = 95 | wrap(RefStreams.of(1, 2, 3)) 96 | .map(x -> x + 10) 97 | .concat(RefStreams.of(4, 5, 6).map(x -> x + 20)); 98 | List results = stream.collect(Collectors.toList()); 99 | assertThat(results).containsExactly(11, 12, 13, 24, 25, 26).inOrder(); 100 | } 101 | 102 | @Test 103 | public void testSort() { 104 | assertThat( 105 | wrap(RefStreams.of(50, 20, 100, 75)) 106 | .sorted() 107 | .collect(Collectors.toList()) 108 | ).containsExactly(20, 50, 75, 100).inOrder(); 109 | } 110 | 111 | @Test 112 | public void testSortWithComparator() { 113 | assertThat( 114 | wrap(RefStreams.of(50, 20, 100, 75)) 115 | .sorted((a, b) -> b - a) 116 | .collect(Collectors.toList()) 117 | ).containsExactly(100, 75, 50, 20).inOrder(); 118 | } 119 | 120 | @Test 121 | public void testSortNonComparable() { 122 | ChkStream stream = 123 | wrap(RefStreams.of(new IOException("x"), new IOException("y"))) 124 | .sorted(); 125 | try { 126 | stream.collect(Collectors.toList()); 127 | fail(); 128 | } catch (ClassCastException e) {} 129 | } 130 | 131 | // Tests for sinks 132 | 133 | @Test 134 | public void testForEach() { 135 | List list = new ArrayList<>(); 136 | wrap(RefStreams.of(1, 2, 3, 4)).forEach(x -> list.add(x)); 137 | assertThat(list).containsExactly(1, 2, 3, 4).inOrder(); 138 | } 139 | 140 | 141 | @Test 142 | public void testCount() { 143 | assertEquals(4, wrap(RefStreams.of(1, 2, 3, 4)).count()); 144 | } 145 | 146 | @Test 147 | public void testMin() { 148 | assertThat( 149 | wrap(RefStreams.of(50, 20, 100, 75)).min(Integer::compareTo).get() 150 | ).isEqualTo(20); 151 | } 152 | 153 | @Test 154 | public void testMinEmpty() { 155 | assertThat( 156 | wrap(RefStreams.empty()) 157 | .min(Integer::compareTo) 158 | .isPresent() 159 | ).isFalse(); 160 | } 161 | 162 | @Test 163 | public void testMax() { 164 | assertThat( 165 | wrap(RefStreams.of(50, 20, 100, 75)).max(Integer::compareTo).get() 166 | ).isEqualTo(100); 167 | } 168 | 169 | @Test 170 | public void testMaxEmpty() { 171 | assertThat( 172 | wrap(RefStreams.empty()).max(Integer::compareTo).isPresent() 173 | ).isFalse(); 174 | } 175 | 176 | @Test 177 | public void testAllMatch() { 178 | assertThat( 179 | wrap(RefStreams.of(1, 2, 3)).allMatch(x -> x <= 3)).isTrue(); 180 | assertThat( 181 | wrap(RefStreams.of(1, 2, 3)).allMatch(x -> x <= 2)).isFalse(); 182 | 183 | // Make sure it short circuits 184 | assertThat( 185 | wrap(RefStreams.of(1, 4, 3)) 186 | .filter(x -> { 187 | // Make sure it never sees this line due to short circuit 188 | assertThat(x).isNotEqualTo(3); 189 | return true; 190 | }) 191 | .allMatch(x -> x <= 3)).isFalse(); 192 | 193 | // Vacuously true 194 | assertThat(wrap(RefStreams.empty()).allMatch(x -> false)).isTrue(); 195 | } 196 | 197 | @Test 198 | public void testAnyMatch() { 199 | assertThat( 200 | wrap(RefStreams.of(1, 2, 3)).anyMatch(x -> x <= 3)).isTrue(); 201 | assertThat( 202 | wrap(RefStreams.of(1, 2, 3)).anyMatch(x -> x <= 0)).isFalse(); 203 | 204 | // Make sure it short circuits 205 | assertThat( 206 | wrap(RefStreams.of(1, 4, 3)) 207 | .filter(x -> { 208 | // Make sure it never sees this line due to short circuit 209 | assertThat(x).isNotEqualTo(3); 210 | return true; 211 | }) 212 | .anyMatch(x -> x == 4)).isTrue(); 213 | 214 | // Vacuously false 215 | assertThat(wrap(RefStreams.empty()).anyMatch(x -> false)).isFalse(); 216 | } 217 | 218 | @Test 219 | public void testNoneMatch() { 220 | assertThat( 221 | wrap(RefStreams.of(1, 2, 3)).noneMatch(x -> x <= 0)).isTrue(); 222 | assertThat( 223 | wrap(RefStreams.of(1, 2, 3)).noneMatch(x -> x <= 3)).isFalse(); 224 | 225 | // Make sure it short circuits 226 | assertThat( 227 | wrap(RefStreams.of(1, 4, 3)) 228 | .filter(x -> { 229 | // Make sure it never sees this line due to short circuit 230 | assertThat(x).isNotEqualTo(3); 231 | return true; 232 | }) 233 | .noneMatch(x -> x == 4)).isFalse(); 234 | 235 | // Vacuously true 236 | assertThat(wrap(RefStreams.empty()).noneMatch(x -> false)).isTrue(); 237 | } 238 | 239 | @Test 240 | public void testConcat() { 241 | ChkStream a = 242 | wrap(RefStreams.of(1, 2, 3)).map(x -> x * 10); 243 | ChkStream b = 244 | wrap(RefStreams.of(4, 5, 6)).map(x -> x * 100); 245 | assertThat(a.concat(b).collect(Collectors.toList())) 246 | .containsExactly(10, 20, 30, 400, 500, 600).inOrder(); 247 | } 248 | 249 | @Test 250 | public void testPrimitive() throws IOException, SQLException { 251 | double avg = ChkStreams.ofInt(IntStreams.range(5, 10)) 252 | .canThrow(IOException.class) 253 | .average().getAsDouble(); 254 | assertThat(avg).isWithin(0.01).of(7); 255 | } 256 | 257 | private static ChkStream wrap(Stream stream) { 258 | return ChkStreams.of(stream).canThrow(RuntimeException.class); 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /third_party/openjdk/streamsupport/src/test/java/com/google/chkstream/ChkStreamThrowTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google. 3 | * 4 | * This file is licensed under the GPLv2+Classpath Exception, which full text 5 | * is found in the LICENSE file at the root of this project. 6 | * 7 | * Google designates this particular file as subject to the "Classpath" 8 | * exception as provided in the LICENSE file that accompanied this code. 9 | */ 10 | package com.google.chkstream; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | import java.io.FileNotFoundException; 15 | import java.io.IOException; 16 | 17 | import org.junit.Test; 18 | 19 | import com.google.chkstream.function.ChkFunctions.ChkFunction; 20 | import com.google.chkstream.streamsupport.ChkStream_Throw2; 21 | import com.google.chkstream.streamsupport.ChkStreams; 22 | 23 | import java8.util.stream.RefStreams; 24 | 25 | public class ChkStreamThrowTest { 26 | @Test 27 | public void testCanThrow1() { 28 | try { 29 | ChkStreams.of(RefStreams.of(1)).canThrow(IOException.class).map(x -> { 30 | throw new IOException("Simulated error: " + x); 31 | }).toArray(); 32 | fail(); 33 | } catch (IOException e) { 34 | assertEquals("Simulated error: 1", e.getMessage()); 35 | } 36 | } 37 | 38 | @Test 39 | public void testCanThrow2() { 40 | try { 41 | ChkStreams.of(RefStreams.of(1)) 42 | .canThrow(IOException.class) 43 | .canThrow(InterruptedException.class) 44 | .map(x -> { 45 | if (x == 1) { 46 | throw new InterruptedException( 47 | "Simulated interrupt error: " + x); 48 | } else { 49 | throw new IOException( 50 | "Simulated io error: " + x); 51 | } 52 | }).toArray(); 53 | fail(); 54 | } catch (InterruptedException e) { 55 | assertEquals("Simulated interrupt error: 1", e.getMessage()); 56 | } catch (IOException e) { 57 | fail(); 58 | } 59 | } 60 | 61 | @Test 62 | public void testConcatAndThrow() throws Exception { 63 | ChkStream_Throw2 a = 64 | ChkStreams.of(RefStreams.of(1, 2)) 65 | .canThrow(IOException.class) 66 | .canThrow(InterruptedException.class); 67 | ChkStream_Throw2 b = 68 | ChkStreams.of(RefStreams.of(10, 20)) 69 | .canThrow(IOException.class) 70 | .canThrow(InterruptedException.class); 71 | ChkStream_Throw2 concat = 72 | a.concat(b); 73 | concat = concat.map( 74 | x -> { throw new InterruptedException("e"); }); 75 | try { 76 | concat.toArray(); 77 | fail(); 78 | } catch (InterruptedException e) {} 79 | } 80 | 81 | @Test 82 | public void testCanThrowDerived() throws IOException { 83 | try { 84 | ChkStreams.of(RefStreams.of(1)).canThrow(IOException.class).map( 85 | new ChkFunction() { 86 | @Override 87 | public Void apply(Integer t) throws FileNotFoundException { 88 | throw new FileNotFoundException( 89 | "Simulated error: " + t); 90 | } 91 | }).toArray(); 92 | fail(); 93 | } catch (FileNotFoundException e) { 94 | assertEquals("Simulated error: 1", e.getMessage()); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /third_party/openjdk/tmpl/com/google/chkstream/ChkPrimitiveStream.tmpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | <%! 27 | split = True 28 | for_each_stream_impl = True 29 | for_each_specialization = True 30 | 31 | def get_class_name(num_exceptions, min_exceptions, specialization): 32 | class_name = 'Chk%sStream' % specialization 33 | if num_exceptions != min_exceptions: 34 | class_name = '%s_Throw%d' % (class_name, num_exceptions) 35 | return class_name 36 | 37 | def get_filename(num_exceptions, min_exceptions, specialization): 38 | return get_class_name( 39 | num_exceptions, min_exceptions, specialization) + '.java' 40 | %> 41 | 42 | <% 43 | throws_list = 'throws ' + ', '.join(['E%d' % i for i in xrange(0, num_e)]) 44 | _ThrowN = '' if num_e == MIN_EXCEPTIONS else '_Throw%d' % num_e 45 | class_name = get_class_name(num_e, MIN_EXCEPTIONS, specialization) 46 | boxed_type = specialization 47 | if boxed_type == 'Int': 48 | boxed_type = 'Integer' 49 | 50 | def exc_list(extends=False, declare=False): 51 | string = ', '.join( 52 | ['%sE%d%s' % ( 53 | '? extends ' if extends else '', 54 | i, 55 | ' extends Exception' if declare else '') 56 | for i in xrange(0, num_e)]) 57 | return string 58 | 59 | def class_type(extends=False, declare=False): 60 | return '%s<%s>' % ( 61 | class_name, exc_list(extends, declare)) 62 | %> 63 | 64 | package com.google.chkstream.${stream_impl}; 65 | 66 | % if stream_impl == 'java8': 67 | import java.util.${specialization}SummaryStatistics; 68 | import java.util.Optional; 69 | import java.util.OptionalDouble; 70 | % if specialization != 'Double': 71 | import java.util.Optional${specialization}; 72 | % endif 73 | import java.util.PrimitiveIterator; 74 | import java.util.Spliterator; 75 | import java.util.function.BiConsumer; 76 | import java.util.function.BinaryOperator; 77 | import java.util.function.${specialization}BinaryOperator; 78 | import java.util.function.${specialization}Function; 79 | import java.util.function.Obj${specialization}Consumer; 80 | import java.util.function.Supplier; 81 | import java.util.stream.DoubleStream; 82 | import java.util.stream.IntStream; 83 | import java.util.stream.LongStream; 84 | import java.util.stream.Stream; 85 | 86 | import com.google.chkstream.java8.function.FunctionUtils_Throw${num_e}; 87 | 88 | % else: 89 | import java8.util.${specialization}SummaryStatistics; 90 | import java8.util.Optional; 91 | import java8.util.OptionalDouble; 92 | % if specialization != 'Double': 93 | import java8.util.Optional${specialization}; 94 | % endif 95 | import java8.util.PrimitiveIterator; 96 | import java8.util.Spliterator; 97 | import java8.util.function.BiConsumer; 98 | import java8.util.function.BinaryOperator; 99 | import java8.util.function.${specialization}BinaryOperator; 100 | import java8.util.function.${specialization}Function; 101 | import java8.util.function.Obj${specialization}Consumer; 102 | import java8.util.function.Supplier; 103 | import java8.util.stream.DoubleStream; 104 | import java8.util.stream.IntStream; 105 | import java8.util.stream.LongStream; 106 | import java8.util.stream.${specialization}Streams; 107 | import java8.util.stream.Stream; 108 | 109 | import com.google.chkstream.streamsupport.function.FunctionUtils_Throw${num_e}; 110 | import com.google.chkstream.lang.AutoCloseable; 111 | 112 | % endif 113 | 114 | import com.google.chkstream.ChkStreamWrappedException; 115 | import com.google.chkstream.function.ChkConsumers.*; 116 | import com.google.chkstream.function.ChkFunctions.*; 117 | import com.google.chkstream.function.ChkPredicates.*; 118 | import com.google.chkstream.function.ChkRunnables.*; 119 | 120 | /** 121 | * A sequence of elements supporting sequential and parallel aggregate 122 | * operations. 123 | * 124 | *

{@link ChkStream} is similar to {@link Stream} except that it can throw 125 | * checked exceptions that have been added to the stream via the 126 | * {@link #canThrow(Class) method. 127 | * 128 | *

See the 129 | * 130 | * official {@link Stream} documentation for details. 131 | * 132 | * @see Stream 133 | */ 134 | public class ${class_type(declare=True)} 135 | implements AutoCloseable { 136 | private final ${specialization}Stream stream; 137 | % for i in xrange(0, num_e): 138 | private final Class e${i}Class; 139 | % endfor 140 | private final FunctionUtils_Throw${num_e} functionUtils; 141 | 142 | ${class_name}( 143 | % for i in xrange(0, num_e): 144 | Class e${i}Class, 145 | % endfor, 146 | ${specialization}Stream stream) { 147 | this.stream = stream; 148 | % for i in xrange(0, num_e): 149 | this.e${i}Class = e${i}Class; 150 | % endfor 151 | this.functionUtils = new FunctionUtils_Throw${num_e}(); 152 | } 153 | 154 | // Methods from BaseStream. 155 | 156 | /** 157 | * Returns an iterator for the elements of this stream. 158 | * 159 | *

This is a terminal 160 | * operation. 161 | * 162 | * @return the element iterator for this stream 163 | */ 164 | public PrimitiveIterator.Of${specialization} iterator() { 165 | return stream.iterator(); 166 | } 167 | 168 | /** 169 | * Returns a spliterator for the elements of this stream. 170 | * 171 | *

This is a terminal 172 | * operation. 173 | * 174 | * @return the element spliterator for this stream 175 | */ 176 | public Spliterator.Of${specialization} spliterator() { 177 | return stream.spliterator(); 178 | } 179 | 180 | /** 181 | * Returns whether this stream, if a terminal operation were to be executed, 182 | * would execute in parallel. Calling this method after invoking an 183 | * terminal stream operation method may yield unpredictable results. 184 | * 185 | * @return {@code true} if this stream would execute in parallel if executed 186 | */ 187 | public boolean isParallel() { 188 | return stream.isParallel(); 189 | } 190 | 191 | /** 192 | * Returns an equivalent stream that is sequential. May return 193 | * itself, either because the stream was already sequential, or because 194 | * the underlying stream state was modified to be sequential. 195 | * 196 | *

This is an intermediate 197 | * operation. 198 | * 199 | * @return a sequential stream 200 | */ 201 | public ${class_type()} sequential() { 202 | return fromStream(stream.sequential()); 203 | } 204 | 205 | /** 206 | * Returns an equivalent stream that is parallel. May return 207 | * itself, either because the stream was already parallel, or because 208 | * the underlying stream state was modified to be parallel. 209 | * 210 | *

This is an intermediate 211 | * operation. 212 | * 213 | * @return a parallel stream 214 | */ 215 | public ${class_type()} parallel() { 216 | return fromStream(stream.parallel()); 217 | } 218 | 219 | /** 220 | * Returns an equivalent stream that is 221 | * unordered. May return 222 | * itself, either because the stream was already unordered, or because 223 | * the underlying stream state was modified to be unordered. 224 | * 225 | *

This is an intermediate 226 | * operation. 227 | * 228 | * @return an unordered stream 229 | */ 230 | public ${class_type()} unordered() { 231 | return fromStream(stream.unordered()); 232 | } 233 | 234 | /** 235 | * Returns an equivalent stream with an additional close handler. Close 236 | * handlers are run when the {@link #close()} method 237 | * is called on the stream, and are executed in the order they were 238 | * added. All close handlers are run, even if earlier close handlers throw 239 | * exceptions. If any close handler throws an exception, the first 240 | * exception thrown will be relayed to the caller of {@code close()}, with 241 | * any remaining exceptions added to that exception as suppressed exceptions 242 | * (unless one of the remaining exceptions is the same exception as the 243 | * first exception, since an exception cannot suppress itself.) May 244 | * return itself. 245 | * 246 | *

This is an intermediate 247 | * operation. 248 | * 249 | * @param closeHandler A task to execute when the stream is closed 250 | * @return a stream with a handler that is run if the stream is closed 251 | */ 252 | public ${class_type()} onClose( 253 | final ChkRunnable${_ThrowN} 254 | <${exc_list(extends=True)}> 255 | closeHandler) { 256 | return fromStream( 257 | stream.onClose(functionUtils.wrapChkRunnable(closeHandler))); 258 | } 259 | 260 | /** 261 | * Closes this stream, causing all close handlers for this stream pipeline 262 | * to be called. 263 | * 264 | * @see AutoCloseable#close() 265 | */ 266 | @Override 267 | public void close() ${throws_list} { 268 | try { 269 | stream.close(); 270 | } catch (ChkStreamWrappedException e) { 271 | rethrowException(e); 272 | } 273 | } 274 | 275 | /** 276 | * Returns a stream consisting of the elements of this stream that match 277 | * the given predicate. 278 | * 279 | *

This is an intermediate 280 | * operation. 281 | * 282 | * @param predicate a non-interfering, 283 | * stateless 284 | * predicate to apply to each element to determine if it 285 | * should be included 286 | * @return the new stream 287 | */ 288 | public ${class_type()} filter( 289 | final Chk${specialization}Predicate${_ThrowN} 290 | <${exc_list(extends=True)}> 291 | predicate) { 292 | return fromStream( 293 | stream.filter( 294 | functionUtils.wrapChk${specialization}Predicate(predicate))); 295 | } 296 | 297 | /** 298 | * Returns an object-valued {@code Stream} consisting of the results of 299 | * applying the given function to the elements of this stream. 300 | * 301 | *

This is an 302 | * intermediate operation. 303 | * 304 | * @param the element type of the new stream 305 | * @param mapper a non-interfering, 306 | * stateless 307 | * function to apply to each element 308 | * @return the new stream 309 | */ 310 | public ChkStream${_ThrowN} mapToObj( 311 | Chk${specialization}Function${_ThrowN} 312 | 314 | mapper) { 315 | Stream newStream = 316 | stream.mapToObj( 317 | functionUtils.wrapChk${specialization}Function(mapper)); 318 | return new ChkStream${_ThrowN}( 319 | ${''.join(['e%dClass,' % i for i in xrange(0, num_e)])} 320 | newStream); 321 | } 322 | 323 | /** 324 | * Returns a stream consisting of the results of applying the given 325 | * function to the elements of this stream. 326 | * 327 | *

This is an intermediate 328 | * operation. 329 | * 330 | * @param mapper a non-interfering, 331 | * stateless 332 | * function to apply to each element 333 | * @return the new stream 334 | */ 335 | public 336 | Chk${specialization}Stream${_ThrowN} 337 | <${exc_list()}> 338 | map( 339 | Chk${specialization}UnaryOperator${_ThrowN} 340 | <${exc_list(extends=True)}> 341 | mapper) { 342 | return fromStream( 343 | stream.map( 344 | functionUtils.wrapChk${specialization}UnaryOperator(mapper))); 345 | } 346 | 347 | % for dest_specialization in SPECIALIZATIONS: 348 | % if dest_specialization != specialization: 349 | /** 350 | * Returns an {@code ${dest_specialization}Stream} consisting of the results 351 | * of applying the given function to the elements of this stream. 352 | * 353 | *

This is an 354 | * intermediate operation. 355 | * 356 | * @param mapper a non-interfering, 357 | * stateless 358 | * function to apply to each element 359 | * @return the new stream 360 | */ 361 | public 362 | Chk${dest_specialization}Stream${_ThrowN}<${exc_list()}> 363 | mapTo${dest_specialization}( 364 | final Chk${specialization}To${dest_specialization}Function${_ThrowN} 365 | <${exc_list(extends=True)}> 366 | mapper) { 367 | ${dest_specialization}Stream newStream = 368 | stream.mapTo${dest_specialization}( 369 | functionUtils.wrapChk${specialization}To${dest_specialization}Function( 370 | mapper)); 371 | return new Chk${dest_specialization}Stream${_ThrowN}<${exc_list()}>( 372 | ${''.join(['e%dClass,' % i for i in xrange(0, num_e)])} 373 | newStream); 374 | } 375 | % endif 376 | % endfor 377 | 378 | /** 379 | * Returns a stream consisting of the results of replacing each element of 380 | * this stream with the contents of a mapped stream produced by applying 381 | * the provided mapping function to each element. Each mapped stream is 382 | * {@link java.util.stream.BaseStream#close() closed} after its contents 383 | * have been placed into this stream. (If a mapped stream is {@code null} 384 | * an empty stream is used, instead.) 385 | * 386 | *

This is an intermediate 387 | * operation. 388 | * 389 | * @apiNote 390 | * The {@code flatMap()} operation has the effect of applying a one-to-many 391 | * transformation to the elements of the stream, and then flattening the 392 | * resulting elements into a new stream. 393 | * 394 | *

Examples. 395 | * 396 | *

If {@code orders} is a stream of purchase orders, and each purchase 397 | * order contains a collection of line items, then the following produces a 398 | * stream containing all the line items in all the orders: 399 | *

{@code
 400 |      *     orders.flatMap(order -> order.getLineItems().stream())...
 401 |      * }
402 | * 403 | *

If {@code path} is the path to a file, then the following produces a 404 | * stream of the {@code words} contained in that file: 405 | *

{@code
 406 |      *     ChkStream lines = Files.lines(path, StandardCharsets.UTF_8);
 407 |      *     ChkStream words = lines.flatMap(line -> Stream.of(line.split(" +")));
 408 |      * }
409 | * The {@code mapper} function passed to {@code flatMap} splits a line, 410 | * using a simple regular expression, into an array of words, and then 411 | * creates a stream of words from that array. 412 | * 413 | * @param The element type of the new stream 414 | * @param mapper a non-interfering, 415 | * stateless 416 | * function to apply to each element which produces a stream 417 | * of new values 418 | * @return the new stream 419 | */ 420 | public ${class_type()} flatMap( 421 | final Chk${specialization}Function${_ThrowN} 422 | 424 | mapper) { 425 | return fromStream( 426 | stream.flatMap( 427 | functionUtils.wrapChk${specialization}Function(mapper))); 428 | } 429 | 430 | /** 431 | * Like #flatMap(ChkFunction${_ThrowN}), except the function returns a 432 | * {@link ChkStream} of the same generic type as this stream. 433 | */ 434 | public ${class_type()} flatMapChk( 435 | final Chk${specialization}Function${_ThrowN} 436 | , 437 | ${exc_list(extends=True)}> 438 | mapper) { 439 | return fromStream(stream.flatMap( 440 | new ${specialization}Function<${specialization}Stream>() { 441 | @Override 442 | public ${specialization}Stream apply( 443 | ${specialization.lower()} t) { 444 | ${class_name}<${exc_list(extends=True)}> subStream; 445 | try { 446 | subStream = mapper.apply(t); 447 | } catch (Exception e) { 448 | throw new ChkStreamWrappedException(e); 449 | } 450 | return subStream.toStream(); 451 | } 452 | })); 453 | } 454 | 455 | /** 456 | * Returns a stream consisting of the distinct elements (according to 457 | * {@link Object#equals(Object)}) of this stream. 458 | * 459 | *

For ordered streams, the selection of distinct elements is stable 460 | * (for duplicated elements, the element appearing first in the encounter 461 | * order is preserved.) For unordered streams, no stability guarantees 462 | * are made. 463 | * 464 | *

This is a stateful 465 | * intermediate operation. 466 | * 467 | * @apiNote 468 | * Preserving stability for {@code distinct()} in parallel pipelines is 469 | * relatively expensive (requires that the operation act as a full barrier, 470 | * with substantial buffering overhead), and stability is often not needed. 471 | * Using an unordered stream source (such as {@link #generate(Supplier)}) 472 | * or removing the ordering constraint with {@link #unordered()} may result 473 | * in significantly more efficient execution for {@code distinct()} in parallel 474 | * pipelines, if the semantics of your situation permit. If consistency 475 | * with encounter order is required, and you are experiencing poor performance 476 | * or memory utilization with {@code distinct()} in parallel pipelines, 477 | * switching to sequential execution with {@link #sequential()} may improve 478 | * performance. 479 | * 480 | * @return the new stream 481 | */ 482 | public ${class_type()} distinct() { 483 | return fromStream(stream.distinct()); 484 | } 485 | 486 | /** 487 | * Returns a stream consisting of the elements of this stream, sorted 488 | * according to natural order. 489 | * 490 | *

For ordered streams, the sort is stable. For unordered streams, no 491 | * stability guarantees are made. 492 | * 493 | *

This is a stateful 494 | * intermediate operation. 495 | * 496 | * @return the new stream 497 | */ 498 | public ${class_type()} sorted() { 499 | return fromStream(stream.sorted()); 500 | } 501 | 502 | /** 503 | * Returns a stream consisting of the elements of this stream, additionally 504 | * performing the provided action on each element as elements are consumed 505 | * from the resulting stream. 506 | * 507 | *

This is an intermediate 508 | * operation. 509 | * 510 | *

For parallel stream pipelines, the action may be called at 511 | * whatever time and in whatever thread the element is made available by the 512 | * upstream operation. If the action modifies shared state, 513 | * it is responsible for providing the required synchronization. 514 | * 515 | * @apiNote This method exists mainly to support debugging, where you want 516 | * to see the elements as they flow past a certain point in a pipeline: 517 | *

{@code
 518 |      *     Stream.of("one", "two", "three", "four")
 519 |      *         .filter(e -> e.length() > 3)
 520 |      *         .peek(e -> System.out.println("Filtered value: " + e))
 521 |      *         .map(String::toUpperCase)
 522 |      *         .peek(e -> System.out.println("Mapped value: " + e))
 523 |      *         .collect(Collectors.toList());
 524 |      * }
525 | * 526 | * @param action a 527 | * non-interfering action to perform on the elements as 528 | * they are consumed from the stream 529 | * @return the new stream 530 | */ 531 | public ${class_type()} peek( 532 | final Chk${specialization}Consumer${_ThrowN} 533 | <${exc_list(extends=True)}> 534 | action) { 535 | return fromStream( 536 | stream.peek( 537 | functionUtils.wrapChk${specialization}Consumer(action))); 538 | } 539 | 540 | /** 541 | * Returns a stream consisting of the elements of this stream, truncated 542 | * to be no longer than {@code maxSize} in length. 543 | * 544 | *

This is a short-circuiting 545 | * stateful intermediate operation. 546 | * 547 | * @apiNote 548 | * While {@code limit()} is generally a cheap operation on sequential 549 | * stream pipelines, it can be quite expensive on ordered parallel pipelines, 550 | * especially for large values of {@code maxSize}, since {@code limit(n)} 551 | * is constrained to return not just any n elements, but the 552 | * first n elements in the encounter order. Using an unordered 553 | * stream source (such as {@link #generate(Supplier)}) or removing the 554 | * ordering constraint with {@link #unordered()} may result in significant 555 | * speedups of {@code limit()} in parallel pipelines, if the semantics of 556 | * your situation permit. If consistency with encounter order is required, 557 | * and you are experiencing poor performance or memory utilization with 558 | * {@code limit()} in parallel pipelines, switching to sequential execution 559 | * with {@link #sequential()} may improve performance. 560 | * 561 | * @param maxSize the number of elements the stream should be limited to 562 | * @return the new stream 563 | * @throws IllegalArgumentException if {@code maxSize} is negative 564 | */ 565 | public ${class_type()} limit(long maxSize) { 566 | return fromStream(stream.limit(maxSize)); 567 | } 568 | 569 | /** 570 | * Returns a stream consisting of the remaining elements of this stream 571 | * after discarding the first {@code n} elements of the stream. 572 | * If this stream contains fewer than {@code n} elements then an 573 | * empty stream will be returned. 574 | * 575 | *

This is a stateful 576 | * intermediate operation. 577 | * 578 | * @apiNote 579 | * While {@code skip()} is generally a cheap operation on sequential 580 | * stream pipelines, it can be quite expensive on ordered parallel pipelines, 581 | * especially for large values of {@code n}, since {@code skip(n)} 582 | * is constrained to skip not just any n elements, but the 583 | * first n elements in the encounter order. Using an unordered 584 | * stream source (such as {@link #generate(Supplier)}) or removing the 585 | * ordering constraint with {@link #unordered()} may result in significant 586 | * speedups of {@code skip()} in parallel pipelines, if the semantics of 587 | * your situation permit. If consistency with encounter order is required, 588 | * and you are experiencing poor performance or memory utilization with 589 | * {@code skip()} in parallel pipelines, switching to sequential execution 590 | * with {@link #sequential()} may improve performance. 591 | * 592 | * @param n the number of leading elements to skip 593 | * @return the new stream 594 | * @throws IllegalArgumentException if {@code n} is negative 595 | */ 596 | public ${class_type()} skip(long n) { 597 | return fromStream(stream.skip(n)); 598 | } 599 | 600 | /** 601 | * Performs an action for each element of this stream. 602 | * 603 | *

This is a terminal 604 | * operation. 605 | * 606 | *

The behavior of this operation is explicitly nondeterministic. 607 | * For parallel stream pipelines, this operation does not 608 | * guarantee to respect the encounter order of the stream, as doing so 609 | * would sacrifice the benefit of parallelism. For any given element, the 610 | * action may be performed at whatever time and in whatever thread the 611 | * library chooses. If the action accesses shared state, it is 612 | * responsible for providing the required synchronization. 613 | * 614 | * @param action a 615 | * non-interfering action to perform on the elements 616 | */ 617 | public void forEach( 618 | final Chk${specialization}Consumer${_ThrowN} 619 | <${exc_list(extends=True)}> 620 | action) ${throws_list} { 621 | try { 622 | stream.forEach( 623 | functionUtils.wrapChk${specialization}Consumer(action)); 624 | } catch (ChkStreamWrappedException e) { 625 | rethrowException(e); 626 | } 627 | } 628 | 629 | /** 630 | * Performs an action for each element of this stream, in the encounter 631 | * order of the stream if the stream has a defined encounter order. 632 | * 633 | *

This is a terminal 634 | * operation. 635 | * 636 | *

This operation processes the elements one at a time, in encounter 637 | * order if one exists. Performing the action for one element 638 | * happens-before 639 | * performing the action for subsequent elements, but for any given element, 640 | * the action may be performed in whatever thread the library chooses. 641 | * 642 | * @param action a 643 | * non-interfering action to perform on the elements 644 | * @see #forEach(Consumer) 645 | */ 646 | public void forEachOrdered( 647 | final Chk${specialization}Consumer${_ThrowN} 648 | <${exc_list(extends=True)}> 649 | action) ${throws_list} { 650 | try { 651 | stream.forEachOrdered( 652 | functionUtils.wrapChk${specialization}Consumer(action)); 653 | } catch (ChkStreamWrappedException e) { 654 | rethrowException(e); 655 | } 656 | } 657 | 658 | /** 659 | * Returns an array containing the elements of this stream. 660 | * 661 | *

This is a terminal 662 | * operation. 663 | * 664 | * @return an array containing the elements of this stream 665 | */ 666 | public ${specialization.lower()}[] toArray() ${throws_list} { 667 | try { 668 | return stream.toArray(); 669 | } catch (ChkStreamWrappedException e) { 670 | rethrowException(e); 671 | return null; 672 | } 673 | } 674 | 675 | /** 676 | * Performs a reduction on the 677 | * elements of this stream, using the provided identity value and an 678 | * associative 679 | * accumulation function, and returns the reduced value. This is equivalent 680 | * to: 681 | *

{@code
 682 |      *     T result = identity;
 683 |      *     for (T element : this stream)
 684 |      *         result = accumulator.apply(result, element)
 685 |      *     return result;
 686 |      * }
687 | * 688 | * but is not constrained to execute sequentially. 689 | * 690 | *

The {@code identity} value must be an identity for the accumulator 691 | * function. This means that for all {@code t}, 692 | * {@code accumulator.apply(identity, t)} is equal to {@code t}. 693 | * The {@code accumulator} function must be an 694 | * associative function. 695 | * 696 | *

This is a terminal 697 | * operation. 698 | * 699 | * @apiNote Sum, min, max, average, and string concatenation are all special 700 | * cases of reduction. Summing a stream of numbers can be expressed as: 701 | * 702 | *

{@code
 703 |      *     Integer sum = integers.reduce(0, (a, b) -> a+b);
 704 |      * }
705 | * 706 | * or: 707 | * 708 | *
{@code
 709 |      *     Integer sum = integers.reduce(0, Integer::sum);
 710 |      * }
711 | * 712 | *

While this may seem a more roundabout way to perform an aggregation 713 | * compared to simply mutating a running total in a loop, reduction 714 | * operations parallelize more gracefully, without needing additional 715 | * synchronization and with greatly reduced risk of data races. 716 | * 717 | * @param identity the identity value for the accumulating function 718 | * @param accumulator an associative, 719 | * non-interfering, 720 | * stateless 721 | * function for combining two values 722 | * @return the result of the reduction 723 | */ 724 | public ${specialization.lower()} reduce( 725 | ${specialization.lower()} identity, 726 | ${specialization}BinaryOperator accumulator) ${throws_list} { 727 | try { 728 | return stream.reduce(identity, accumulator); 729 | } catch (ChkStreamWrappedException e) { 730 | rethrowException(e); 731 | return -1; 732 | } 733 | } 734 | 735 | /** 736 | * Performs a reduction on the 737 | * elements of this stream, using an 738 | * associative accumulation 739 | * function, and returns an {@code Optional} describing the reduced value, 740 | * if any. This is equivalent to: 741 | *

{@code
 742 |      *     boolean foundAny = false;
 743 |      *     T result = null;
 744 |      *     for (T element : this stream) {
 745 |      *         if (!foundAny) {
 746 |      *             foundAny = true;
 747 |      *             result = element;
 748 |      *         }
 749 |      *         else
 750 |      *             result = accumulator.apply(result, element);
 751 |      *     }
 752 |      *     return foundAny ? Optional.of(result) : Optional.empty();
 753 |      * }
754 | * 755 | * but is not constrained to execute sequentially. 756 | * 757 | *

The {@code accumulator} function must be an 758 | * associative function. 759 | * 760 | *

This is a terminal 761 | * operation. 762 | * 763 | * @param accumulator an associative, 764 | * non-interfering, 765 | * stateless 766 | * function for combining two values 767 | * @return an {@link Optional} describing the result of the reduction 768 | * @throws NullPointerException if the result of the reduction is null 769 | * @see #reduce(Object, BinaryOperator) 770 | * @see #min() 771 | * @see #max() 772 | */ 773 | public Optional${specialization} reduce( 774 | ${specialization}BinaryOperator op) ${throws_list} { 775 | try { 776 | return stream.reduce(op); 777 | } catch (ChkStreamWrappedException e) { 778 | rethrowException(e); 779 | return null; 780 | } 781 | } 782 | 783 | /** 784 | * Performs a mutable 785 | * reduction operation on the elements of this stream. A mutable 786 | * reduction is one in which the reduced value is a mutable result container, 787 | * such as an {@code ArrayList}, and elements are incorporated by updating 788 | * the state of the result rather than by replacing the result. This 789 | * produces a result equivalent to: 790 | *

{@code
 791 |      *     R result = supplier.get();
 792 |      *     for (T element : this stream)
 793 |      *         accumulator.accept(result, element);
 794 |      *     return result;
 795 |      * }
796 | * 797 | *

Like {@link #reduce(Object, BinaryOperator)}, {@code collect} operations 798 | * can be parallelized without requiring additional synchronization. 799 | * 800 | *

This is a terminal 801 | * operation. 802 | * 803 | * @apiNote There are many existing classes in the JDK whose signatures are 804 | * well-suited for use with method references as arguments to {@code collect()}. 805 | * For example, the following will accumulate strings into an {@code ArrayList}: 806 | *

{@code
 807 |      *     List asList = stringStream.collect(ArrayList::new, ArrayList::add,
 808 |      *                                                ArrayList::addAll);
 809 |      * }
810 | * 811 | *

The following will take a stream of strings and concatenates them into a 812 | * single string: 813 | *

{@code
 814 |      *     String concat = stringStream.collect(StringBuilder::new, StringBuilder::append,
 815 |      *                                          StringBuilder::append)
 816 |      *                                 .toString();
 817 |      * }
818 | * 819 | * @param type of the result 820 | * @param supplier a function that creates a new result container. For a 821 | * parallel execution, this function may be called 822 | * multiple times and must return a fresh value each time. 823 | * @param accumulator an associative, 824 | * non-interfering, 825 | * stateless 826 | * function for incorporating an additional element into a result 827 | * @param combiner an associative, 828 | * non-interfering, 829 | * stateless 830 | * function for combining two values, which must be 831 | * compatible with the accumulator function 832 | * @return the result of the reduction 833 | */ 834 | public R collect( 835 | Supplier supplier, 836 | Obj${specialization}Consumer accumulator, 837 | BiConsumer combiner) ${throws_list} { 838 | try { 839 | return stream.collect(supplier, accumulator, combiner); 840 | } catch (ChkStreamWrappedException e) { 841 | rethrowException(e); 842 | return null; 843 | } 844 | } 845 | 846 | /** 847 | * Returns the sum of elements in this stream. This is a special case 848 | * of a reduction 849 | * and is equivalent to: 850 | *
{@code
 851 |      *     return reduce(0, Integer::sum);
 852 |      * }
853 | * 854 | *

This is a terminal 855 | * operation. 856 | * 857 | * @return the sum of elements in this stream 858 | */ 859 | public ${specialization.lower()} sum() ${throws_list} { 860 | try { 861 | return stream.sum(); 862 | } catch (ChkStreamWrappedException e) { 863 | rethrowException(e); 864 | return -1; 865 | } 866 | } 867 | 868 | /** 869 | * Returns an {@code Optional} describing the minimum element of this 870 | * stream, or an empty optional if this stream is empty. This is a special 871 | * case of a reduction 872 | * and is equivalent to: 873 | *

{@code
 874 |      *     return reduce(Integer::min);
 875 |      * }
876 | * 877 | *

This is a terminal operation. 878 | * 879 | * @return an {@code Optional} containing the minimum element of this 880 | * stream, or an empty {@code Optional} if the stream is empty 881 | */ 882 | public Optional${specialization} min() ${throws_list} { 883 | try { 884 | return stream.min(); 885 | } catch (ChkStreamWrappedException e) { 886 | rethrowException(e); 887 | return null; 888 | } 889 | } 890 | 891 | /** 892 | * Returns an {@code Optional} describing the maximum element of this 893 | * stream, or an empty optional if this stream is empty. This is a special 894 | * case of a reduction 895 | * and is equivalent to: 896 | *

{@code
 897 |      *     return reduce(Integer::max);
 898 |      * }
899 | * 900 | *

This is a terminal 901 | * operation. 902 | * 903 | * @return an {@code Optional} containing the maximum element of this 904 | * stream, or an empty {@code Optional} if the stream is empty 905 | */ 906 | public Optional${specialization} max() ${throws_list} { 907 | try { 908 | return stream.max(); 909 | } catch (ChkStreamWrappedException e) { 910 | rethrowException(e); 911 | return null; 912 | } 913 | } 914 | 915 | /** 916 | * Returns the count of elements in this stream. This is a special case of 917 | * a reduction and is 918 | * equivalent to: 919 | *

{@code
 920 |      *     return mapToLong(e -> 1L).sum();
 921 |      * }
922 | * 923 | *

This is a terminal operation. 924 | * 925 | * @return the count of elements in this stream 926 | */ 927 | public long count() ${throws_list} { 928 | try { 929 | return stream.count(); 930 | } catch (ChkStreamWrappedException e) { 931 | rethrowException(e); 932 | return -1; 933 | } 934 | } 935 | 936 | /** 937 | * Returns an {@code OptionalDouble} describing the arithmetic mean of elements of 938 | * this stream, or an empty optional if this stream is empty. This is a 939 | * special case of a 940 | * reduction. 941 | * 942 | *

This is a terminal 943 | * operation. 944 | * 945 | * @return an {@code OptionalDouble} containing the average element of this 946 | * stream, or an empty optional if the stream is empty 947 | */ 948 | public OptionalDouble average() ${throws_list} { 949 | try { 950 | return stream.average(); 951 | } catch (ChkStreamWrappedException e) { 952 | rethrowException(e); 953 | return null; 954 | } 955 | } 956 | 957 | /** 958 | * Returns an {@code IntSummaryStatistics} describing various 959 | * summary data about the elements of this stream. This is a special 960 | * case of a reduction. 961 | * 962 | *

This is a terminal 963 | * operation. 964 | * 965 | * @return an {@code IntSummaryStatistics} describing various summary data 966 | * about the elements of this stream 967 | */ 968 | public ${specialization}SummaryStatistics summaryStatistics() 969 | ${throws_list} { 970 | try { 971 | return stream.summaryStatistics(); 972 | } catch (ChkStreamWrappedException e) { 973 | rethrowException(e); 974 | return null; 975 | } 976 | } 977 | 978 | /** 979 | * Returns whether any elements of this stream match the provided 980 | * predicate. May not evaluate the predicate on all elements if not 981 | * necessary for determining the result. If the stream is empty then 982 | * {@code false} is returned and the predicate is not evaluated. 983 | * 984 | *

This is a short-circuiting 985 | * terminal operation. 986 | * 987 | * @apiNote 988 | * This method evaluates the existential quantification of the 989 | * predicate over the elements of the stream (for some x P(x)). 990 | * 991 | * @param predicate a non-interfering, 992 | * stateless 993 | * predicate to apply to elements of this stream 994 | * @return {@code true} if any elements of the stream match the provided 995 | * predicate, otherwise {@code false} 996 | */ 997 | public boolean anyMatch( 998 | final Chk${specialization}Predicate${_ThrowN} 999 | <${exc_list(extends=True)}> 1000 | predicate) ${throws_list} { 1001 | try { 1002 | return stream.anyMatch( 1003 | functionUtils.wrapChk${specialization}Predicate(predicate)); 1004 | } catch (ChkStreamWrappedException e) { 1005 | rethrowException(e); 1006 | return false; 1007 | } 1008 | } 1009 | 1010 | /** 1011 | * Returns whether all elements of this stream match the provided predicate. 1012 | * May not evaluate the predicate on all elements if not necessary for 1013 | * determining the result. If the stream is empty then {@code true} is 1014 | * returned and the predicate is not evaluated. 1015 | * 1016 | *

This is a short-circuiting 1017 | * terminal operation. 1018 | * 1019 | * @apiNote 1020 | * This method evaluates the universal quantification of the 1021 | * predicate over the elements of the stream (for all x P(x)). If the 1022 | * stream is empty, the quantification is said to be vacuously 1023 | * satisfied and is always {@code true} (regardless of P(x)). 1024 | * 1025 | * @param predicate a non-interfering, 1026 | * stateless 1027 | * predicate to apply to elements of this stream 1028 | * @return {@code true} if either all elements of the stream match the 1029 | * provided predicate or the stream is empty, otherwise {@code false} 1030 | */ 1031 | public boolean allMatch( 1032 | final Chk${specialization}Predicate${_ThrowN} 1033 | <${exc_list(extends=True)}> 1034 | predicate) ${throws_list} { 1035 | try { 1036 | return stream.allMatch( 1037 | functionUtils.wrapChk${specialization}Predicate(predicate)); 1038 | } catch (ChkStreamWrappedException e) { 1039 | rethrowException(e); 1040 | return false; 1041 | } 1042 | } 1043 | 1044 | /** 1045 | * Returns whether no elements of this stream match the provided predicate. 1046 | * May not evaluate the predicate on all elements if not necessary for 1047 | * determining the result. If the stream is empty then {@code true} is 1048 | * returned and the predicate is not evaluated. 1049 | * 1050 | *

This is a short-circuiting 1051 | * terminal operation. 1052 | * 1053 | * @apiNote 1054 | * This method evaluates the universal quantification of the 1055 | * negated predicate over the elements of the stream (for all x ~P(x)). If 1056 | * the stream is empty, the quantification is said to be vacuously satisfied 1057 | * and is always {@code true}, regardless of P(x). 1058 | * 1059 | * @param predicate a non-interfering, 1060 | * stateless 1061 | * predicate to apply to elements of this stream 1062 | * @return {@code true} if either no elements of the stream match the 1063 | * provided predicate or the stream is empty, otherwise {@code false} 1064 | */ 1065 | public boolean noneMatch( 1066 | final Chk${specialization}Predicate${_ThrowN} 1067 | <${exc_list(extends=True)}> 1068 | predicate) ${throws_list} { 1069 | try { 1070 | return stream.noneMatch( 1071 | functionUtils.wrapChk${specialization}Predicate(predicate)); 1072 | } catch (ChkStreamWrappedException e) { 1073 | rethrowException(e); 1074 | return false; 1075 | } 1076 | } 1077 | 1078 | /** 1079 | * Returns an {@link Optional} describing the first element of this stream, 1080 | * or an empty {@code Optional} if the stream is empty. If the stream has 1081 | * no encounter order, then any element may be returned. 1082 | * 1083 | *

This is a short-circuiting 1084 | * terminal operation. 1085 | * 1086 | * @return an {@code Optional} describing the first element of this stream, 1087 | * or an empty {@code Optional} if the stream is empty 1088 | * @throws NullPointerException if the element selected is null 1089 | */ 1090 | public Optional${specialization} findFirst() ${throws_list} { 1091 | try { 1092 | return stream.findFirst(); 1093 | } catch (ChkStreamWrappedException e) { 1094 | rethrowException(e); 1095 | return null; 1096 | } 1097 | } 1098 | 1099 | /** 1100 | * Returns an {@link Optional} describing some element of the stream, or an 1101 | * empty {@code Optional} if the stream is empty. 1102 | * 1103 | *

This is a short-circuiting 1104 | * terminal operation. 1105 | * 1106 | *

The behavior of this operation is explicitly nondeterministic; it is 1107 | * free to select any element in the stream. This is to allow for maximal 1108 | * performance in parallel operations; the cost is that multiple invocations 1109 | * on the same source may not return the same result. (If a stable result 1110 | * is desired, use {@link #findFirst()} instead.) 1111 | * 1112 | * @return an {@code Optional} describing some element of this stream, or an 1113 | * empty {@code Optional} if the stream is empty 1114 | * @throws NullPointerException if the element selected is null 1115 | * @see #findFirst() 1116 | */ 1117 | public Optional${specialization} findAny() ${throws_list} { 1118 | try { 1119 | return stream.findAny(); 1120 | } catch (ChkStreamWrappedException e) { 1121 | rethrowException(e); 1122 | return null; 1123 | } 1124 | } 1125 | 1126 | <% 1127 | banned_combinations = [ 1128 | ('Long', 'Int'), 1129 | ('Double', 'Int'), 1130 | ('Double', 'Long'), 1131 | ] 1132 | %> 1133 | % for dest_specialization in SPECIALIZATIONS: 1134 | % if specialization != dest_specialization: 1135 | % if (specialization, dest_specialization) not in banned_combinations: 1136 | /** 1137 | * Returns a {@code ${dest_specialization}Stream} consisting of the elements 1138 | * of this stream. 1139 | * 1140 | *

This is an intermediate 1141 | * operation. 1142 | * 1143 | * @return a {@code ${dest_specialization}Stream} consisting of the elements 1144 | * of this stream. 1145 | */ 1146 | public Chk${dest_specialization}Stream${_ThrowN}<${exc_list()}> 1147 | as${dest_specialization}Stream() { 1148 | ${dest_specialization}Stream newStream = 1149 | stream.as${dest_specialization}Stream(); 1150 | return new Chk${dest_specialization}Stream${_ThrowN}<${exc_list()}>( 1151 | ${''.join(['e%dClass,' % i for i in xrange(0, num_e)])} 1152 | newStream); 1153 | } 1154 | % else: 1155 | // Chk${specialization}#as${dest_specialization}Stream() not generated, it 1156 | // is not an allowed combination. 1157 | % endif 1158 | % endif 1159 | % endfor 1160 | 1161 | /** 1162 | * Returns a {@code Stream} consisting of the elements of this stream, 1163 | * each boxed to an {@code Integer}. 1164 | * 1165 | *

This is an intermediate 1166 | * operation. 1167 | * 1168 | * @return a {@code Stream} consistent of the elements of this stream, 1169 | * each boxed to an {@code Integer} 1170 | */ 1171 | public ChkStream${_ThrowN}<${boxed_type}, ${exc_list()}> boxed() { 1172 | Stream<${boxed_type}> newStream = stream.boxed(); 1173 | return new ChkStream${_ThrowN}<${boxed_type}, ${exc_list()}>( 1174 | ${''.join(['e%dClass,' % i for i in xrange(0, num_e)])} 1175 | newStream); 1176 | } 1177 | 1178 | // Adapted static methods. 1179 | 1180 | /** 1181 | * Creates a lazily concatenated stream whose elements are all the 1182 | * elements of this stream followed by all the elements of the 1183 | * given stream. The resulting stream is ordered if both 1184 | * of the input streams are ordered, and parallel if either of the input 1185 | * streams is parallel. When the resulting stream is closed, the close 1186 | * handlers for both input streams are invoked. 1187 | * 1188 | * @implNote 1189 | * Use caution when constructing streams from repeated concatenation. 1190 | * Accessing an element of a deeply concatenated stream can result in deep 1191 | * call chains, or even {@code StackOverflowException}. 1192 | * 1193 | * @param The type of stream elements 1194 | * @param a the first stream 1195 | * @param b the second stream 1196 | * @return the concatenation of the two input streams 1197 | */ 1198 | public ${class_type()} concat(${specialization}Stream b) { 1199 | ${specialization}Stream concatStream = 1200 | ${specialization}Stream${'' if stream_impl == 'java8' else 's'} 1201 | .concat(toStream(), b); 1202 | return new ${class_type()}( 1203 | ${', '.join(['e%dClass' % i for i in xrange(0, num_e)])}, 1204 | concatStream); 1205 | } 1206 | 1207 | /** 1208 | * Like {@link #concat(Stream)}, except that the stream to be concatenated 1209 | * is a {@link ChkStream} of the same generic type. 1210 | */ 1211 | public ${class_type()} concat( 1212 | ${class_type(extends=True)} b) { 1213 | return concat(b.toStream()); 1214 | } 1215 | 1216 | // New methods specific to ChkStream. 1217 | 1218 | % if num_e != MAX_EXCEPTIONS: 1219 | <% 1220 | next_class_type = ( 1221 | 'Chk%sStream_Throw%d<%s>' % ( 1222 | specialization, 1223 | num_e + 1, 1224 | ', '.join(['E%d' % i for i in xrange(0, num_e)] + ['NewE']))) 1225 | %> 1226 | /** 1227 | * Returns a stream consisting of the elements of this stream, but where the 1228 | * functions passed to Stream operations can throw an additional checked 1229 | * exception type. 1230 | * 1231 | * @param exceptionClass Class of the new exception the returned stream can 1232 | * throw. 1233 | * @return the newly created stream. 1234 | */ 1235 | public 1236 | ${next_class_type} canThrow(Class clazz) { 1237 | return new ${next_class_type}( 1238 | ${', '.join( 1239 | ['e%dClass' % i for i in xrange(0, num_e)] + ['clazz'])}, 1240 | stream); 1241 | } 1242 | % else: 1243 | // canThrow() not generated; this stream type has the max allowed exceptions 1244 | % endif 1245 | 1246 | /** 1247 | * Returns a {@link Stream} containing the elements of this ChkStream, but 1248 | * which cannot throw checked exceptions. 1249 | * 1250 | *

Any checked exceptions thrown by stream operations that have already 1251 | * been added will be wrapped in {@link ChkStreamWrappedException}, an 1252 | * instance of {@link RuntimeException}. 1253 | */ 1254 | public ${specialization}Stream toStream() { 1255 | return stream; 1256 | } 1257 | 1258 | // Private methods. 1259 | 1260 | private ${class_type()} fromStream(${specialization}Stream stream) { 1261 | return new ${class_type()}( 1262 | ${''.join(['e%dClass,' % i for i in xrange(0, num_e)])} 1263 | stream); 1264 | } 1265 | 1266 | @SuppressWarnings("unchecked") 1267 | private void rethrowException(ChkStreamWrappedException wrapE) 1268 | ${throws_list} { 1269 | Throwable e = wrapE.getCause(); 1270 | if (e instanceof RuntimeException) { 1271 | throw (RuntimeException) e; 1272 | } 1273 | % for i in xrange(0, num_e): 1274 | if (e${i}Class.isInstance(e)) { throw (E${i}) e; } 1275 | % endfor 1276 | throw wrapE; 1277 | } 1278 | } 1279 | -------------------------------------------------------------------------------- /third_party/openjdk/tmpl/com/google/chkstream/ChkStreams.tmpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google. 3 | * 4 | * This file is licensed under the GPLv2+Classpath Exception, which full text 5 | * is found in the LICENSE file at the root of this project. 6 | * 7 | * Google designates this particular file as subject to the "Classpath" 8 | * exception as provided in the LICENSE file that accompanied this code. 9 | */ 10 | 11 | <%! for_each_stream_impl = True %> 12 | 13 | package com.google.chkstream.${stream_impl}; 14 | 15 | % if stream_impl == 'java8': 16 | import java.util.stream.DoubleStream; 17 | import java.util.stream.IntStream; 18 | import java.util.stream.LongStream; 19 | import java.util.stream.Stream; 20 | 21 | % else: 22 | import java8.util.stream.DoubleStream; 23 | import java8.util.stream.IntStream; 24 | import java8.util.stream.LongStream; 25 | import java8.util.stream.Stream; 26 | % endif 27 | 28 | /** 29 | * Static methods for creating new instances of {@link ChkStream}. 30 | * 31 | * @author Alexander Dorokhine 32 | */ 33 | public final class ChkStreams { 34 | private ChkStreams() {} 35 | 36 | /** 37 | * A builder for initializing a {@link ChkStream} with a checked exception. 38 | * 39 | *

Call {@link #canThrow(Class)} to start a {@link ChkStream}. 40 | * {@link ChkStream} implements the same method so more exceptions can be 41 | * added later. 42 | * 43 | * @author Alexander Dorokhine 44 | */ 45 | public static final class ChkStreamStarter { 46 | private final Stream stream; 47 | 48 | private ChkStreamStarter(Stream stream) { 49 | this.stream = stream; 50 | } 51 | 52 | /** 53 | * Initializes a {@link ChkStream} with the given exception type. 54 | * 55 | *

Additional exceptions can be added later by calling 56 | * {@link ChkStream#canThrow(Class)}. 57 | * 58 | * @param exceptionClass Class of the exception this stream can throw. 59 | * @return the newly created stream. 60 | */ 61 | public ChkStream canThrow( 62 | Class exceptionClass) { 63 | return new ChkStream(exceptionClass, stream); 64 | } 65 | } 66 | 67 | /** 68 | * Returns a builder for a {@link ChkStream} wrapping the given 69 | * {@link Stream}. 70 | */ 71 | public static ChkStreamStarter of(Stream stream) { 72 | return new ChkStreamStarter(stream); 73 | } 74 | 75 | // Support the specializations 76 | % for specialization in SPECIALIZATIONS: 77 | public static final class Chk${specialization}StreamStarter { 78 | private final ${specialization}Stream stream; 79 | 80 | private Chk${specialization}StreamStarter( 81 | ${specialization}Stream stream) { 82 | this.stream = stream; 83 | } 84 | 85 | /** 86 | * Initializes a {@link Chk${specialization}Stream} with the given 87 | * exception type. 88 | * 89 | *

Additional exceptions can be added later by calling 90 | * {@link Chk${specialization}Stream#canThrow(Class)}. 91 | * 92 | * @param exceptionClass Class of the exception this stream can throw. 93 | * @return the newly created stream. 94 | */ 95 | public Chk${specialization}Stream canThrow( 96 | Class exceptionClass) { 97 | return new Chk${specialization}Stream(exceptionClass, stream); 98 | } 99 | } 100 | 101 | /** 102 | * Returns a builder for a {@link Chk${specialization}Stream} wrapping the 103 | * given {@link ${specialization}Stream}. 104 | */ 105 | public static Chk${specialization}StreamStarter of${specialization}( 106 | ${specialization}Stream stream) { 107 | return new Chk${specialization}StreamStarter(stream); 108 | } 109 | % endfor 110 | } 111 | -------------------------------------------------------------------------------- /third_party/openjdk/tmpl/com/google/chkstream/function/ChkConsumers.tmpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package com.google.chkstream.function; 26 | 27 | public final class ChkConsumers { 28 | private ChkConsumers() {} 29 | 30 | % for num_e in xrange(MIN_EXCEPTIONS, MAX_EXCEPTIONS + 1): 31 | <% 32 | exc_decl_list = ', '.join( 33 | ['E%d extends Exception' % i for i in xrange(0, num_e)]) 34 | throws_list = 'throws ' + ', '.join(['E%d' % i for i in xrange(0, num_e)]) 35 | _ThrowN = '' if num_e == MIN_EXCEPTIONS else '_Throw%d' % num_e 36 | %> 37 | 38 | /** 39 | * Represents an operation that accepts a single input argument and returns no 40 | * result. Unlike most other functional interfaces, {@code Consumer} is expected 41 | * to operate via side-effects. 42 | * 43 | *

This is a functional interface 44 | * whose functional method is {@link #accept(Object)}. 45 | * 46 | * @param the type of the input to the operation 47 | */ 48 | public static interface ChkConsumer${_ThrowN} 49 | 50 | { 51 | /** 52 | * Performs this operation on the given argument. 53 | * 54 | * @param t the input argument 55 | */ 56 | void accept(T t) ${throws_list}; 57 | } 58 | 59 | % for specialization in SPECIALIZATIONS: 60 | /** 61 | * Represents an operation that accepts a single input argument and returns no 62 | * result. Unlike most other functional interfaces, {@code Consumer} is expected 63 | * to operate via side-effects. 64 | * 65 | *

This is a functional interface 66 | * whose functional method is {@link #accept(Object)}. 67 | * 68 | * @param the type of the input to the operation 69 | */ 70 | public static interface Chk${specialization}Consumer${_ThrowN} 71 | <${exc_decl_list}> 72 | { 73 | /** 74 | * Performs this operation on the given argument. 75 | * 76 | * @param t the input argument 77 | */ 78 | void accept(${specialization.lower()} t) ${throws_list}; 79 | } 80 | % endfor 81 | % endfor 82 | } 83 | -------------------------------------------------------------------------------- /third_party/openjdk/tmpl/com/google/chkstream/function/ChkFunctions.tmpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package com.google.chkstream.function; 26 | 27 | public final class ChkFunctions { 28 | private ChkFunctions() {} 29 | 30 | % for num_e in xrange(MIN_EXCEPTIONS, MAX_EXCEPTIONS + 1): 31 | <% 32 | exc_decl_list = ', '.join( 33 | ['E%d extends Exception' % i for i in xrange(0, num_e)]) 34 | throws_list = 'throws ' + ', '.join(['E%d' % i for i in xrange(0, num_e)]) 35 | _ThrowN = '' if num_e == MIN_EXCEPTIONS else '_Throw%d' % num_e 36 | %> 37 | 38 | /** 39 | * Represents a function that accepts one argument and produces a result. 40 | * 41 | *

This is a functional interface 42 | * whose functional method is {@link #apply(Object)}. 43 | * 44 | * @param the type of the input to the function 45 | * @param the type of the result of the function 46 | */ 47 | public static interface ChkFunction${_ThrowN} 48 | 49 | { 50 | /** 51 | * Applies this function to the given argument. 52 | * 53 | * @param t the function argument 54 | * @return the function result 55 | */ 56 | R apply(T t) ${throws_list}; 57 | } 58 | 59 | % for specialization in SPECIALIZATIONS: 60 | /** 61 | * Represents a function that accepts an object and returns ${specialization}. 62 | */ 63 | public static interface ChkTo${specialization}Function${_ThrowN} 64 | 65 | { 66 | /** 67 | * Applies this function to the given argument. 68 | * 69 | * @param t the function argument 70 | * @return the function result 71 | */ 72 | ${specialization.lower()} applyAs${specialization}(T t) ${throws_list}; 73 | } 74 | 75 | /** 76 | * Represents a function that accepts ${specialization} and returns 77 | * ${specialization}. 78 | */ 79 | public static interface Chk${specialization}UnaryOperator${_ThrowN} 80 | <${exc_decl_list}> 81 | { 82 | /** 83 | * Applies this function to the given argument. 84 | * 85 | * @param t the function argument 86 | * @return the function result 87 | */ 88 | ${specialization.lower()} applyAs${specialization} 89 | (${specialization.lower()} t) 90 | ${throws_list}; 91 | } 92 | 93 | /** 94 | * Represents a function that accepts a ${specialization} and returns an 95 | * object. 96 | */ 97 | public static interface Chk${specialization}Function${_ThrowN} 98 | 99 | { 100 | /** 101 | * Applies this function to the given argument. 102 | * 103 | * @param t the function argument 104 | * @return the function result 105 | */ 106 | U apply(${specialization.lower()} t) ${throws_list}; 107 | } 108 | 109 | % for dest_specialization in SPECIALIZATIONS: 110 | % if dest_specialization != specialization: 111 | /** 112 | * Represents a function that accepts a ${specialization} and returns a 113 | * ${dest_specialization}. 114 | */ 115 | public static interface 116 | Chk${specialization}To${dest_specialization}Function${_ThrowN} 117 | <${exc_decl_list}> 118 | { 119 | /** 120 | * Applies this function to the given argument. 121 | * 122 | * @param t the function argument 123 | * @return the function result 124 | */ 125 | ${dest_specialization.lower()} applyAs${dest_specialization}( 126 | ${specialization.lower()} t) 127 | ${throws_list}; 128 | } 129 | % endif 130 | % endfor // dest_specialization 131 | % endfor // specialization 132 | % endfor // num_e 133 | } 134 | -------------------------------------------------------------------------------- /third_party/openjdk/tmpl/com/google/chkstream/function/ChkPredicates.tmpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package com.google.chkstream.function; 26 | 27 | public final class ChkPredicates { 28 | private ChkPredicates() {} 29 | 30 | % for num_e in xrange(MIN_EXCEPTIONS, MAX_EXCEPTIONS + 1): 31 | <% 32 | exc_decl_list = ', '.join( 33 | ['E%d extends Exception' % i for i in xrange(0, num_e)]) 34 | throws_list = 'throws ' + ', '.join(['E%d' % i for i in xrange(0, num_e)]) 35 | _ThrowN = '' if num_e == MIN_EXCEPTIONS else '_Throw%d' % num_e 36 | %> 37 | 38 | /** 39 | * Represents a predicate (boolean-valued function) of one argument. 40 | * 41 | *

This is a functional interface 42 | * whose functional method is {@link #test(Object)}. 43 | * 44 | * @param the type of the input to the predicate 45 | */ 46 | public static interface ChkPredicate${_ThrowN} 47 | 48 | { 49 | /** 50 | * Evaluates this predicate on the given argument. 51 | * 52 | * @param t the input argument 53 | * @return {@code true} if the input argument matches the predicate, 54 | * otherwise {@code false} 55 | */ 56 | boolean test(T t) ${throws_list}; 57 | } 58 | 59 | % for specialization in SPECIALIZATIONS: 60 | /** 61 | * Represents a predicate (boolean-valued function) of one ${specialization} 62 | * argument. 63 | * 64 | *

This is a functional interface 65 | * whose functional method is {@link #test(${specialization})}. 66 | */ 67 | public static interface Chk${specialization}Predicate${_ThrowN} 68 | <${exc_decl_list}> 69 | { 70 | /** 71 | * Evaluates this predicate on the given argument. 72 | * 73 | * @param t the input argument 74 | * @return {@code true} if the input argument matches the predicate, 75 | * otherwise {@code false} 76 | */ 77 | boolean test(${specialization.lower()} value) ${throws_list}; 78 | } 79 | % endfor 80 | % endfor 81 | } 82 | -------------------------------------------------------------------------------- /third_party/openjdk/tmpl/com/google/chkstream/function/ChkRunnables.tmpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | package com.google.chkstream.function; 26 | 27 | public final class ChkRunnables { 28 | private ChkRunnables() {} 29 | 30 | % for num_e in xrange(MIN_EXCEPTIONS, MAX_EXCEPTIONS + 1): 31 | <% 32 | exc_decl_list = ', '.join( 33 | ['E%d extends Exception' % i for i in xrange(0, num_e)]) 34 | throws_list = 'throws ' + ', '.join(['E%d' % i for i in xrange(0, num_e)]) 35 | _ThrowN = '' if num_e == MIN_EXCEPTIONS else '_Throw%d' % num_e 36 | %> 37 | 38 | /** 39 | * The Runnable interface should be implemented by any 40 | * class whose instances are intended to be executed by a thread. The 41 | * class must define a method of no arguments called run. 42 | *

43 | * This interface is designed to provide a common protocol for objects that 44 | * wish to execute code while they are active. For example, 45 | * Runnable is implemented by class Thread. 46 | * Being active simply means that a thread has been started and has not 47 | * yet been stopped. 48 | *

49 | * In addition, Runnable provides the means for a class to be 50 | * active while not subclassing Thread. A class that implements 51 | * Runnable can run without subclassing Thread 52 | * by instantiating a Thread instance and passing itself in 53 | * as the target. In most cases, the Runnable interface should 54 | * be used if you are only planning to override the run() 55 | * method and no other Thread methods. 56 | * This is important because classes should not be subclassed 57 | * unless the programmer intends on modifying or enhancing the fundamental 58 | * behavior of the class. 59 | */ 60 | public static interface ChkRunnable${_ThrowN} 61 | <${exc_decl_list}> 62 | { 63 | /** 64 | * When an object implementing interface Runnable is used 65 | * to create a thread, starting the thread causes the object's 66 | * run method to be called in that separately executing 67 | * thread. 68 | *

69 | * The general contract of the method run is that it may 70 | * take any action whatsoever. 71 | */ 72 | void run() ${throws_list}; 73 | } 74 | % endfor 75 | } 76 | -------------------------------------------------------------------------------- /third_party/openjdk/tmpl/com/google/chkstream/function/FunctionUtils.tmpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google. 3 | * 4 | * This file is licensed under the GPLv2+Classpath Exception, which full text 5 | * is found in the LICENSE file at the root of this project. 6 | * 7 | * Google designates this particular file as subject to the "Classpath" 8 | * exception as provided in the LICENSE file that accompanied this code. 9 | */ 10 | 11 | <%! 12 | split = True 13 | for_each_stream_impl = True 14 | 15 | def get_filename(num_exceptions, min_exceptions, specialization=None): 16 | return 'FunctionUtils_Throw%d.java' % num_exceptions 17 | %> 18 | 19 | <% 20 | exc_extend_list = ', '.join(['?' for i in xrange(0, num_e)]) 21 | throws_list = 'throws ' + ', '.join(['E%d' % i for i in xrange(0, num_e)]) 22 | _ThrowN = '' if num_e == MIN_EXCEPTIONS else '_Throw%d' % num_e 23 | %> 24 | 25 | package com.google.chkstream.${stream_impl}.function; 26 | 27 | % if stream_impl == 'java8': 28 | import java.util.function.*; 29 | % else: 30 | import java8.util.function.*; 31 | % endif 32 | 33 | import com.google.chkstream.ChkStreamWrappedException; 34 | import com.google.chkstream.function.ChkConsumers.*; 35 | import com.google.chkstream.function.ChkFunctions.*; 36 | import com.google.chkstream.function.ChkPredicates.*; 37 | import com.google.chkstream.function.ChkRunnables.*; 38 | 39 | public class FunctionUtils_Throw${num_e} { 40 | 41 | // Consumer 42 | 43 | public Consumer wrapChkConsumer( 44 | final ChkConsumer${_ThrowN} consumer) { 45 | return new Consumer() { 46 | @Override 47 | public void accept(T t) { 48 | try { 49 | consumer.accept(t); 50 | } catch (Exception e) { 51 | throw new ChkStreamWrappedException(e); 52 | } 53 | } 54 | }; 55 | } 56 | 57 | % for specialization in SPECIALIZATIONS: 58 | public ${specialization}Consumer wrapChk${specialization}Consumer( 59 | final Chk${specialization}Consumer${_ThrowN}<${exc_extend_list}> 60 | consumer) { 61 | return new ${specialization}Consumer() { 62 | @Override 63 | public void accept(${specialization.lower()} t) { 64 | try { 65 | consumer.accept(t); 66 | } catch (Exception e) { 67 | throw new ChkStreamWrappedException(e); 68 | } 69 | } 70 | }; 71 | } 72 | % endfor 73 | 74 | // Function 75 | 76 | public Function wrapChkFunction( 77 | final ChkFunction${_ThrowN} function) { 78 | return new Function() { 79 | @Override 80 | public R apply(T t) { 81 | try { 82 | return function.apply(t); 83 | } catch (Exception e) { 84 | throw new ChkStreamWrappedException(e); 85 | } 86 | } 87 | }; 88 | } 89 | 90 | % for specialization in SPECIALIZATIONS: 91 | public To${specialization}Function 92 | wrapChkTo${specialization}Function( 93 | final ChkTo${specialization}Function${_ThrowN} 94 | 95 | function) { 96 | return new To${specialization}Function() { 97 | @Override 98 | public ${specialization.lower()} applyAs${specialization}(T t) { 99 | try { 100 | return function.applyAs${specialization}(t); 101 | } catch (Exception e) { 102 | throw new ChkStreamWrappedException(e); 103 | } 104 | } 105 | }; 106 | } 107 | 108 | public ${specialization}Function 109 | wrapChk${specialization}Function( 110 | final Chk${specialization}Function${_ThrowN} 111 | 112 | function) { 113 | return new ${specialization}Function() { 114 | @Override 115 | public U apply(${specialization.lower()} t) { 116 | try { 117 | return function.apply(t); 118 | } catch (Exception e) { 119 | throw new ChkStreamWrappedException(e); 120 | } 121 | } 122 | }; 123 | } 124 | 125 | public ${specialization}UnaryOperator 126 | wrapChk${specialization}UnaryOperator( 127 | final Chk${specialization}UnaryOperator${_ThrowN} 128 | <${exc_extend_list}> 129 | function) { 130 | return new ${specialization}UnaryOperator() { 131 | @Override 132 | public ${specialization.lower()} applyAs${specialization}( 133 | ${specialization.lower()} t) { 134 | try { 135 | return function.applyAs${specialization}(t); 136 | } catch (Exception e) { 137 | throw new ChkStreamWrappedException(e); 138 | } 139 | } 140 | }; 141 | } 142 | 143 | % for dest_specialization in SPECIALIZATIONS: 144 | % if dest_specialization != specialization: 145 | public ${specialization}To${dest_specialization}Function 146 | wrapChk${specialization}To${dest_specialization}Function( 147 | final Chk${specialization}To${dest_specialization}Function${_ThrowN} 148 | <${exc_extend_list}> 149 | function) { 150 | return new ${specialization}To${dest_specialization}Function() { 151 | @Override 152 | public ${dest_specialization.lower()} applyAs${dest_specialization}( 153 | ${specialization.lower()} t) { 154 | try { 155 | return function.applyAs${dest_specialization}(t); 156 | } catch (Exception e) { 157 | throw new ChkStreamWrappedException(e); 158 | } 159 | } 160 | }; 161 | } 162 | % endif 163 | % endfor 164 | % endfor 165 | 166 | // Predciates 167 | 168 | public Predicate wrapChkPredicate( 169 | final ChkPredicate${_ThrowN} predicate) { 170 | return new Predicate() { 171 | @Override 172 | public boolean test(T t) { 173 | try { 174 | return predicate.test(t); 175 | } catch (Exception e) { 176 | throw new ChkStreamWrappedException(e); 177 | } 178 | } 179 | }; 180 | } 181 | 182 | % for specialization in SPECIALIZATIONS: 183 | public ${specialization}Predicate wrapChk${specialization}Predicate( 184 | final Chk${specialization}Predicate${_ThrowN}<${exc_extend_list}> 185 | predicate) { 186 | return new ${specialization}Predicate() { 187 | @Override 188 | public boolean test(${specialization.lower()} value) { 189 | try { 190 | return predicate.test(value); 191 | } catch (Exception e) { 192 | throw new ChkStreamWrappedException(e); 193 | } 194 | } 195 | }; 196 | } 197 | % endfor 198 | 199 | // Runnables 200 | 201 | public Runnable wrapChkRunnable( 202 | final ChkRunnable${_ThrowN}<${exc_extend_list}> runnable) { 203 | return new Runnable() { 204 | @Override 205 | public void run() { 206 | try { 207 | runnable.run(); 208 | } catch (Exception e) { 209 | throw new ChkStreamWrappedException(e); 210 | } 211 | } 212 | }; 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /third_party/openjdk/tmpl/com/google/chkstream/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. Oracle designates this 8 | * particular file as subject to the "Classpath" exception as provided 9 | * by Oracle in the LICENSE file that accompanied this code. 10 | * 11 | * This code is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 | * version 2 for more details (a copy is included in the LICENSE file that 15 | * accompanied this code). 16 | * 17 | * You should have received a copy of the GNU General Public License version 18 | * 2 along with this work; if not, write to the Free Software Foundation, 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 | * 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 | * or visit www.oracle.com if you need additional information or have any 23 | * questions. 24 | */ 25 | 26 | /** 27 | * Classes to support functional-style operations on streams of elements, such 28 | * as map-reduce transformations on collections. For example: 29 | * 30 | *

{@code
 31 |  *     int sum = widgets.stream()
 32 |  *                      .filter(b -> b.getColor() == RED)
 33 |  *                      .mapToInt(b -> b.getWeight())
 34 |  *                      .sum();
 35 |  * }
36 | * 37 | *

Here we use {@code widgets}, a {@code Collection}, 38 | * as a source for a stream, and then perform a filter-map-reduce on the stream 39 | * to obtain the sum of the weights of the red widgets. (Summation is an 40 | * example of a reduction 41 | * operation.) 42 | * 43 | *

The key abstraction introduced in this package is stream. The 44 | * classes {@link java.util.stream.Stream}, {@link java.util.stream.IntStream}, 45 | * {@link java.util.stream.LongStream}, and {@link java.util.stream.DoubleStream} 46 | * are streams over objects and the primitive {@code int}, {@code long} and 47 | * {@code double} types. Streams differ from collections in several ways: 48 | * 49 | *

    50 | *
  • No storage. A stream is not a data structure that stores elements; 51 | * instead, it conveys elements from a source such as a data structure, 52 | * an array, a generator function, or an I/O channel, through a pipeline of 53 | * computational operations.
  • 54 | *
  • Functional in nature. An operation on a stream produces a result, 55 | * but does not modify its source. For example, filtering a {@code Stream} 56 | * obtained from a collection produces a new {@code Stream} without the 57 | * filtered elements, rather than removing elements from the source 58 | * collection.
  • 59 | *
  • Laziness-seeking. Many stream operations, such as filtering, mapping, 60 | * or duplicate removal, can be implemented lazily, exposing opportunities 61 | * for optimization. For example, "find the first {@code String} with 62 | * three consecutive vowels" need not examine all the input strings. 63 | * Stream operations are divided into intermediate ({@code Stream}-producing) 64 | * operations and terminal (value- or side-effect-producing) operations. 65 | * Intermediate operations are always lazy.
  • 66 | *
  • Possibly unbounded. While collections have a finite size, streams 67 | * need not. Short-circuiting operations such as {@code limit(n)} or 68 | * {@code findFirst()} can allow computations on infinite streams to 69 | * complete in finite time.
  • 70 | *
  • Consumable. The elements of a stream are only visited once during 71 | * the life of a stream. Like an {@link java.util.Iterator}, a new stream 72 | * must be generated to revisit the same elements of the source. 73 | *
  • 74 | *
75 | * 76 | * Streams can be obtained in a number of ways. Some examples include: 77 | *
    78 | *
  • From a {@link java.util.Collection} via the {@code stream()} and 79 | * {@code parallelStream()} methods;
  • 80 | *
  • From an array via {@link java.util.Arrays#stream(Object[])};
  • 81 | *
  • From static factory methods on the stream classes, such as 82 | * {@link java.util.stream.Stream#of(Object[])}, 83 | * {@link java.util.stream.IntStream#range(int, int)} 84 | * or {@link java.util.stream.Stream#iterate(Object, UnaryOperator)};
  • 85 | *
  • The lines of a file can be obtained from {@link java.io.BufferedReader#lines()};
  • 86 | *
  • Streams of file paths can be obtained from methods in {@link java.nio.file.Files};
  • 87 | *
  • Streams of random numbers can be obtained from {@link java.util.Random#ints()};
  • 88 | *
  • Numerous other stream-bearing methods in the JDK, including 89 | * {@link java.util.BitSet#stream()}, 90 | * {@link java.util.regex.Pattern#splitAsStream(java.lang.CharSequence)}, 91 | * and {@link java.util.jar.JarFile#stream()}.
  • 92 | *
93 | * 94 | *

Additional stream sources can be provided by third-party libraries using 95 | * these techniques. 96 | * 97 | *

Stream operations and pipelines

98 | * 99 | *

Stream operations are divided into intermediate and 100 | * terminal operations, and are combined to form stream 101 | * pipelines. A stream pipeline consists of a source (such as a 102 | * {@code Collection}, an array, a generator function, or an I/O channel); 103 | * followed by zero or more intermediate operations such as 104 | * {@code Stream.filter} or {@code Stream.map}; and a terminal operation such 105 | * as {@code Stream.forEach} or {@code Stream.reduce}. 106 | * 107 | *

Intermediate operations return a new stream. They are always 108 | * lazy; executing an intermediate operation such as 109 | * {@code filter()} does not actually perform any filtering, but instead 110 | * creates a new stream that, when traversed, contains the elements of 111 | * the initial stream that match the given predicate. Traversal 112 | * of the pipeline source does not begin until the terminal operation of the 113 | * pipeline is executed. 114 | * 115 | *

Terminal operations, such as {@code Stream.forEach} or 116 | * {@code IntStream.sum}, may traverse the stream to produce a result or a 117 | * side-effect. After the terminal operation is performed, the stream pipeline 118 | * is considered consumed, and can no longer be used; if you need to traverse 119 | * the same data source again, you must return to the data source to get a new 120 | * stream. In almost all cases, terminal operations are eager, 121 | * completing their traversal of the data source and processing of the pipeline 122 | * before returning. Only the terminal operations {@code iterator()} and 123 | * {@code spliterator()} are not; these are provided as an "escape hatch" to enable 124 | * arbitrary client-controlled pipeline traversals in the event that the 125 | * existing operations are not sufficient to the task. 126 | * 127 | *

Processing streams lazily allows for significant efficiencies; in a 128 | * pipeline such as the filter-map-sum example above, filtering, mapping, and 129 | * summing can be fused into a single pass on the data, with minimal 130 | * intermediate state. Laziness also allows avoiding examining all the data 131 | * when it is not necessary; for operations such as "find the first string 132 | * longer than 1000 characters", it is only necessary to examine just enough 133 | * strings to find one that has the desired characteristics without examining 134 | * all of the strings available from the source. (This behavior becomes even 135 | * more important when the input stream is infinite and not merely large.) 136 | * 137 | *

Intermediate operations are further divided into stateless 138 | * and stateful operations. Stateless operations, such as {@code filter} 139 | * and {@code map}, retain no state from previously seen element when processing 140 | * a new element -- each element can be processed 141 | * independently of operations on other elements. Stateful operations, such as 142 | * {@code distinct} and {@code sorted}, may incorporate state from previously 143 | * seen elements when processing new elements. 144 | * 145 | *

Stateful operations may need to process the entire input 146 | * before producing a result. For example, one cannot produce any results from 147 | * sorting a stream until one has seen all elements of the stream. As a result, 148 | * under parallel computation, some pipelines containing stateful intermediate 149 | * operations may require multiple passes on the data or may need to buffer 150 | * significant data. Pipelines containing exclusively stateless intermediate 151 | * operations can be processed in a single pass, whether sequential or parallel, 152 | * with minimal data buffering. 153 | * 154 | *

Further, some operations are deemed short-circuiting operations. 155 | * An intermediate operation is short-circuiting if, when presented with 156 | * infinite input, it may produce a finite stream as a result. A terminal 157 | * operation is short-circuiting if, when presented with infinite input, it may 158 | * terminate in finite time. Having a short-circuiting operation in the pipeline 159 | * is a necessary, but not sufficient, condition for the processing of an infinite 160 | * stream to terminate normally in finite time. 161 | * 162 | *

Parallelism

163 | * 164 | *

Processing elements with an explicit {@code for-}loop is inherently serial. 165 | * Streams facilitate parallel execution by reframing the computation as a pipeline of 166 | * aggregate operations, rather than as imperative operations on each individual 167 | * element. All streams operations can execute either in serial or in parallel. 168 | * The stream implementations in the JDK create serial streams unless parallelism is 169 | * explicitly requested. For example, {@code Collection} has methods 170 | * {@link java.util.Collection#stream} and {@link java.util.Collection#parallelStream}, 171 | * which produce sequential and parallel streams respectively; other 172 | * stream-bearing methods such as {@link java.util.stream.IntStream#range(int, int)} 173 | * produce sequential streams but these streams can be efficiently parallelized by 174 | * invoking their {@link java.util.stream.BaseStream#parallel()} method. 175 | * To execute the prior "sum of weights of widgets" query in parallel, we would 176 | * do: 177 | * 178 | *

{@code
179 |  *     int sumOfWeights = widgets.}parallelStream(){@code
180 |  *                               .filter(b -> b.getColor() == RED)
181 |  *                               .mapToInt(b -> b.getWeight())
182 |  *                               .sum();
183 |  * }
184 | * 185 | *

The only difference between the serial and parallel versions of this 186 | * example is the creation of the initial stream, using "{@code parallelStream()}" 187 | * instead of "{@code stream()}". When the terminal operation is initiated, 188 | * the stream pipeline is executed sequentially or in parallel depending on the 189 | * orientation of the stream on which it is invoked. Whether a stream will execute in serial or 190 | * parallel can be determined with the {@code isParallel()} method, and the 191 | * orientation of a stream can be modified with the 192 | * {@link java.util.stream.BaseStream#sequential()} and 193 | * {@link java.util.stream.BaseStream#parallel()} operations. When the terminal 194 | * operation is initiated, the stream pipeline is executed sequentially or in 195 | * parallel depending on the mode of the stream on which it is invoked. 196 | * 197 | *

Except for operations identified as explicitly nondeterministic, such 198 | * as {@code findAny()}, whether a stream executes sequentially or in parallel 199 | * should not change the result of the computation. 200 | * 201 | *

Most stream operations accept parameters that describe user-specified 202 | * behavior, which are often lambda expressions. To preserve correct behavior, 203 | * these behavioral parameters must be non-interfering, and in 204 | * most cases must be stateless. Such parameters are always instances 205 | * of a functional interface such 206 | * as {@link java.util.function.Function}, and are often lambda expressions or 207 | * method references. 208 | * 209 | *

Non-interference

210 | * 211 | * Streams enable you to execute possibly-parallel aggregate operations over a 212 | * variety of data sources, including even non-thread-safe collections such as 213 | * {@code ArrayList}. This is possible only if we can prevent 214 | * interference with the data source during the execution of a stream 215 | * pipeline. Except for the escape-hatch operations {@code iterator()} and 216 | * {@code spliterator()}, execution begins when the terminal operation is 217 | * invoked, and ends when the terminal operation completes. For most data 218 | * sources, preventing interference means ensuring that the data source is 219 | * not modified at all during the execution of the stream pipeline. 220 | * The notable exception to this are streams whose sources are concurrent 221 | * collections, which are specifically designed to handle concurrent modification. 222 | * Concurrent stream sources are those whose {@code Spliterator} reports the 223 | * {@code CONCURRENT} characteristic. 224 | * 225 | *

Accordingly, behavioral parameters in stream pipelines whose source might 226 | * not be concurrent should never modify the stream's data source. 227 | * A behavioral parameter is said to interfere with a non-concurrent 228 | * data source if it modifies, or causes to be 229 | * modified, the stream's data source. The need for non-interference applies 230 | * to all pipelines, not just parallel ones. Unless the stream source is 231 | * concurrent, modifying a stream's data source during execution of a stream 232 | * pipeline can cause exceptions, incorrect answers, or nonconformant behavior. 233 | * 234 | * For well-behaved stream sources, the source can be modified before the 235 | * terminal operation commences and those modifications will be reflected in 236 | * the covered elements. For example, consider the following code: 237 | * 238 | *

{@code
239 |  *     List l = new ArrayList(Arrays.asList("one", "two"));
240 |  *     Stream sl = l.stream();
241 |  *     l.add("three");
242 |  *     String s = sl.collect(joining(" "));
243 |  * }
244 | * 245 | * First a list is created consisting of two strings: "one"; and "two". Then a 246 | * stream is created from that list. Next the list is modified by adding a third 247 | * string: "three". Finally the elements of the stream are collected and joined 248 | * together. Since the list was modified before the terminal {@code collect} 249 | * operation commenced the result will be a string of "one two three". All the 250 | * streams returned from JDK collections, and most other JDK classes, 251 | * are well-behaved in this manner; for streams generated by other libraries, see 252 | * Low-level stream 253 | * construction for requirements for building well-behaved streams. 254 | * 255 | *

Stateless behaviors

256 | * 257 | * Stream pipeline results may be nondeterministic or incorrect if the behavioral 258 | * parameters to the stream operations are stateful. A stateful lambda 259 | * (or other object implementing the appropriate functional interface) is one 260 | * whose result depends on any state which might change during the execution 261 | * of the stream pipeline. An example of a stateful lambda is the parameter 262 | * to {@code map()} in: 263 | * 264 | *
{@code
265 |  *     Set seen = Collections.synchronizedSet(new HashSet<>());
266 |  *     stream.parallel().map(e -> { if (seen.add(e)) return 0; else return e; })...
267 |  * }
268 | * 269 | * Here, if the mapping operation is performed in parallel, the results for the 270 | * same input could vary from run to run, due to thread scheduling differences, 271 | * whereas, with a stateless lambda expression the results would always be the 272 | * same. 273 | * 274 | *

Note also that attempting to access mutable state from behavioral parameters 275 | * presents you with a bad choice with respect to safety and performance; if 276 | * you do not synchronize access to that state, you have a data race and 277 | * therefore your code is broken, but if you do synchronize access to that 278 | * state, you risk having contention undermine the parallelism you are seeking 279 | * to benefit from. The best approach is to avoid stateful behavioral 280 | * parameters to stream operations entirely; there is usually a way to 281 | * restructure the stream pipeline to avoid statefulness. 282 | * 283 | *

Side-effects

284 | * 285 | * Side-effects in behavioral parameters to stream operations are, in general, 286 | * discouraged, as they can often lead to unwitting violations of the 287 | * statelessness requirement, as well as other thread-safety hazards. 288 | * 289 | *

If the behavioral parameters do have side-effects, unless explicitly 290 | * stated, there are no guarantees as to the 291 | * visibility 292 | * of those side-effects to other threads, nor are there any guarantees that 293 | * different operations on the "same" element within the same stream pipeline 294 | * are executed in the same thread. Further, the ordering of those effects 295 | * may be surprising. Even when a pipeline is constrained to produce a 296 | * result that is consistent with the encounter order of the stream 297 | * source (for example, {@code IntStream.range(0,5).parallel().map(x -> x*2).toArray()} 298 | * must produce {@code [0, 2, 4, 6, 8]}), no guarantees are made as to the order 299 | * in which the mapper function is applied to individual elements, or in what 300 | * thread any behavioral parameter is executed for a given element. 301 | * 302 | *

Many computations where one might be tempted to use side effects can be more 303 | * safely and efficiently expressed without side-effects, such as using 304 | * reduction instead of mutable 305 | * accumulators. However, side-effects such as using {@code println()} for debugging 306 | * purposes are usually harmless. A small number of stream operations, such as 307 | * {@code forEach()} and {@code peek()}, can operate only via side-effects; 308 | * these should be used with care. 309 | * 310 | *

As an example of how to transform a stream pipeline that inappropriately 311 | * uses side-effects to one that does not, the following code searches a stream 312 | * of strings for those matching a given regular expression, and puts the 313 | * matches in a list. 314 | * 315 | *

{@code
316 |  *     ArrayList results = new ArrayList<>();
317 |  *     stream.filter(s -> pattern.matcher(s).matches())
318 |  *           .forEach(s -> results.add(s));  // Unnecessary use of side-effects!
319 |  * }
320 | * 321 | * This code unnecessarily uses side-effects. If executed in parallel, the 322 | * non-thread-safety of {@code ArrayList} would cause incorrect results, and 323 | * adding needed synchronization would cause contention, undermining the 324 | * benefit of parallelism. Furthermore, using side-effects here is completely 325 | * unnecessary; the {@code forEach()} can simply be replaced with a reduction 326 | * operation that is safer, more efficient, and more amenable to 327 | * parallelization: 328 | * 329 | *
{@code
330 |  *     Listresults =
331 |  *         stream.filter(s -> pattern.matcher(s).matches())
332 |  *               .collect(Collectors.toList());  // No side-effects!
333 |  * }
334 | * 335 | *

Ordering

336 | * 337 | *

Streams may or may not have a defined encounter order. Whether 338 | * or not a stream has an encounter order depends on the source and the 339 | * intermediate operations. Certain stream sources (such as {@code List} or 340 | * arrays) are intrinsically ordered, whereas others (such as {@code HashSet}) 341 | * are not. Some intermediate operations, such as {@code sorted()}, may impose 342 | * an encounter order on an otherwise unordered stream, and others may render an 343 | * ordered stream unordered, such as {@link java.util.stream.BaseStream#unordered()}. 344 | * Further, some terminal operations may ignore encounter order, such as 345 | * {@code forEach()}. 346 | * 347 | *

If a stream is ordered, most operations are constrained to operate on the 348 | * elements in their encounter order; if the source of a stream is a {@code List} 349 | * containing {@code [1, 2, 3]}, then the result of executing {@code map(x -> x*2)} 350 | * must be {@code [2, 4, 6]}. However, if the source has no defined encounter 351 | * order, then any permutation of the values {@code [2, 4, 6]} would be a valid 352 | * result. 353 | * 354 | *

For sequential streams, the presence or absence of an encounter order does 355 | * not affect performance, only determinism. If a stream is ordered, repeated 356 | * execution of identical stream pipelines on an identical source will produce 357 | * an identical result; if it is not ordered, repeated execution might produce 358 | * different results. 359 | * 360 | *

For parallel streams, relaxing the ordering constraint can sometimes enable 361 | * more efficient execution. Certain aggregate operations, 362 | * such as filtering duplicates ({@code distinct()}) or grouped reductions 363 | * ({@code Collectors.groupingBy()}) can be implemented more efficiently if ordering of elements 364 | * is not relevant. Similarly, operations that are intrinsically tied to encounter order, 365 | * such as {@code limit()}, may require 366 | * buffering to ensure proper ordering, undermining the benefit of parallelism. 367 | * In cases where the stream has an encounter order, but the user does not 368 | * particularly care about that encounter order, explicitly de-ordering 369 | * the stream with {@link java.util.stream.BaseStream#unordered() unordered()} may 370 | * improve parallel performance for some stateful or terminal operations. 371 | * However, most stream pipelines, such as the "sum of weight of blocks" example 372 | * above, still parallelize efficiently even under ordering constraints. 373 | * 374 | *

Reduction operations

375 | * 376 | * A reduction operation (also called a fold) takes a sequence 377 | * of input elements and combines them into a single summary result by repeated 378 | * application of a combining operation, such as finding the sum or maximum of 379 | * a set of numbers, or accumulating elements into a list. The streams classes have 380 | * multiple forms of general reduction operations, called 381 | * {@link java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduce()} 382 | * and {@link java.util.stream.Stream#collect(java.util.stream.Collector) collect()}, 383 | * as well as multiple specialized reduction forms such as 384 | * {@link java.util.stream.IntStream#sum() sum()}, {@link java.util.stream.IntStream#max() max()}, 385 | * or {@link java.util.stream.IntStream#count() count()}. 386 | * 387 | *

Of course, such operations can be readily implemented as simple sequential 388 | * loops, as in: 389 | *

{@code
390 |  *    int sum = 0;
391 |  *    for (int x : numbers) {
392 |  *       sum += x;
393 |  *    }
394 |  * }
395 | * However, there are good reasons to prefer a reduce operation 396 | * over a mutative accumulation such as the above. Not only is a reduction 397 | * "more abstract" -- it operates on the stream as a whole rather than individual 398 | * elements -- but a properly constructed reduce operation is inherently 399 | * parallelizable, so long as the function(s) used to process the elements 400 | * are associative and 401 | * stateless. 402 | * For example, given a stream of numbers for which we want to find the sum, we 403 | * can write: 404 | *
{@code
405 |  *    int sum = numbers.stream().reduce(0, (x,y) -> x+y);
406 |  * }
407 | * or: 408 | *
{@code
409 |  *    int sum = numbers.stream().reduce(0, Integer::sum);
410 |  * }
411 | * 412 | *

These reduction operations can run safely in parallel with almost no 413 | * modification: 414 | *

{@code
415 |  *    int sum = numbers.parallelStream().reduce(0, Integer::sum);
416 |  * }
417 | * 418 | *

Reduction parallellizes well because the implementation 419 | * can operate on subsets of the data in parallel, and then combine the 420 | * intermediate results to get the final correct answer. (Even if the language 421 | * had a "parallel for-each" construct, the mutative accumulation approach would 422 | * still required the developer to provide 423 | * thread-safe updates to the shared accumulating variable {@code sum}, and 424 | * the required synchronization would then likely eliminate any performance gain from 425 | * parallelism.) Using {@code reduce()} instead removes all of the 426 | * burden of parallelizing the reduction operation, and the library can provide 427 | * an efficient parallel implementation with no additional synchronization 428 | * required. 429 | * 430 | *

The "widgets" examples shown earlier shows how reduction combines with 431 | * other operations to replace for loops with bulk operations. If {@code widgets} 432 | * is a collection of {@code Widget} objects, which have a {@code getWeight} method, 433 | * we can find the heaviest widget with: 434 | *

{@code
435 |  *     OptionalInt heaviest = widgets.parallelStream()
436 |  *                                   .mapToInt(Widget::getWeight)
437 |  *                                   .max();
438 |  * }
439 | * 440 | *

In its more general form, a {@code reduce} operation on elements of type 441 | * {@code } yielding a result of type {@code } requires three parameters: 442 | *

{@code
443 |  *  U reduce(U identity,
444 |  *              BiFunction accumulator,
445 |  *              BinaryOperator combiner);
446 |  * }
447 | * Here, the identity element is both an initial seed value for the reduction 448 | * and a default result if there are no input elements. The accumulator 449 | * function takes a partial result and the next element, and produces a new 450 | * partial result. The combiner function combines two partial results 451 | * to produce a new partial result. (The combiner is necessary in parallel 452 | * reductions, where the input is partitioned, a partial accumulation computed 453 | * for each partition, and then the partial results are combined to produce a 454 | * final result.) 455 | * 456 | *

More formally, the {@code identity} value must be an identity for 457 | * the combiner function. This means that for all {@code u}, 458 | * {@code combiner.apply(identity, u)} is equal to {@code u}. Additionally, the 459 | * {@code combiner} function must be associative and 460 | * must be compatible with the {@code accumulator} function: for all {@code u} 461 | * and {@code t}, {@code combiner.apply(u, accumulator.apply(identity, t))} must 462 | * be {@code equals()} to {@code accumulator.apply(u, t)}. 463 | * 464 | *

The three-argument form is a generalization of the two-argument form, 465 | * incorporating a mapping step into the accumulation step. We could 466 | * re-cast the simple sum-of-weights example using the more general form as 467 | * follows: 468 | *

{@code
469 |  *     int sumOfWeights = widgets.stream()
470 |  *                               .reduce(0,
471 |  *                                       (sum, b) -> sum + b.getWeight())
472 |  *                                       Integer::sum);
473 |  * }
474 | * though the explicit map-reduce form is more readable and therefore should 475 | * usually be preferred. The generalized form is provided for cases where 476 | * significant work can be optimized away by combining mapping and reducing 477 | * into a single function. 478 | * 479 | *

Mutable reduction

480 | * 481 | * A mutable reduction operation accumulates input elements into a 482 | * mutable result container, such as a {@code Collection} or {@code StringBuilder}, 483 | * as it processes the elements in the stream. 484 | * 485 | *

If we wanted to take a stream of strings and concatenate them into a 486 | * single long string, we could achieve this with ordinary reduction: 487 | *

{@code
488 |  *     String concatenated = strings.reduce("", String::concat)
489 |  * }
490 | * 491 | *

We would get the desired result, and it would even work in parallel. However, 492 | * we might not be happy about the performance! Such an implementation would do 493 | * a great deal of string copying, and the run time would be O(n^2) in 494 | * the number of characters. A more performant approach would be to accumulate 495 | * the results into a {@link java.lang.StringBuilder}, which is a mutable 496 | * container for accumulating strings. We can use the same technique to 497 | * parallelize mutable reduction as we do with ordinary reduction. 498 | * 499 | *

The mutable reduction operation is called 500 | * {@link java.util.stream.Stream#collect(Collector) collect()}, 501 | * as it collects together the desired results into a result container such 502 | * as a {@code Collection}. 503 | * A {@code collect} operation requires three functions: 504 | * a supplier function to construct new instances of the result container, an 505 | * accumulator function to incorporate an input element into a result 506 | * container, and a combining function to merge the contents of one result 507 | * container into another. The form of this is very similar to the general 508 | * form of ordinary reduction: 509 | *

{@code
510 |  *  R collect(Supplier supplier,
511 |  *               BiConsumer accumulator,
512 |  *               BiConsumer combiner);
513 |  * }
514 | *

As with {@code reduce()}, a benefit of expressing {@code collect} in this 515 | * abstract way is that it is directly amenable to parallelization: we can 516 | * accumulate partial results in parallel and then combine them, so long as the 517 | * accumulation and combining functions satisfy the appropriate requirements. 518 | * For example, to collect the String representations of the elements in a 519 | * stream into an {@code ArrayList}, we could write the obvious sequential 520 | * for-each form: 521 | *

{@code
522 |  *     ArrayList strings = new ArrayList<>();
523 |  *     for (T element : stream) {
524 |  *         strings.add(element.toString());
525 |  *     }
526 |  * }
527 | * Or we could use a parallelizable collect form: 528 | *
{@code
529 |  *     ArrayList strings = stream.collect(() -> new ArrayList<>(),
530 |  *                                                (c, e) -> c.add(e.toString()),
531 |  *                                                (c1, c2) -> c1.addAll(c2));
532 |  * }
533 | * or, pulling the mapping operation out of the accumulator function, we could 534 | * express it more succinctly as: 535 | *
{@code
536 |  *     List strings = stream.map(Object::toString)
537 |  *                                  .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
538 |  * }
539 | * Here, our supplier is just the {@link java.util.ArrayList#ArrayList() 540 | * ArrayList constructor}, the accumulator adds the stringified element to an 541 | * {@code ArrayList}, and the combiner simply uses {@link java.util.ArrayList#addAll addAll} 542 | * to copy the strings from one container into the other. 543 | * 544 | *

The three aspects of {@code collect} -- supplier, accumulator, and 545 | * combiner -- are tightly coupled. We can use the abstraction of a 546 | * {@link java.util.stream.Collector} to capture all three aspects. The 547 | * above example for collecting strings into a {@code List} can be rewritten 548 | * using a standard {@code Collector} as: 549 | *

{@code
550 |  *     List strings = stream.map(Object::toString)
551 |  *                                  .collect(Collectors.toList());
552 |  * }
553 | * 554 | *

Packaging mutable reductions into a Collector has another advantage: 555 | * composability. The class {@link java.util.stream.Collectors} contains a 556 | * number of predefined factories for collectors, including combinators 557 | * that transform one collector into another. For example, suppose we have a 558 | * collector that computes the sum of the salaries of a stream of 559 | * employees, as follows: 560 | * 561 | *

{@code
562 |  *     Collector summingSalaries
563 |  *         = Collectors.summingInt(Employee::getSalary);
564 |  * }
565 | * 566 | * (The {@code ?} for the second type parameter merely indicates that we don't 567 | * care about the intermediate representation used by this collector.) 568 | * If we wanted to create a collector to tabulate the sum of salaries by 569 | * department, we could reuse {@code summingSalaries} using 570 | * {@link java.util.stream.Collectors#groupingBy(java.util.function.Function, java.util.stream.Collector) groupingBy}: 571 | * 572 | *
{@code
573 |  *     Map salariesByDept
574 |  *         = employees.stream().collect(Collectors.groupingBy(Employee::getDepartment,
575 |  *                                                            summingSalaries));
576 |  * }
577 | * 578 | *

As with the regular reduction operation, {@code collect()} operations can 579 | * only be parallelized if appropriate conditions are met. For any partially 580 | * accumulated result, combining it with an empty result container must 581 | * produce an equivalent result. That is, for a partially accumulated result 582 | * {@code p} that is the result of any series of accumulator and combiner 583 | * invocations, {@code p} must be equivalent to 584 | * {@code combiner.apply(p, supplier.get())}. 585 | * 586 | *

Further, however the computation is split, it must produce an equivalent 587 | * result. For any input elements {@code t1} and {@code t2}, the results 588 | * {@code r1} and {@code r2} in the computation below must be equivalent: 589 | *

{@code
590 |  *     A a1 = supplier.get();
591 |  *     accumulator.accept(a1, t1);
592 |  *     accumulator.accept(a1, t2);
593 |  *     R r1 = finisher.apply(a1);  // result without splitting
594 |  *
595 |  *     A a2 = supplier.get();
596 |  *     accumulator.accept(a2, t1);
597 |  *     A a3 = supplier.get();
598 |  *     accumulator.accept(a3, t2);
599 |  *     R r2 = finisher.apply(combiner.apply(a2, a3));  // result with splitting
600 |  * }
601 | * 602 | *

Here, equivalence generally means according to {@link java.lang.Object#equals(Object)}. 603 | * but in some cases equivalence may be relaxed to account for differences in 604 | * order. 605 | * 606 | *

Reduction, concurrency, and ordering

607 | * 608 | * With some complex reduction operations, for example a {@code collect()} that 609 | * produces a {@code Map}, such as: 610 | *
{@code
611 |  *     Map> salesByBuyer
612 |  *         = txns.parallelStream()
613 |  *               .collect(Collectors.groupingBy(Transaction::getBuyer));
614 |  * }
615 | * it may actually be counterproductive to perform the operation in parallel. 616 | * This is because the combining step (merging one {@code Map} into another by 617 | * key) can be expensive for some {@code Map} implementations. 618 | * 619 | *

Suppose, however, that the result container used in this reduction 620 | * was a concurrently modifiable collection -- such as a 621 | * {@link java.util.concurrent.ConcurrentHashMap}. In that case, the parallel 622 | * invocations of the accumulator could actually deposit their results 623 | * concurrently into the same shared result container, eliminating the need for 624 | * the combiner to merge distinct result containers. This potentially provides 625 | * a boost to the parallel execution performance. We call this a 626 | * concurrent reduction. 627 | * 628 | *

A {@link java.util.stream.Collector} that supports concurrent reduction is 629 | * marked with the {@link java.util.stream.Collector.Characteristics#CONCURRENT} 630 | * characteristic. However, a concurrent collection also has a downside. If 631 | * multiple threads are depositing results concurrently into a shared container, 632 | * the order in which results are deposited is non-deterministic. Consequently, 633 | * a concurrent reduction is only possible if ordering is not important for the 634 | * stream being processed. The {@link java.util.stream.Stream#collect(Collector)} 635 | * implementation will only perform a concurrent reduction if 636 | *

    637 | *
  • The stream is parallel;
  • 638 | *
  • The collector has the 639 | * {@link java.util.stream.Collector.Characteristics#CONCURRENT} characteristic, 640 | * and;
  • 641 | *
  • Either the stream is unordered, or the collector has the 642 | * {@link java.util.stream.Collector.Characteristics#UNORDERED} characteristic. 643 | *
644 | * You can ensure the stream is unordered by using the 645 | * {@link java.util.stream.BaseStream#unordered()} method. For example: 646 | *
{@code
647 |  *     Map> salesByBuyer
648 |  *         = txns.parallelStream()
649 |  *               .unordered()
650 |  *               .collect(groupingByConcurrent(Transaction::getBuyer));
651 |  * }
652 | * (where {@link java.util.stream.Collectors#groupingByConcurrent} is the 653 | * concurrent equivalent of {@code groupingBy}). 654 | * 655 | *

Note that if it is important that the elements for a given key appear in 656 | * the order they appear in the source, then we cannot use a concurrent 657 | * reduction, as ordering is one of the casualties of concurrent insertion. 658 | * We would then be constrained to implement either a sequential reduction or 659 | * a merge-based parallel reduction. 660 | * 661 | *

Associativity

662 | * 663 | * An operator or function {@code op} is associative if the following 664 | * holds: 665 | *
{@code
666 |  *     (a op b) op c == a op (b op c)
667 |  * }
668 | * The importance of this to parallel evaluation can be seen if we expand this 669 | * to four terms: 670 | *
{@code
671 |  *     a op b op c op d == (a op b) op (c op d)
672 |  * }
673 | * So we can evaluate {@code (a op b)} in parallel with {@code (c op d)}, and 674 | * then invoke {@code op} on the results. 675 | * 676 | *

Examples of associative operations include numeric addition, min, and 677 | * max, and string concatenation. 678 | * 679 | *

Low-level stream construction

680 | * 681 | * So far, all the stream examples have used methods like 682 | * {@link java.util.Collection#stream()} or {@link java.util.Arrays#stream(Object[])} 683 | * to obtain a stream. How are those stream-bearing methods implemented? 684 | * 685 | *

The class {@link java.util.stream.StreamSupport} has a number of 686 | * low-level methods for creating a stream, all using some form of a 687 | * {@link java.util.Spliterator}. A spliterator is the parallel analogue of an 688 | * {@link java.util.Iterator}; it describes a (possibly infinite) collection of 689 | * elements, with support for sequentially advancing, bulk traversal, and 690 | * splitting off some portion of the input into another spliterator which can 691 | * be processed in parallel. At the lowest level, all streams are driven by a 692 | * spliterator. 693 | * 694 | *

There are a number of implementation choices in implementing a 695 | * spliterator, nearly all of which are tradeoffs between simplicity of 696 | * implementation and runtime performance of streams using that spliterator. 697 | * The simplest, but least performant, way to create a spliterator is to 698 | * create one from an iterator using 699 | * {@link java.util.Spliterators#spliteratorUnknownSize(java.util.Iterator, int)}. 700 | * While such a spliterator will work, it will likely offer poor parallel 701 | * performance, since we have lost sizing information (how big is the 702 | * underlying data set), as well as being constrained to a simplistic 703 | * splitting algorithm. 704 | * 705 | *

A higher-quality spliterator will provide balanced and known-size 706 | * splits, accurate sizing information, and a number of other 707 | * {@link java.util.Spliterator#characteristics() characteristics} of the 708 | * spliterator or data that can be used by implementations to optimize 709 | * execution. 710 | * 711 | *

Spliterators for mutable data sources have an additional challenge; 712 | * timing of binding to the data, since the data could change between the time 713 | * the spliterator is created and the time the stream pipeline is executed. 714 | * Ideally, a spliterator for a stream would report a characteristic of 715 | 716 | * {@code IMMUTABLE} or {@code CONCURRENT}; if not it should be 717 | * late-binding. If a source 718 | * cannot directly supply a recommended spliterator, it may indirectly supply 719 | * a spliterator using a {@code Supplier}, and construct a stream via the 720 | * {@code Supplier}-accepting versions of 721 | * {@link java.util.stream.StreamSupport#stream(Supplier, int, boolean) stream()}. 722 | * The spliterator is obtained from the supplier only after the terminal 723 | * operation of the stream pipeline commences. 724 | * 725 | *

These requirements significantly reduce the scope of potential 726 | * interference between mutations of the stream source and execution of stream 727 | * pipelines. Streams based on spliterators with the desired characteristics, 728 | * or those using the Supplier-based factory forms, are immune to 729 | * modifications of the data source prior to commencement of the terminal 730 | * operation (provided the behavioral parameters to the stream operations meet 731 | * the required criteria for non-interference and statelessness). See 732 | * Non-Interference 733 | * for more details. 734 | */ 735 | package com.google.chkstream; 736 | --------------------------------------------------------------------------------