mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-25 17:50:45 +00:00
8012665: add CharSequence.chars, CharSequence.codePoints
Co-authored-by: Henry Jen <henry.jen@oracle.com> Reviewed-by: martin, alanb, ulfzibis, mduigou
This commit is contained in:
parent
905250cdfe
commit
73e9aec3c4
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,13 @@
|
||||
|
||||
package java.lang;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.function.IntConsumer;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* A <tt>CharSequence</tt> is a readable sequence of <code>char</code> values. This
|
||||
@ -108,4 +115,95 @@ public interface CharSequence {
|
||||
*/
|
||||
public String toString();
|
||||
|
||||
/**
|
||||
* Returns a stream of {@code int} zero-extending the {@code char} values
|
||||
* from this sequence. Any char which maps to a <a
|
||||
* href="{@docRoot}/java/lang/Character.html#unicode">surrogate code
|
||||
* point</a> is passed through uninterpreted.
|
||||
*
|
||||
* <p>If the sequence is mutated while the stream is being read, the
|
||||
* result is undefined.
|
||||
*
|
||||
* @return an IntStream of char values from this sequence
|
||||
* @since 1.8
|
||||
*/
|
||||
public default IntStream chars() {
|
||||
class CharIterator implements PrimitiveIterator.OfInt {
|
||||
int cur = 0;
|
||||
|
||||
public boolean hasNext() {
|
||||
return cur < length();
|
||||
}
|
||||
|
||||
public int nextInt() {
|
||||
if (hasNext()) {
|
||||
return charAt(cur++);
|
||||
} else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachRemaining(IntConsumer block) {
|
||||
for (; cur < length(); cur++) {
|
||||
block.accept(charAt(cur));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return StreamSupport.intStream(() ->
|
||||
Spliterators.spliterator(
|
||||
new CharIterator(),
|
||||
length(),
|
||||
Spliterator.ORDERED),
|
||||
Spliterator.SUBSIZED | Spliterator.SIZED | Spliterator.ORDERED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a stream of code point values from this sequence. Any surrogate
|
||||
* pairs encountered in the sequence are combined as if by {@linkplain
|
||||
* Character#toCodePoint Character.toCodePoint} and the result is passed
|
||||
* to the stream. Any other code units, including ordinary BMP characters,
|
||||
* unpaired surrogates, and undefined code units, are zero-extended to
|
||||
* {@code int} values which are then passed to the stream.
|
||||
*
|
||||
* <p>If the sequence is mutated while the stream is being read, the result
|
||||
* is undefined.
|
||||
*
|
||||
* @return an IntStream of Unicode code points from this sequence
|
||||
* @since 1.8
|
||||
*/
|
||||
public default IntStream codePoints() {
|
||||
class CodePointIterator implements PrimitiveIterator.OfInt {
|
||||
int cur = 0;
|
||||
|
||||
@Override
|
||||
public void forEachRemaining(IntConsumer block) {
|
||||
while (cur < length()) {
|
||||
int cp = Character.codePointAt(CharSequence.this, cur);
|
||||
cur += Character.charCount(cp);
|
||||
block.accept(cp);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return cur < length();
|
||||
}
|
||||
|
||||
public int nextInt() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
int cp = Character.codePointAt(CharSequence.this, cur);
|
||||
cur += Character.charCount(cp);
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
|
||||
return StreamSupport.intStream(() ->
|
||||
Spliterators.spliteratorUnknownSize(
|
||||
new CodePointIterator(),
|
||||
Spliterator.ORDERED),
|
||||
Spliterator.SUBSIZED | Spliterator.SIZED | Spliterator.ORDERED);
|
||||
}
|
||||
}
|
||||
|
||||
96
jdk/test/java/lang/CharSequence/DefaultTest.java
Normal file
96
jdk/test/java/lang/CharSequence/DefaultTest.java
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Unit test for CharSequence default methods
|
||||
* @bug 8012665
|
||||
* @run testng DefaultTest
|
||||
*/
|
||||
|
||||
@Test(groups = "lib")
|
||||
public class DefaultTest {
|
||||
|
||||
@Test(expectedExceptions = NoSuchElementException.class)
|
||||
public void testEmptyChars() {
|
||||
PrimitiveIterator.OfInt s = "".chars().iterator();
|
||||
assertFalse(s.hasNext());
|
||||
int ch = s.nextInt();
|
||||
}
|
||||
|
||||
public void testSimpleChars() {
|
||||
List<Integer> list = "abc".chars().boxed().collect(Collectors.toList());
|
||||
assertEquals(list, Arrays.asList((int) 'a', (int) 'b', (int) 'c'));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NoSuchElementException.class)
|
||||
public void testEmptyCodePoints() {
|
||||
PrimitiveIterator.OfInt s = "".codePoints().iterator();
|
||||
assertFalse(s.hasNext());
|
||||
int cp = s.nextInt();
|
||||
}
|
||||
|
||||
public void testSimpleCodePoints() {
|
||||
List<Integer> list = "abc".codePoints().boxed().collect(Collectors.toList());
|
||||
assertEquals(list, Arrays.asList((int)'a', (int)'b', (int)'c'));
|
||||
}
|
||||
|
||||
public void testUndefCodePoints() {
|
||||
List<Integer> list = "X\ufffeY".codePoints().boxed().collect(Collectors.toList());
|
||||
assertEquals(list, Arrays.asList((int)'X', 0xFFFE, (int)'Y'));
|
||||
}
|
||||
|
||||
public void testSurrogatePairing() {
|
||||
// U+1D11E = MUSICAL SYMBOL G CLEF
|
||||
// equivalent to surrogate pair U+D834 U+DD1E
|
||||
List<Integer> list;
|
||||
final int GCLEF = 0x1d11e;
|
||||
|
||||
list = "\ud834\udd1e".codePoints().boxed().collect(Collectors.toList());
|
||||
assertEquals(list, Arrays.asList(GCLEF));
|
||||
list = "A\ud834\udd1e".codePoints().boxed().collect(Collectors.toList());
|
||||
assertEquals(list, Arrays.asList((int)'A', GCLEF));
|
||||
list = "\ud834\udd1eB".codePoints().boxed().collect(Collectors.toList());
|
||||
assertEquals(list, Arrays.asList(GCLEF, (int)'B'));
|
||||
list = "X\ud834\udd1eY".codePoints().boxed().collect(Collectors.toList());
|
||||
assertEquals(list, Arrays.asList((int)'X', GCLEF, (int)'Y'));
|
||||
}
|
||||
|
||||
public void testUndefUnpaired() {
|
||||
List<Integer> list = "W\udd1eX\ud834Y\ufffeZ".codePoints().boxed().collect(Collectors.toList());
|
||||
assertEquals(list, Arrays.asList(
|
||||
(int)'W', 0xdd1e, (int)'X', 0xd834, (int)'Y', 0xfffe, (int)'Z'));
|
||||
}
|
||||
}
|
||||
@ -96,6 +96,10 @@ public class TestSynchronization {
|
||||
// the right thing.
|
||||
List<Method> methods = Arrays.asList(aClass.getDeclaredMethods());
|
||||
for (Method m : methods) {
|
||||
// skip synthetic methods, like default interface methods and lambdas
|
||||
if (m.isSynthetic()) {
|
||||
continue;
|
||||
}
|
||||
int modifiers = m.getModifiers();
|
||||
if (Modifier.isPublic(modifiers)
|
||||
&& !Modifier.isSynchronized(modifiers)) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user