commit c1a00eea1fc0a7268977645b4358463fdc14f84e Author: Joe Tretter Date: Thu Mar 2 18:06:10 2023 -0600 Initial Checkin diff --git a/DB/PostgreSqlExample copy.java b/DB/PostgreSqlExample copy.java new file mode 100644 index 0000000..a8d4343 --- /dev/null +++ b/DB/PostgreSqlExample copy.java @@ -0,0 +1,44 @@ +/* +Compile: +javac PostgreSqlExample.java + +Run: +java -cp postgresql-42.5.4.jar;. PostgreSqlExample + +*/ + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +public class PostgreSqlExample { + public static void main(String[] args) { + try (Connection connection = DriverManager.getConnection("jdbc:postgresql://192.168.10.138:5432/example", "postgres", "postgres")) { + + System.out.println("Java JDBC PostgreSQL Example"); + // When this class first attempts to establish a connection, it automatically loads any JDBC 4.0 drivers found within + // the class path. Note that your application must manually load any JDBC drivers prior to version 4.0. +// Class.forName("org.postgresql.Driver"); + + System.out.println("Connected to PostgreSQL database!"); + Statement statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + statement.setFetchSize(10); + System.out.println("Reading records."); + //ResultSet resultSet = statement.executeQuery("SELECT * FROM test1 a, test1 b, test1 c, test1 d, test1 e, test1 f, test1 g, test1 h, test1 i, test1 j limit (10)"); + ResultSet resultSet = statement.executeQuery("SELECT * FROM test1 a, test1 b, test1 c, test1 d, test1 e, test1 f, test1 g, test1 h, test1 i, test1 j"); + while (resultSet.next()) { + System.out.print(resultSet.getInt(1)); + System.out.println("-"+ resultSet.getString(2)); + } + + } /*catch (ClassNotFoundException e) { + System.out.println("PostgreSQL JDBC driver not found."); + e.printStackTrace(); + }*/ catch (SQLException e) { + System.out.println("Connection failure."); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/DB/PostgreSqlExample.class b/DB/PostgreSqlExample.class new file mode 100644 index 0000000..71f0165 Binary files /dev/null and b/DB/PostgreSqlExample.class differ diff --git a/DB/PostgreSqlExample.java b/DB/PostgreSqlExample.java new file mode 100644 index 0000000..eac1004 --- /dev/null +++ b/DB/PostgreSqlExample.java @@ -0,0 +1,42 @@ +/* +Compile: +javac PostgreSqlExample.java + +Run: +java -cp postgresql-42.5.4.jar;. PostgreSqlExample + +*/ + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +public class PostgreSqlExample { + public static void main(String[] args) { + try (Connection connection = DriverManager.getConnection("jdbc:postgresql://192.168.10.138:5432/example", "postgres", "postgres")) { + System.out.println("Java JDBC PostgreSQL Example"); + + System.out.println("Connected to PostgreSQL database!"); + Statement statement = connection.createStatement(); + + // For huge resultset the following two lines do the trick: + statement.setFetchSize(100); + connection.setAutoCommit(false); + System.out.println("Reading records."); + + //ResultSet resultSet = statement.executeQuery("SELECT * FROM test1 a, test1 b, test1 c, test1 d, test1 e, test1 f, test1 g, test1 h, test1 i, test1 j limit (10)"); + // Produce HUGE resultest + ResultSet resultSet = statement.executeQuery("SELECT * FROM test1 a, test1 b, test1 c, test1 d, test1 e, test1 f, test1 g, test1 h, test1 i, test1 j"); + while (resultSet.next()) { + System.out.print(resultSet.getInt(1)); + System.out.println("-"+ resultSet.getString(2)); + } + + } catch (SQLException e) { + System.out.println("Connection failure."); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/DB/postgresql-42.5.4.jar b/DB/postgresql-42.5.4.jar new file mode 100644 index 0000000..df33dad Binary files /dev/null and b/DB/postgresql-42.5.4.jar differ diff --git a/FinalFlag1.class b/FinalFlag1.class new file mode 100644 index 0000000..229a9c9 Binary files /dev/null and b/FinalFlag1.class differ diff --git a/FinalFlag1.java b/FinalFlag1.java new file mode 100644 index 0000000..5ec0532 --- /dev/null +++ b/FinalFlag1.java @@ -0,0 +1,9 @@ +class FinalFlag1{ + private String x; + public FinalFlag1(){ + x="Final?"; + } + public final void test(){ + System.out.println(x); + } +} \ No newline at end of file diff --git a/HashMapTest1.java b/HashMapTest1.java new file mode 100644 index 0000000..58216a7 --- /dev/null +++ b/HashMapTest1.java @@ -0,0 +1,20 @@ +import java.util.*; + +public class HashMapTest1 { + public static void main(String []args) { + String string1= "ABFED"; + String string2= "AFBHI"; + + HashMap hm1 = new HashMap<>(); + + for (char theChar : string1.toCharArray()){ + hm1.put(theChar ,false); + } + + for (char theChar : string2.toCharArray()){ + if (hm1.containsKey(theChar)) { + System.out.print(theChar); + } + } + } +} \ No newline at end of file diff --git a/LinkedList1.class b/LinkedList1.class new file mode 100644 index 0000000..209ae30 Binary files /dev/null and b/LinkedList1.class differ diff --git a/LinkedList1.java b/LinkedList1.java new file mode 100644 index 0000000..eafe6a5 --- /dev/null +++ b/LinkedList1.java @@ -0,0 +1,57 @@ +public class LinkedList1 { + + public static void main(String []args) { + + MyLinkedListElement le1 = new MyLinkedListElement(); + le1.setData("Data1"); + + MyLinkedListElement le2 = new MyLinkedListElement(); + le2.setData("Data2"); + le1.setNextElement(le2); + + MyLinkedListElement le3 = new MyLinkedListElement(); + le3.setData("Data3"); + le2.setNextElement(le3); + + MyLinkedListElement x = new MyLinkedListElement(); + x.setData("DataX"); + le1.setNextElement(x); + x.setNextElement(le2); + + eleTest(le1); + } + + public static void eleTest(MyLinkedListElement ele){ + while (ele != null){ + System.out.println(ele.getData()); + ele = ele.getNextElement(); + } + } + +} + + class MyLinkedListElement { + private String data; + private MyLinkedListElement nextElement; + + public MyLinkedListElement getNextElement() { + return nextElement; + } + + public void setNextElement(MyLinkedListElement nextElement) { + this.nextElement = nextElement; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } +} + + + + + \ No newline at end of file diff --git a/MyLinkedListElement.class b/MyLinkedListElement.class new file mode 100644 index 0000000..baaf4d2 Binary files /dev/null and b/MyLinkedListElement.class differ diff --git a/NF b/NF new file mode 100644 index 0000000..772b262 --- /dev/null +++ b/NF @@ -0,0 +1,29 @@ +00000000: cafe babe 0000 0037 0020 0a00 0700 1108 .......7. ...... +00000010: 0012 0900 0600 1309 0014 0015 0a00 1600 ................ +00000020: 1707 0018 0700 1901 0001 7801 0012 4c6a ..........x...Lj +00000030: 6176 612f 6c61 6e67 2f53 7472 696e 673b ava/lang/String; +00000040: 0100 063c 696e 6974 3e01 0003 2829 5601 ......()V. +00000050: 0004 436f 6465 0100 0f4c 696e 654e 756d ..Code...LineNum +00000060: 6265 7254 6162 6c65 0100 0474 6573 7401 berTable...test. +00000070: 000a 536f 7572 6365 4669 6c65 0100 0f46 ..SourceFile...F +00000080: 696e 616c 466c 6167 312e 6a61 7661 0c00 inalFlag1.java.. +00000090: 0a00 0b01 0006 4669 6e61 6c3f 0c00 0800 ......Final?.... +000000a0: 0907 001a 0c00 1b00 1c07 001d 0c00 1e00 ................ +000000b0: 1f01 000a 4669 6e61 6c46 6c61 6731 0100 ....FinalFlag1.. +000000c0: 106a 6176 612f 6c61 6e67 2f4f 626a 6563 .java/lang/Objec +000000d0: 7401 0010 6a61 7661 2f6c 616e 672f 5379 t...java/lang/Sy +000000e0: 7374 656d 0100 036f 7574 0100 154c 6a61 stem...out...Lja +000000f0: 7661 2f69 6f2f 5072 696e 7453 7472 6561 va/io/PrintStrea +00000100: 6d3b 0100 136a 6176 612f 696f 2f50 7269 m;...java/io/Pri +00000110: 6e74 5374 7265 616d 0100 0770 7269 6e74 ntStream...print +00000120: 6c6e 0100 1528 4c6a 6176 612f 6c61 6e67 ln...(Ljava/lang +00000130: 2f53 7472 696e 673b 2956 0020 0006 0007 /String;)V. .... +00000140: 0000 0001 0002 0008 0009 0000 0002 0001 ................ +00000150: 000a 000b 0001 000c 0000 002b 0002 0001 ...........+.... +00000160: 0000 000b 2ab7 0001 2a12 02b5 0003 b100 ....*...*....... +00000170: 0000 0100 0d00 0000 0e00 0300 0000 0300 ................ +00000180: 0400 0400 0a00 0500 0100 0e00 0b00 0100 ................ +00000190: 0c00 0000 2700 0200 0100 0000 0bb2 0004 ....'........... +000001a0: 2ab4 0003 b600 05b1 0000 0001 000d 0000 *............... +000001b0: 000a 0002 0000 0007 000a 0008 0001 000f ................ +000001c0: 0000 0002 0010 ...... diff --git a/RefAndVal1.java b/RefAndVal1.java new file mode 100644 index 0000000..e8a7f17 --- /dev/null +++ b/RefAndVal1.java @@ -0,0 +1,19 @@ +public class RefAndVal1 { + public static void main(String[] argv ){ + int i=7; + String s="Hello"; + String[] sa ={"HelAlo"}; + + test (i,s,sa); + + System.out.println(i); + System.out.println(s); + System.out.println(sa[0]); + } + + public static void test(int i, String s, String[] sa){ + i +=7; + s += "X"; + sa[0] += "X"; + } +} diff --git a/RefAndVal2.class b/RefAndVal2.class new file mode 100644 index 0000000..87bc291 Binary files /dev/null and b/RefAndVal2.class differ diff --git a/RefAndVal2.java b/RefAndVal2.java new file mode 100644 index 0000000..23735fe --- /dev/null +++ b/RefAndVal2.java @@ -0,0 +1,12 @@ +public class RefAndVal2 { + public static void main(String[] argv ){ + String s="Hello"; + test (s); + System.out.println(s); + } + + public static String test( String s){ + s += "X"; + return s; + } +} diff --git a/RefAndVal3.class b/RefAndVal3.class new file mode 100644 index 0000000..41c33cc Binary files /dev/null and b/RefAndVal3.class differ diff --git a/RefAndVal3.java b/RefAndVal3.java new file mode 100644 index 0000000..b9dfd00 --- /dev/null +++ b/RefAndVal3.java @@ -0,0 +1,25 @@ +public class RefAndVal3 { + public static void main(String[] argv ){ + String s="HHH"; + String t=s; + System.out.println("A: _" + s + "_ -> " + (t.equals(s)) + "/" + (t==s)); + + s="H".substring(0)+"H"+"H"; + System.out.println("B: _" + s + "_ -> " + (t.equals(s)) + "/" + (t==s)); + + s="HHH".replace("HHH", "HHH"); + System.out.println("C: _" + s + "_ -> " + (t.equals(s)) + "/" + (t==s)); + + s="H"+"H".concat("H"); + System.out.println("D: _" + s + "_ -> " + (t.equals(s)) + "/" + (t==s)); + + s="H" + "H" + "H"; + System.out.println("E: _" + s + "_ -> " + (t.equals(s)) + "/" + (t==s)); + + s="HHH".concat(""); + System.out.println("F: _" + s + "_ -> " + (t.equals(s)) + "/" + (t==s)); + + s="HHH".replace("", ""); + System.out.println("G: _" + s + "_ -> " + (t.equals(s)) + "/" + (t==s)); + } +} diff --git a/RefAndVal4.java b/RefAndVal4.java new file mode 100644 index 0000000..91f9f21 --- /dev/null +++ b/RefAndVal4.java @@ -0,0 +1,3243 @@ +public class RefAndVal4 { + + public static void main(String[] argv ){ + MyString s = new MyString("Hello"); + + test (i,s,sa); + + System.out.println(i); + System.out.println(s); + System.out.println(sa[0]); + } + + public static void test(int i, String s, String[] sa){ + i +=7; + s += "X"; + sa[0] += "X"; + } + + + public final class MyString + implements java.io.Serializable, Comparable, CharSequence { + + /** + * The value is used for character storage. + * + * @implNote This field is trusted by the VM, and is a subject to + * constant folding if String instance is constant. Overwriting this + * field after construction will cause problems. + * + * Additionally, it is marked with {@link Stable} to trust the contents + * of the array. No other facility in JDK provides this functionality (yet). + * {@link Stable} is safe here, because value is never null. + */ + private final byte[] value; + + /** + * The identifier of the encoding used to encode the bytes in + * {@code value}. The supported values in this implementation are + * + * LATIN1 + * UTF16 + * + * @implNote This field is trusted by the VM, and is a subject to + * constant folding if String instance is constant. Overwriting this + * field after construction will cause problems. + */ + private final byte coder; + + /** Cache the hash code for the string */ + private int hash; // Default to 0 + + /** use serialVersionUID from JDK 1.0.2 for interoperability */ + private static final long serialVersionUID = -6849794470754667710L; + + /** + * If String compaction is disabled, the bytes in {@code value} are + * always encoded in UTF16. + * + * For methods with several possible implementation paths, when String + * compaction is disabled, only one code path is taken. + * + * The instance field value is generally opaque to optimizing JIT + * compilers. Therefore, in performance-sensitive place, an explicit + * check of the static boolean {@code COMPACT_STRINGS} is done first + * before checking the {@code coder} field since the static boolean + * {@code COMPACT_STRINGS} would be constant folded away by an + * optimizing JIT compiler. The idioms for these cases are as follows. + * + * For code such as: + * + * if (coder == LATIN1) { ... } + * + * can be written more optimally as + * + * if (coder() == LATIN1) { ... } + * + * or: + * + * if (COMPACT_STRINGS && coder == LATIN1) { ... } + * + * An optimizing JIT compiler can fold the above conditional as: + * + * COMPACT_STRINGS == true => if (coder == LATIN1) { ... } + * COMPACT_STRINGS == false => if (false) { ... } + * + * @implNote + * The actual value for this field is injected by JVM. The static + * initialization block is used to set the value here to communicate + * that this static final field is not statically foldable, and to + * avoid any possible circular dependency during vm initialization. + */ + static final boolean COMPACT_STRINGS; + + static { + COMPACT_STRINGS = true; + } + + /** + * Class String is special cased within the Serialization Stream Protocol. + * + * A String instance is written into an ObjectOutputStream according to + * + * Object Serialization Specification, Section 6.2, "Stream Elements" + */ + private static final ObjectStreamField[] serialPersistentFields = + new ObjectStreamField[0]; + + /** + * Initializes a newly created {@code String} object so that it represents + * an empty character sequence. Note that use of this constructor is + * unnecessary since Strings are immutable. + */ + public MyString() { + this.value = "".value; + this.coder = "".coder; + } + + /** + * Initializes a newly created {@code String} object so that it represents + * the same sequence of characters as the argument; in other words, the + * newly created string is a copy of the argument string. Unless an + * explicit copy of {@code original} is needed, use of this constructor is + * unnecessary since Strings are immutable. + * + * @param original + * A {@code String} + */ + public MyString(String original) { + this.value = original.value; + this.coder = original.coder; + this.hash = original.hash; + } + + /** + * Allocates a new {@code String} so that it represents the sequence of + * characters currently contained in the character array argument. The + * contents of the character array are copied; subsequent modification of + * the character array does not affect the newly created string. + * + * @param value + * The initial value of the string + */ + public String(char value[]) { + this(value, 0, value.length, null); + } + + /** + * Allocates a new {@code String} that contains characters from a subarray + * of the character array argument. The {@code offset} argument is the + * index of the first character of the subarray and the {@code count} + * argument specifies the length of the subarray. The contents of the + * subarray are copied; subsequent modification of the character array does + * not affect the newly created string. + * + * @param value + * Array that is the source of characters + * + * @param offset + * The initial offset + * + * @param count + * The length + * + * @throws IndexOutOfBoundsException + * If {@code offset} is negative, {@code count} is negative, or + * {@code offset} is greater than {@code value.length - count} + */ + public String(char value[], int offset, int count) { + this(value, offset, count, rangeCheck(value, offset, count)); + } + + private static Void rangeCheck(char[] value, int offset, int count) { + checkBoundsOffCount(offset, count, value.length); + return null; + } + + /** + * Allocates a new {@code String} that contains characters from a subarray + * of the Unicode code point array + * argument. The {@code offset} argument is the index of the first code + * point of the subarray and the {@code count} argument specifies the + * length of the subarray. The contents of the subarray are converted to + * {@code char}s; subsequent modification of the {@code int} array does not + * affect the newly created string. + * + * @param codePoints + * Array that is the source of Unicode code points + * + * @param offset + * The initial offset + * + * @param count + * The length + * + * @throws IllegalArgumentException + * If any invalid Unicode code point is found in {@code + * codePoints} + * + * @throws IndexOutOfBoundsException + * If {@code offset} is negative, {@code count} is negative, or + * {@code offset} is greater than {@code codePoints.length - count} + * + * @since 1.5 + */ + public String(int[] codePoints, int offset, int count) { + checkBoundsOffCount(offset, count, codePoints.length); + if (count == 0) { + this.value = "".value; + this.coder = "".coder; + return; + } + if (COMPACT_STRINGS) { + byte[] val = StringLatin1.toBytes(codePoints, offset, count); + if (val != null) { + this.coder = LATIN1; + this.value = val; + return; + } + } + this.coder = UTF16; + this.value = StringUTF16.toBytes(codePoints, offset, count); + } + + /** + * Allocates a new {@code String} constructed from a subarray of an array + * of 8-bit integer values. + * + *

The {@code offset} argument is the index of the first byte of the + * subarray, and the {@code count} argument specifies the length of the + * subarray. + * + *

Each {@code byte} in the subarray is converted to a {@code char} as + * specified in the {@link #String(byte[],int) String(byte[],int)} constructor. + * + * @deprecated This method does not properly convert bytes into characters. + * As of JDK 1.1, the preferred way to do this is via the + * {@code String} constructors that take a {@link + * java.nio.charset.Charset}, charset name, or that use the platform's + * default charset. + * + * @param ascii + * The bytes to be converted to characters + * + * @param hibyte + * The top 8 bits of each 16-bit Unicode code unit + * + * @param offset + * The initial offset + * @param count + * The length + * + * @throws IndexOutOfBoundsException + * If {@code offset} is negative, {@code count} is negative, or + * {@code offset} is greater than {@code ascii.length - count} + * + * @see #String(byte[], int) + * @see #String(byte[], int, int, java.lang.String) + * @see #String(byte[], int, int, java.nio.charset.Charset) + * @see #String(byte[], int, int) + * @see #String(byte[], java.lang.String) + * @see #String(byte[], java.nio.charset.Charset) + * @see #String(byte[]) + */ + @Deprecated(since="1.1") + public String(byte ascii[], int hibyte, int offset, int count) { + checkBoundsOffCount(offset, count, ascii.length); + if (count == 0) { + this.value = "".value; + this.coder = "".coder; + return; + } + if (COMPACT_STRINGS && (byte)hibyte == 0) { + this.value = Arrays.copyOfRange(ascii, offset, offset + count); + this.coder = LATIN1; + } else { + hibyte <<= 8; + byte[] val = StringUTF16.newBytesFor(count); + for (int i = 0; i < count; i++) { + StringUTF16.putChar(val, i, hibyte | (ascii[offset++] & 0xff)); + } + this.value = val; + this.coder = UTF16; + } + } + + /** + * Allocates a new {@code String} containing characters constructed from + * an array of 8-bit integer values. Each character c in the + * resulting string is constructed from the corresponding component + * b in the byte array such that: + * + *

+     *     c == (char)(((hibyte & 0xff) << 8)
+     *                         | (b & 0xff))
+     * 
+ * + * @deprecated This method does not properly convert bytes into + * characters. As of JDK 1.1, the preferred way to do this is via the + * {@code String} constructors that take a {@link + * java.nio.charset.Charset}, charset name, or that use the platform's + * default charset. + * + * @param ascii + * The bytes to be converted to characters + * + * @param hibyte + * The top 8 bits of each 16-bit Unicode code unit + * + * @see #String(byte[], int, int, java.lang.String) + * @see #String(byte[], int, int, java.nio.charset.Charset) + * @see #String(byte[], int, int) + * @see #String(byte[], java.lang.String) + * @see #String(byte[], java.nio.charset.Charset) + * @see #String(byte[]) + */ + @Deprecated(since="1.1") + public String(byte ascii[], int hibyte) { + this(ascii, hibyte, 0, ascii.length); + } + + /** + * Constructs a new {@code String} by decoding the specified subarray of + * bytes using the specified charset. The length of the new {@code String} + * is a function of the charset, and hence may not be equal to the length + * of the subarray. + * + *

The behavior of this constructor when the given bytes are not valid + * in the given charset is unspecified. The {@link + * java.nio.charset.CharsetDecoder} class should be used when more control + * over the decoding process is required. + * + * @param bytes + * The bytes to be decoded into characters + * + * @param offset + * The index of the first byte to decode + * + * @param length + * The number of bytes to decode + + * @param charsetName + * The name of a supported {@linkplain java.nio.charset.Charset + * charset} + * + * @throws UnsupportedEncodingException + * If the named charset is not supported + * + * @throws IndexOutOfBoundsException + * If {@code offset} is negative, {@code length} is negative, or + * {@code offset} is greater than {@code bytes.length - length} + * + * @since 1.1 + */ + public String(byte bytes[], int offset, int length, String charsetName) + throws UnsupportedEncodingException { + if (charsetName == null) + throw new NullPointerException("charsetName"); + checkBoundsOffCount(offset, length, bytes.length); + StringCoding.Result ret = + StringCoding.decode(charsetName, bytes, offset, length); + this.value = ret.value; + this.coder = ret.coder; + } + + /** + * Constructs a new {@code String} by decoding the specified subarray of + * bytes using the specified {@linkplain java.nio.charset.Charset charset}. + * The length of the new {@code String} is a function of the charset, and + * hence may not be equal to the length of the subarray. + * + *

This method always replaces malformed-input and unmappable-character + * sequences with this charset's default replacement string. The {@link + * java.nio.charset.CharsetDecoder} class should be used when more control + * over the decoding process is required. + * + * @param bytes + * The bytes to be decoded into characters + * + * @param offset + * The index of the first byte to decode + * + * @param length + * The number of bytes to decode + * + * @param charset + * The {@linkplain java.nio.charset.Charset charset} to be used to + * decode the {@code bytes} + * + * @throws IndexOutOfBoundsException + * If {@code offset} is negative, {@code length} is negative, or + * {@code offset} is greater than {@code bytes.length - length} + * + * @since 1.6 + */ + public String(byte bytes[], int offset, int length, Charset charset) { + if (charset == null) + throw new NullPointerException("charset"); + checkBoundsOffCount(offset, length, bytes.length); + StringCoding.Result ret = + StringCoding.decode(charset, bytes, offset, length); + this.value = ret.value; + this.coder = ret.coder; + } + + /** + * Constructs a new {@code String} by decoding the specified array of bytes + * using the specified {@linkplain java.nio.charset.Charset charset}. The + * length of the new {@code String} is a function of the charset, and hence + * may not be equal to the length of the byte array. + * + *

The behavior of this constructor when the given bytes are not valid + * in the given charset is unspecified. The {@link + * java.nio.charset.CharsetDecoder} class should be used when more control + * over the decoding process is required. + * + * @param bytes + * The bytes to be decoded into characters + * + * @param charsetName + * The name of a supported {@linkplain java.nio.charset.Charset + * charset} + * + * @throws UnsupportedEncodingException + * If the named charset is not supported + * + * @since 1.1 + */ + public String(byte bytes[], String charsetName) + throws UnsupportedEncodingException { + this(bytes, 0, bytes.length, charsetName); + } + + /** + * Constructs a new {@code String} by decoding the specified array of + * bytes using the specified {@linkplain java.nio.charset.Charset charset}. + * The length of the new {@code String} is a function of the charset, and + * hence may not be equal to the length of the byte array. + * + *

This method always replaces malformed-input and unmappable-character + * sequences with this charset's default replacement string. The {@link + * java.nio.charset.CharsetDecoder} class should be used when more control + * over the decoding process is required. + * + * @param bytes + * The bytes to be decoded into characters + * + * @param charset + * The {@linkplain java.nio.charset.Charset charset} to be used to + * decode the {@code bytes} + * + * @since 1.6 + */ + public String(byte bytes[], Charset charset) { + this(bytes, 0, bytes.length, charset); + } + + /** + * Constructs a new {@code String} by decoding the specified subarray of + * bytes using the platform's default charset. The length of the new + * {@code String} is a function of the charset, and hence may not be equal + * to the length of the subarray. + * + *

The behavior of this constructor when the given bytes are not valid + * in the default charset is unspecified. The {@link + * java.nio.charset.CharsetDecoder} class should be used when more control + * over the decoding process is required. + * + * @param bytes + * The bytes to be decoded into characters + * + * @param offset + * The index of the first byte to decode + * + * @param length + * The number of bytes to decode + * + * @throws IndexOutOfBoundsException + * If {@code offset} is negative, {@code length} is negative, or + * {@code offset} is greater than {@code bytes.length - length} + * + * @since 1.1 + */ + public String(byte bytes[], int offset, int length) { + checkBoundsOffCount(offset, length, bytes.length); + StringCoding.Result ret = StringCoding.decode(bytes, offset, length); + this.value = ret.value; + this.coder = ret.coder; + } + + /** + * Constructs a new {@code String} by decoding the specified array of bytes + * using the platform's default charset. The length of the new {@code + * String} is a function of the charset, and hence may not be equal to the + * length of the byte array. + * + *

The behavior of this constructor when the given bytes are not valid + * in the default charset is unspecified. The {@link + * java.nio.charset.CharsetDecoder} class should be used when more control + * over the decoding process is required. + * + * @param bytes + * The bytes to be decoded into characters + * + * @since 1.1 + */ + public String(byte[] bytes) { + this(bytes, 0, bytes.length); + } + + /** + * Allocates a new string that contains the sequence of characters + * currently contained in the string buffer argument. The contents of the + * string buffer are copied; subsequent modification of the string buffer + * does not affect the newly created string. + * + * @param buffer + * A {@code StringBuffer} + */ + public String(StringBuffer buffer) { + this(buffer.toString()); + } + + /** + * Allocates a new string that contains the sequence of characters + * currently contained in the string builder argument. The contents of the + * string builder are copied; subsequent modification of the string builder + * does not affect the newly created string. + * + *

This constructor is provided to ease migration to {@code + * StringBuilder}. Obtaining a string from a string builder via the {@code + * toString} method is likely to run faster and is generally preferred. + * + * @param builder + * A {@code StringBuilder} + * + * @since 1.5 + */ + public String(StringBuilder builder) { + this(builder, null); + } + + /** + * Returns the length of this string. + * The length is equal to the number of Unicode + * code units in the string. + * + * @return the length of the sequence of characters represented by this + * object. + */ + public int length() { + return value.length >> coder(); + } + + /** + * Returns {@code true} if, and only if, {@link #length()} is {@code 0}. + * + * @return {@code true} if {@link #length()} is {@code 0}, otherwise + * {@code false} + * + * @since 1.6 + */ + public boolean isEmpty() { + return value.length == 0; + } + + /** + * Returns the {@code char} value at the + * specified index. An index ranges from {@code 0} to + * {@code length() - 1}. The first {@code char} value of the sequence + * is at index {@code 0}, the next at index {@code 1}, + * and so on, as for array indexing. + * + *

If the {@code char} value specified by the index is a + * surrogate, the surrogate + * value is returned. + * + * @param index the index of the {@code char} value. + * @return the {@code char} value at the specified index of this string. + * The first {@code char} value is at index {@code 0}. + * @exception IndexOutOfBoundsException if the {@code index} + * argument is negative or not less than the length of this + * string. + */ + public char charAt(int index) { + if (isLatin1()) { + return StringLatin1.charAt(value, index); + } else { + return StringUTF16.charAt(value, index); + } + } + + /** + * Returns the character (Unicode code point) at the specified + * index. The index refers to {@code char} values + * (Unicode code units) and ranges from {@code 0} to + * {@link #length()}{@code - 1}. + * + *

If the {@code char} value specified at the given index + * is in the high-surrogate range, the following index is less + * than the length of this {@code String}, and the + * {@code char} value at the following index is in the + * low-surrogate range, then the supplementary code point + * corresponding to this surrogate pair is returned. Otherwise, + * the {@code char} value at the given index is returned. + * + * @param index the index to the {@code char} values + * @return the code point value of the character at the + * {@code index} + * @exception IndexOutOfBoundsException if the {@code index} + * argument is negative or not less than the length of this + * string. + * @since 1.5 + */ + public int codePointAt(int index) { + if (isLatin1()) { + checkIndex(index, value.length); + return value[index] & 0xff; + } + int length = value.length >> 1; + checkIndex(index, length); + return StringUTF16.codePointAt(value, index, length); + } + + /** + * Returns the character (Unicode code point) before the specified + * index. The index refers to {@code char} values + * (Unicode code units) and ranges from {@code 1} to {@link + * CharSequence#length() length}. + * + *

If the {@code char} value at {@code (index - 1)} + * is in the low-surrogate range, {@code (index - 2)} is not + * negative, and the {@code char} value at {@code (index - + * 2)} is in the high-surrogate range, then the + * supplementary code point value of the surrogate pair is + * returned. If the {@code char} value at {@code index - + * 1} is an unpaired low-surrogate or a high-surrogate, the + * surrogate value is returned. + * + * @param index the index following the code point that should be returned + * @return the Unicode code point value before the given index. + * @exception IndexOutOfBoundsException if the {@code index} + * argument is less than 1 or greater than the length + * of this string. + * @since 1.5 + */ + public int codePointBefore(int index) { + int i = index - 1; + if (i < 0 || i >= length()) { + throw new StringIndexOutOfBoundsException(index); + } + if (isLatin1()) { + return (value[i] & 0xff); + } + return StringUTF16.codePointBefore(value, index); + } + + /** + * Returns the number of Unicode code points in the specified text + * range of this {@code String}. The text range begins at the + * specified {@code beginIndex} and extends to the + * {@code char} at index {@code endIndex - 1}. Thus the + * length (in {@code char}s) of the text range is + * {@code endIndex-beginIndex}. Unpaired surrogates within + * the text range count as one code point each. + * + * @param beginIndex the index to the first {@code char} of + * the text range. + * @param endIndex the index after the last {@code char} of + * the text range. + * @return the number of Unicode code points in the specified text + * range + * @exception IndexOutOfBoundsException if the + * {@code beginIndex} is negative, or {@code endIndex} + * is larger than the length of this {@code String}, or + * {@code beginIndex} is larger than {@code endIndex}. + * @since 1.5 + */ + public int codePointCount(int beginIndex, int endIndex) { + if (beginIndex < 0 || beginIndex > endIndex || + endIndex > length()) { + throw new IndexOutOfBoundsException(); + } + if (isLatin1()) { + return endIndex - beginIndex; + } + return StringUTF16.codePointCount(value, beginIndex, endIndex); + } + + /** + * Returns the index within this {@code String} that is + * offset from the given {@code index} by + * {@code codePointOffset} code points. Unpaired surrogates + * within the text range given by {@code index} and + * {@code codePointOffset} count as one code point each. + * + * @param index the index to be offset + * @param codePointOffset the offset in code points + * @return the index within this {@code String} + * @exception IndexOutOfBoundsException if {@code index} + * is negative or larger then the length of this + * {@code String}, or if {@code codePointOffset} is positive + * and the substring starting with {@code index} has fewer + * than {@code codePointOffset} code points, + * or if {@code codePointOffset} is negative and the substring + * before {@code index} has fewer than the absolute value + * of {@code codePointOffset} code points. + * @since 1.5 + */ + public int offsetByCodePoints(int index, int codePointOffset) { + if (index < 0 || index > length()) { + throw new IndexOutOfBoundsException(); + } + return Character.offsetByCodePoints(this, index, codePointOffset); + } + + /** + * Copies characters from this string into the destination character + * array. + *

+ * The first character to be copied is at index {@code srcBegin}; + * the last character to be copied is at index {@code srcEnd-1} + * (thus the total number of characters to be copied is + * {@code srcEnd-srcBegin}). The characters are copied into the + * subarray of {@code dst} starting at index {@code dstBegin} + * and ending at index: + *

+     *     dstBegin + (srcEnd-srcBegin) - 1
+     * 
+ * + * @param srcBegin index of the first character in the string + * to copy. + * @param srcEnd index after the last character in the string + * to copy. + * @param dst the destination array. + * @param dstBegin the start offset in the destination array. + * @exception IndexOutOfBoundsException If any of the following + * is true: + *
  • {@code srcBegin} is negative. + *
  • {@code srcBegin} is greater than {@code srcEnd} + *
  • {@code srcEnd} is greater than the length of this + * string + *
  • {@code dstBegin} is negative + *
  • {@code dstBegin+(srcEnd-srcBegin)} is larger than + * {@code dst.length}
+ */ + public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) { + checkBoundsBeginEnd(srcBegin, srcEnd, length()); + checkBoundsOffCount(dstBegin, srcEnd - srcBegin, dst.length); + if (isLatin1()) { + StringLatin1.getChars(value, srcBegin, srcEnd, dst, dstBegin); + } else { + StringUTF16.getChars(value, srcBegin, srcEnd, dst, dstBegin); + } + } + + /** + * Copies characters from this string into the destination byte array. Each + * byte receives the 8 low-order bits of the corresponding character. The + * eight high-order bits of each character are not copied and do not + * participate in the transfer in any way. + * + *

The first character to be copied is at index {@code srcBegin}; the + * last character to be copied is at index {@code srcEnd-1}. The total + * number of characters to be copied is {@code srcEnd-srcBegin}. The + * characters, converted to bytes, are copied into the subarray of {@code + * dst} starting at index {@code dstBegin} and ending at index: + * + *

+     *     dstBegin + (srcEnd-srcBegin) - 1
+     * 
+ * + * @deprecated This method does not properly convert characters into + * bytes. As of JDK 1.1, the preferred way to do this is via the + * {@link #getBytes()} method, which uses the platform's default charset. + * + * @param srcBegin + * Index of the first character in the string to copy + * + * @param srcEnd + * Index after the last character in the string to copy + * + * @param dst + * The destination array + * + * @param dstBegin + * The start offset in the destination array + * + * @throws IndexOutOfBoundsException + * If any of the following is true: + *
    + *
  • {@code srcBegin} is negative + *
  • {@code srcBegin} is greater than {@code srcEnd} + *
  • {@code srcEnd} is greater than the length of this String + *
  • {@code dstBegin} is negative + *
  • {@code dstBegin+(srcEnd-srcBegin)} is larger than {@code + * dst.length} + *
+ */ + @Deprecated(since="1.1") + public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) { + checkBoundsBeginEnd(srcBegin, srcEnd, length()); + Objects.requireNonNull(dst); + checkBoundsOffCount(dstBegin, srcEnd - srcBegin, dst.length); + if (isLatin1()) { + StringLatin1.getBytes(value, srcBegin, srcEnd, dst, dstBegin); + } else { + StringUTF16.getBytes(value, srcBegin, srcEnd, dst, dstBegin); + } + } + + /** + * Encodes this {@code String} into a sequence of bytes using the named + * charset, storing the result into a new byte array. + * + *

The behavior of this method when this string cannot be encoded in + * the given charset is unspecified. The {@link + * java.nio.charset.CharsetEncoder} class should be used when more control + * over the encoding process is required. + * + * @param charsetName + * The name of a supported {@linkplain java.nio.charset.Charset + * charset} + * + * @return The resultant byte array + * + * @throws UnsupportedEncodingException + * If the named charset is not supported + * + * @since 1.1 + */ + public byte[] getBytes(String charsetName) + throws UnsupportedEncodingException { + if (charsetName == null) throw new NullPointerException(); + return StringCoding.encode(charsetName, coder(), value); + } + + /** + * Encodes this {@code String} into a sequence of bytes using the given + * {@linkplain java.nio.charset.Charset charset}, storing the result into a + * new byte array. + * + *

This method always replaces malformed-input and unmappable-character + * sequences with this charset's default replacement byte array. The + * {@link java.nio.charset.CharsetEncoder} class should be used when more + * control over the encoding process is required. + * + * @param charset + * The {@linkplain java.nio.charset.Charset} to be used to encode + * the {@code String} + * + * @return The resultant byte array + * + * @since 1.6 + */ + public byte[] getBytes(Charset charset) { + if (charset == null) throw new NullPointerException(); + return StringCoding.encode(charset, coder(), value); + } + + /** + * Encodes this {@code String} into a sequence of bytes using the + * platform's default charset, storing the result into a new byte array. + * + *

The behavior of this method when this string cannot be encoded in + * the default charset is unspecified. The {@link + * java.nio.charset.CharsetEncoder} class should be used when more control + * over the encoding process is required. + * + * @return The resultant byte array + * + * @since 1.1 + */ + public byte[] getBytes() { + return StringCoding.encode(coder(), value); + } + + /** + * Compares this string to the specified object. The result is {@code + * true} if and only if the argument is not {@code null} and is a {@code + * String} object that represents the same sequence of characters as this + * object. + * + *

For finer-grained String comparison, refer to + * {@link java.text.Collator}. + * + * @param anObject + * The object to compare this {@code String} against + * + * @return {@code true} if the given object represents a {@code String} + * equivalent to this string, {@code false} otherwise + * + * @see #compareTo(String) + * @see #equalsIgnoreCase(String) + */ + public boolean equals(Object anObject) { + if (this == anObject) { + return true; + } + if (anObject instanceof String) { + String aString = (String)anObject; + if (coder() == aString.coder()) { + return isLatin1() ? StringLatin1.equals(value, aString.value) + : StringUTF16.equals(value, aString.value); + } + } + return false; + } + + /** + * Compares this string to the specified {@code StringBuffer}. The result + * is {@code true} if and only if this {@code String} represents the same + * sequence of characters as the specified {@code StringBuffer}. This method + * synchronizes on the {@code StringBuffer}. + * + *

For finer-grained String comparison, refer to + * {@link java.text.Collator}. + * + * @param sb + * The {@code StringBuffer} to compare this {@code String} against + * + * @return {@code true} if this {@code String} represents the same + * sequence of characters as the specified {@code StringBuffer}, + * {@code false} otherwise + * + * @since 1.4 + */ + public boolean contentEquals(StringBuffer sb) { + return contentEquals((CharSequence)sb); + } + + private boolean nonSyncContentEquals(AbstractStringBuilder sb) { + int len = length(); + if (len != sb.length()) { + return false; + } + byte v1[] = value; + byte v2[] = sb.getValue(); + if (coder() == sb.getCoder()) { + int n = v1.length; + for (int i = 0; i < n; i++) { + if (v1[i] != v2[i]) { + return false; + } + } + } else { + if (!isLatin1()) { // utf16 str and latin1 abs can never be "equal" + return false; + } + return StringUTF16.contentEquals(v1, v2, len); + } + return true; + } + + /** + * Compares this string to the specified {@code CharSequence}. The + * result is {@code true} if and only if this {@code String} represents the + * same sequence of char values as the specified sequence. Note that if the + * {@code CharSequence} is a {@code StringBuffer} then the method + * synchronizes on it. + * + *

For finer-grained String comparison, refer to + * {@link java.text.Collator}. + * + * @param cs + * The sequence to compare this {@code String} against + * + * @return {@code true} if this {@code String} represents the same + * sequence of char values as the specified sequence, {@code + * false} otherwise + * + * @since 1.5 + */ + public boolean contentEquals(CharSequence cs) { + // Argument is a StringBuffer, StringBuilder + if (cs instanceof AbstractStringBuilder) { + if (cs instanceof StringBuffer) { + synchronized(cs) { + return nonSyncContentEquals((AbstractStringBuilder)cs); + } + } else { + return nonSyncContentEquals((AbstractStringBuilder)cs); + } + } + // Argument is a String + if (cs instanceof String) { + return equals(cs); + } + // Argument is a generic CharSequence + int n = cs.length(); + if (n != length()) { + return false; + } + byte[] val = this.value; + if (isLatin1()) { + for (int i = 0; i < n; i++) { + if ((val[i] & 0xff) != cs.charAt(i)) { + return false; + } + } + } else { + if (!StringUTF16.contentEquals(val, cs, n)) { + return false; + } + } + return true; + } + + /** + * Compares this {@code String} to another {@code String}, ignoring case + * considerations. Two strings are considered equal ignoring case if they + * are of the same length and corresponding characters in the two strings + * are equal ignoring case. + * + *

Two characters {@code c1} and {@code c2} are considered the same + * ignoring case if at least one of the following is true: + *

    + *
  • The two characters are the same (as compared by the + * {@code ==} operator) + *
  • Calling {@code Character.toLowerCase(Character.toUpperCase(char))} + * on each character produces the same result + *
+ * + *

Note that this method does not take locale into account, and + * will result in unsatisfactory results for certain locales. The + * {@link java.text.Collator} class provides locale-sensitive comparison. + * + * @param anotherString + * The {@code String} to compare this {@code String} against + * + * @return {@code true} if the argument is not {@code null} and it + * represents an equivalent {@code String} ignoring case; {@code + * false} otherwise + * + * @see #equals(Object) + */ + public boolean equalsIgnoreCase(String anotherString) { + return (this == anotherString) ? true + : (anotherString != null) + && (anotherString.length() == length()) + && regionMatches(true, 0, anotherString, 0, length()); + } + + /** + * Compares two strings lexicographically. + * The comparison is based on the Unicode value of each character in + * the strings. The character sequence represented by this + * {@code String} object is compared lexicographically to the + * character sequence represented by the argument string. The result is + * a negative integer if this {@code String} object + * lexicographically precedes the argument string. The result is a + * positive integer if this {@code String} object lexicographically + * follows the argument string. The result is zero if the strings + * are equal; {@code compareTo} returns {@code 0} exactly when + * the {@link #equals(Object)} method would return {@code true}. + *

+ * This is the definition of lexicographic ordering. If two strings are + * different, then either they have different characters at some index + * that is a valid index for both strings, or their lengths are different, + * or both. If they have different characters at one or more index + * positions, let k be the smallest such index; then the string + * whose character at position k has the smaller value, as + * determined by using the {@code <} operator, lexicographically precedes the + * other string. In this case, {@code compareTo} returns the + * difference of the two character values at position {@code k} in + * the two string -- that is, the value: + *

+     * this.charAt(k)-anotherString.charAt(k)
+     * 
+ * If there is no index position at which they differ, then the shorter + * string lexicographically precedes the longer string. In this case, + * {@code compareTo} returns the difference of the lengths of the + * strings -- that is, the value: + *
+     * this.length()-anotherString.length()
+     * 
+ * + *

For finer-grained String comparison, refer to + * {@link java.text.Collator}. + * + * @param anotherString the {@code String} to be compared. + * @return the value {@code 0} if the argument string is equal to + * this string; a value less than {@code 0} if this string + * is lexicographically less than the string argument; and a + * value greater than {@code 0} if this string is + * lexicographically greater than the string argument. + */ + public int compareTo(String anotherString) { + byte v1[] = value; + byte v2[] = anotherString.value; + if (coder() == anotherString.coder()) { + return isLatin1() ? StringLatin1.compareTo(v1, v2) + : StringUTF16.compareTo(v1, v2); + } + return isLatin1() ? StringLatin1.compareToUTF16(v1, v2) + : StringUTF16.compareToLatin1(v1, v2); + } + + /** + * A Comparator that orders {@code String} objects as by + * {@code compareToIgnoreCase}. This comparator is serializable. + *

+ * Note that this Comparator does not take locale into account, + * and will result in an unsatisfactory ordering for certain locales. + * The {@link java.text.Collator} class provides locale-sensitive comparison. + * + * @see java.text.Collator + * @since 1.2 + */ + public static final Comparator CASE_INSENSITIVE_ORDER + = new CaseInsensitiveComparator(); + private static class CaseInsensitiveComparator + implements Comparator, java.io.Serializable { + // use serialVersionUID from JDK 1.2.2 for interoperability + private static final long serialVersionUID = 8575799808933029326L; + + public int compare(String s1, String s2) { + byte v1[] = s1.value; + byte v2[] = s2.value; + if (s1.coder() == s2.coder()) { + return s1.isLatin1() ? StringLatin1.compareToCI(v1, v2) + : StringUTF16.compareToCI(v1, v2); + } + return s1.isLatin1() ? StringLatin1.compareToCI_UTF16(v1, v2) + : StringUTF16.compareToCI_Latin1(v1, v2); + } + + /** Replaces the de-serialized object. */ + private Object readResolve() { return CASE_INSENSITIVE_ORDER; } + } + + /** + * Compares two strings lexicographically, ignoring case + * differences. This method returns an integer whose sign is that of + * calling {@code compareTo} with normalized versions of the strings + * where case differences have been eliminated by calling + * {@code Character.toLowerCase(Character.toUpperCase(character))} on + * each character. + *

+ * Note that this method does not take locale into account, + * and will result in an unsatisfactory ordering for certain locales. + * The {@link java.text.Collator} class provides locale-sensitive comparison. + * + * @param str the {@code String} to be compared. + * @return a negative integer, zero, or a positive integer as the + * specified String is greater than, equal to, or less + * than this String, ignoring case considerations. + * @see java.text.Collator + * @since 1.2 + */ + public int compareToIgnoreCase(String str) { + return CASE_INSENSITIVE_ORDER.compare(this, str); + } + + /** + * Tests if two string regions are equal. + *

+ * A substring of this {@code String} object is compared to a substring + * of the argument other. The result is true if these substrings + * represent identical character sequences. The substring of this + * {@code String} object to be compared begins at index {@code toffset} + * and has length {@code len}. The substring of other to be compared + * begins at index {@code ooffset} and has length {@code len}. The + * result is {@code false} if and only if at least one of the following + * is true: + *

  • {@code toffset} is negative. + *
  • {@code ooffset} is negative. + *
  • {@code toffset+len} is greater than the length of this + * {@code String} object. + *
  • {@code ooffset+len} is greater than the length of the other + * argument. + *
  • There is some nonnegative integer k less than {@code len} + * such that: + * {@code this.charAt(toffset + }k{@code ) != other.charAt(ooffset + } + * k{@code )} + *
+ * + *

Note that this method does not take locale into account. The + * {@link java.text.Collator} class provides locale-sensitive comparison. + * + * @param toffset the starting offset of the subregion in this string. + * @param other the string argument. + * @param ooffset the starting offset of the subregion in the string + * argument. + * @param len the number of characters to compare. + * @return {@code true} if the specified subregion of this string + * exactly matches the specified subregion of the string argument; + * {@code false} otherwise. + */ + public boolean regionMatches(int toffset, String other, int ooffset, int len) { + byte tv[] = value; + byte ov[] = other.value; + // Note: toffset, ooffset, or len might be near -1>>>1. + if ((ooffset < 0) || (toffset < 0) || + (toffset > (long)length() - len) || + (ooffset > (long)other.length() - len)) { + return false; + } + if (coder() == other.coder()) { + if (!isLatin1() && (len > 0)) { + toffset = toffset << 1; + ooffset = ooffset << 1; + len = len << 1; + } + while (len-- > 0) { + if (tv[toffset++] != ov[ooffset++]) { + return false; + } + } + } else { + if (coder() == LATIN1) { + while (len-- > 0) { + if (StringLatin1.getChar(tv, toffset++) != + StringUTF16.getChar(ov, ooffset++)) { + return false; + } + } + } else { + while (len-- > 0) { + if (StringUTF16.getChar(tv, toffset++) != + StringLatin1.getChar(ov, ooffset++)) { + return false; + } + } + } + } + return true; + } + + /** + * Tests if two string regions are equal. + *

+ * A substring of this {@code String} object is compared to a substring + * of the argument {@code other}. The result is {@code true} if these + * substrings represent character sequences that are the same, ignoring + * case if and only if {@code ignoreCase} is true. The substring of + * this {@code String} object to be compared begins at index + * {@code toffset} and has length {@code len}. The substring of + * {@code other} to be compared begins at index {@code ooffset} and + * has length {@code len}. The result is {@code false} if and only if + * at least one of the following is true: + *

  • {@code toffset} is negative. + *
  • {@code ooffset} is negative. + *
  • {@code toffset+len} is greater than the length of this + * {@code String} object. + *
  • {@code ooffset+len} is greater than the length of the other + * argument. + *
  • {@code ignoreCase} is {@code false} and there is some nonnegative + * integer k less than {@code len} such that: + *
    +     * this.charAt(toffset+k) != other.charAt(ooffset+k)
    +     * 
    + *
  • {@code ignoreCase} is {@code true} and there is some nonnegative + * integer k less than {@code len} such that: + *
    +     * Character.toLowerCase(Character.toUpperCase(this.charAt(toffset+k))) !=
    +     Character.toLowerCase(Character.toUpperCase(other.charAt(ooffset+k)))
    +     * 
    + *
+ * + *

Note that this method does not take locale into account, + * and will result in unsatisfactory results for certain locales when + * {@code ignoreCase} is {@code true}. The {@link java.text.Collator} class + * provides locale-sensitive comparison. + * + * @param ignoreCase if {@code true}, ignore case when comparing + * characters. + * @param toffset the starting offset of the subregion in this + * string. + * @param other the string argument. + * @param ooffset the starting offset of the subregion in the string + * argument. + * @param len the number of characters to compare. + * @return {@code true} if the specified subregion of this string + * matches the specified subregion of the string argument; + * {@code false} otherwise. Whether the matching is exact + * or case insensitive depends on the {@code ignoreCase} + * argument. + */ + public boolean regionMatches(boolean ignoreCase, int toffset, + String other, int ooffset, int len) { + if (!ignoreCase) { + return regionMatches(toffset, other, ooffset, len); + } + // Note: toffset, ooffset, or len might be near -1>>>1. + if ((ooffset < 0) || (toffset < 0) + || (toffset > (long)length() - len) + || (ooffset > (long)other.length() - len)) { + return false; + } + byte tv[] = value; + byte ov[] = other.value; + if (coder() == other.coder()) { + return isLatin1() + ? StringLatin1.regionMatchesCI(tv, toffset, ov, ooffset, len) + : StringUTF16.regionMatchesCI(tv, toffset, ov, ooffset, len); + } + return isLatin1() + ? StringLatin1.regionMatchesCI_UTF16(tv, toffset, ov, ooffset, len) + : StringUTF16.regionMatchesCI_Latin1(tv, toffset, ov, ooffset, len); + } + + /** + * Tests if the substring of this string beginning at the + * specified index starts with the specified prefix. + * + * @param prefix the prefix. + * @param toffset where to begin looking in this string. + * @return {@code true} if the character sequence represented by the + * argument is a prefix of the substring of this object starting + * at index {@code toffset}; {@code false} otherwise. + * The result is {@code false} if {@code toffset} is + * negative or greater than the length of this + * {@code String} object; otherwise the result is the same + * as the result of the expression + *

+     *          this.substring(toffset).startsWith(prefix)
+     *          
+ */ + public boolean startsWith(String prefix, int toffset) { + // Note: toffset might be near -1>>>1. + if (toffset < 0 || toffset > length() - prefix.length()) { + return false; + } + byte ta[] = value; + byte pa[] = prefix.value; + int po = 0; + int pc = pa.length; + if (coder() == prefix.coder()) { + int to = isLatin1() ? toffset : toffset << 1; + while (po < pc) { + if (ta[to++] != pa[po++]) { + return false; + } + } + } else { + if (isLatin1()) { // && pcoder == UTF16 + return false; + } + // coder == UTF16 && pcoder == LATIN1) + while (po < pc) { + if (StringUTF16.getChar(ta, toffset++) != (pa[po++] & 0xff)) { + return false; + } + } + } + return true; + } + + /** + * Tests if this string starts with the specified prefix. + * + * @param prefix the prefix. + * @return {@code true} if the character sequence represented by the + * argument is a prefix of the character sequence represented by + * this string; {@code false} otherwise. + * Note also that {@code true} will be returned if the + * argument is an empty string or is equal to this + * {@code String} object as determined by the + * {@link #equals(Object)} method. + * @since 1.0 + */ + public boolean startsWith(String prefix) { + return startsWith(prefix, 0); + } + + /** + * Tests if this string ends with the specified suffix. + * + * @param suffix the suffix. + * @return {@code true} if the character sequence represented by the + * argument is a suffix of the character sequence represented by + * this object; {@code false} otherwise. Note that the + * result will be {@code true} if the argument is the + * empty string or is equal to this {@code String} object + * as determined by the {@link #equals(Object)} method. + */ + public boolean endsWith(String suffix) { + return startsWith(suffix, length() - suffix.length()); + } + + /** + * Returns a hash code for this string. The hash code for a + * {@code String} object is computed as + *
+     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
+     * 
+ * using {@code int} arithmetic, where {@code s[i]} is the + * ith character of the string, {@code n} is the length of + * the string, and {@code ^} indicates exponentiation. + * (The hash value of the empty string is zero.) + * + * @return a hash code value for this object. + */ + public int hashCode() { + int h = hash; + if (h == 0 && value.length > 0) { + hash = h = isLatin1() ? StringLatin1.hashCode(value) + : StringUTF16.hashCode(value); + } + return h; + } + + /** + * Returns the index within this string of the first occurrence of + * the specified character. If a character with value + * {@code ch} occurs in the character sequence represented by + * this {@code String} object, then the index (in Unicode + * code units) of the first such occurrence is returned. For + * values of {@code ch} in the range from 0 to 0xFFFF + * (inclusive), this is the smallest value k such that: + *
+     * this.charAt(k) == ch
+     * 
+ * is true. For other values of {@code ch}, it is the + * smallest value k such that: + *
+     * this.codePointAt(k) == ch
+     * 
+ * is true. In either case, if no such character occurs in this + * string, then {@code -1} is returned. + * + * @param ch a character (Unicode code point). + * @return the index of the first occurrence of the character in the + * character sequence represented by this object, or + * {@code -1} if the character does not occur. + */ + public int indexOf(int ch) { + return indexOf(ch, 0); + } + + /** + * Returns the index within this string of the first occurrence of the + * specified character, starting the search at the specified index. + *

+ * If a character with value {@code ch} occurs in the + * character sequence represented by this {@code String} + * object at an index no smaller than {@code fromIndex}, then + * the index of the first such occurrence is returned. For values + * of {@code ch} in the range from 0 to 0xFFFF (inclusive), + * this is the smallest value k such that: + *

+     * (this.charAt(k) == ch) {@code &&} (k >= fromIndex)
+     * 
+ * is true. For other values of {@code ch}, it is the + * smallest value k such that: + *
+     * (this.codePointAt(k) == ch) {@code &&} (k >= fromIndex)
+     * 
+ * is true. In either case, if no such character occurs in this + * string at or after position {@code fromIndex}, then + * {@code -1} is returned. + * + *

+ * There is no restriction on the value of {@code fromIndex}. If it + * is negative, it has the same effect as if it were zero: this entire + * string may be searched. If it is greater than the length of this + * string, it has the same effect as if it were equal to the length of + * this string: {@code -1} is returned. + * + *

All indices are specified in {@code char} values + * (Unicode code units). + * + * @param ch a character (Unicode code point). + * @param fromIndex the index to start the search from. + * @return the index of the first occurrence of the character in the + * character sequence represented by this object that is greater + * than or equal to {@code fromIndex}, or {@code -1} + * if the character does not occur. + */ + public int indexOf(int ch, int fromIndex) { + return isLatin1() ? StringLatin1.indexOf(value, ch, fromIndex) + : StringUTF16.indexOf(value, ch, fromIndex); + } + + /** + * Returns the index within this string of the last occurrence of + * the specified character. For values of {@code ch} in the + * range from 0 to 0xFFFF (inclusive), the index (in Unicode code + * units) returned is the largest value k such that: + *

+     * this.charAt(k) == ch
+     * 
+ * is true. For other values of {@code ch}, it is the + * largest value k such that: + *
+     * this.codePointAt(k) == ch
+     * 
+ * is true. In either case, if no such character occurs in this + * string, then {@code -1} is returned. The + * {@code String} is searched backwards starting at the last + * character. + * + * @param ch a character (Unicode code point). + * @return the index of the last occurrence of the character in the + * character sequence represented by this object, or + * {@code -1} if the character does not occur. + */ + public int lastIndexOf(int ch) { + return lastIndexOf(ch, length() - 1); + } + + /** + * Returns the index within this string of the last occurrence of + * the specified character, searching backward starting at the + * specified index. For values of {@code ch} in the range + * from 0 to 0xFFFF (inclusive), the index returned is the largest + * value k such that: + *
+     * (this.charAt(k) == ch) {@code &&} (k <= fromIndex)
+     * 
+ * is true. For other values of {@code ch}, it is the + * largest value k such that: + *
+     * (this.codePointAt(k) == ch) {@code &&} (k <= fromIndex)
+     * 
+ * is true. In either case, if no such character occurs in this + * string at or before position {@code fromIndex}, then + * {@code -1} is returned. + * + *

All indices are specified in {@code char} values + * (Unicode code units). + * + * @param ch a character (Unicode code point). + * @param fromIndex the index to start the search from. There is no + * restriction on the value of {@code fromIndex}. If it is + * greater than or equal to the length of this string, it has + * the same effect as if it were equal to one less than the + * length of this string: this entire string may be searched. + * If it is negative, it has the same effect as if it were -1: + * -1 is returned. + * @return the index of the last occurrence of the character in the + * character sequence represented by this object that is less + * than or equal to {@code fromIndex}, or {@code -1} + * if the character does not occur before that point. + */ + public int lastIndexOf(int ch, int fromIndex) { + return isLatin1() ? StringLatin1.lastIndexOf(value, ch, fromIndex) + : StringUTF16.lastIndexOf(value, ch, fromIndex); + } + + /** + * Returns the index within this string of the first occurrence of the + * specified substring. + * + *

The returned index is the smallest value {@code k} for which: + *

{@code
+     * this.startsWith(str, k)
+     * }
+ * If no such value of {@code k} exists, then {@code -1} is returned. + * + * @param str the substring to search for. + * @return the index of the first occurrence of the specified substring, + * or {@code -1} if there is no such occurrence. + */ + public int indexOf(String str) { + if (coder() == str.coder()) { + return isLatin1() ? StringLatin1.indexOf(value, str.value) + : StringUTF16.indexOf(value, str.value); + } + if (coder() == LATIN1) { // str.coder == UTF16 + return -1; + } + return StringUTF16.indexOfLatin1(value, str.value); + } + + /** + * Returns the index within this string of the first occurrence of the + * specified substring, starting at the specified index. + * + *

The returned index is the smallest value {@code k} for which: + *

{@code
+     *     k >= Math.min(fromIndex, this.length()) &&
+     *                   this.startsWith(str, k)
+     * }
+ * If no such value of {@code k} exists, then {@code -1} is returned. + * + * @param str the substring to search for. + * @param fromIndex the index from which to start the search. + * @return the index of the first occurrence of the specified substring, + * starting at the specified index, + * or {@code -1} if there is no such occurrence. + */ + public int indexOf(String str, int fromIndex) { + return indexOf(value, coder(), length(), str, fromIndex); + } + + /** + * Code shared by String and AbstractStringBuilder to do searches. The + * source is the character array being searched, and the target + * is the string being searched for. + * + * @param src the characters being searched. + * @param srcCoder the coder of the source string. + * @param srcCount length of the source string. + * @param tgtStr the characters being searched for. + * @param fromIndex the index to begin searching from. + */ + static int indexOf(byte[] src, byte srcCoder, int srcCount, + String tgtStr, int fromIndex) { + byte[] tgt = tgtStr.value; + byte tgtCoder = tgtStr.coder(); + int tgtCount = tgtStr.length(); + + if (fromIndex >= srcCount) { + return (tgtCount == 0 ? srcCount : -1); + } + if (fromIndex < 0) { + fromIndex = 0; + } + if (tgtCount == 0) { + return fromIndex; + } + if (tgtCount > srcCount) { + return -1; + } + if (srcCoder == tgtCoder) { + return srcCoder == LATIN1 + ? StringLatin1.indexOf(src, srcCount, tgt, tgtCount, fromIndex) + : StringUTF16.indexOf(src, srcCount, tgt, tgtCount, fromIndex); + } + if (srcCoder == LATIN1) { // && tgtCoder == UTF16 + return -1; + } + // srcCoder == UTF16 && tgtCoder == LATIN1) { + return StringUTF16.indexOfLatin1(src, srcCount, tgt, tgtCount, fromIndex); + } + + /** + * Returns the index within this string of the last occurrence of the + * specified substring. The last occurrence of the empty string "" + * is considered to occur at the index value {@code this.length()}. + * + *

The returned index is the largest value {@code k} for which: + *

{@code
+     * this.startsWith(str, k)
+     * }
+ * If no such value of {@code k} exists, then {@code -1} is returned. + * + * @param str the substring to search for. + * @return the index of the last occurrence of the specified substring, + * or {@code -1} if there is no such occurrence. + */ + public int lastIndexOf(String str) { + return lastIndexOf(str, length()); + } + + /** + * Returns the index within this string of the last occurrence of the + * specified substring, searching backward starting at the specified index. + * + *

The returned index is the largest value {@code k} for which: + *

{@code
+     *     k <= Math.min(fromIndex, this.length()) &&
+     *                   this.startsWith(str, k)
+     * }
+ * If no such value of {@code k} exists, then {@code -1} is returned. + * + * @param str the substring to search for. + * @param fromIndex the index to start the search from. + * @return the index of the last occurrence of the specified substring, + * searching backward from the specified index, + * or {@code -1} if there is no such occurrence. + */ + public int lastIndexOf(String str, int fromIndex) { + return lastIndexOf(value, coder(), length(), str, fromIndex); + } + + /** + * Code shared by String and AbstractStringBuilder to do searches. The + * source is the character array being searched, and the target + * is the string being searched for. + * + * @param src the characters being searched. + * @param srcCoder coder handles the mapping between bytes/chars + * @param srcCount count of the source string. + * @param tgt the characters being searched for. + * @param fromIndex the index to begin searching from. + */ + static int lastIndexOf(byte[] src, byte srcCoder, int srcCount, + String tgtStr, int fromIndex) { + byte[] tgt = tgtStr.value; + byte tgtCoder = tgtStr.coder(); + int tgtCount = tgtStr.length(); + /* + * Check arguments; return immediately where possible. For + * consistency, don't check for null str. + */ + int rightIndex = srcCount - tgtCount; + if (fromIndex > rightIndex) { + fromIndex = rightIndex; + } + if (fromIndex < 0) { + return -1; + } + /* Empty string always matches. */ + if (tgtCount == 0) { + return fromIndex; + } + if (srcCoder == tgtCoder) { + return srcCoder == LATIN1 + ? StringLatin1.lastIndexOf(src, srcCount, tgt, tgtCount, fromIndex) + : StringUTF16.lastIndexOf(src, srcCount, tgt, tgtCount, fromIndex); + } + if (srcCoder == LATIN1) { // && tgtCoder == UTF16 + return -1; + } + // srcCoder == UTF16 && tgtCoder == LATIN1 + return StringUTF16.lastIndexOfLatin1(src, srcCount, tgt, tgtCount, fromIndex); + } + + /** + * Returns a string that is a substring of this string. The + * substring begins with the character at the specified index and + * extends to the end of this string.

+ * Examples: + *

+     * "unhappy".substring(2) returns "happy"
+     * "Harbison".substring(3) returns "bison"
+     * "emptiness".substring(9) returns "" (an empty string)
+     * 
+ * + * @param beginIndex the beginning index, inclusive. + * @return the specified substring. + * @exception IndexOutOfBoundsException if + * {@code beginIndex} is negative or larger than the + * length of this {@code String} object. + */ + public String substring(int beginIndex) { + if (beginIndex < 0) { + throw new StringIndexOutOfBoundsException(beginIndex); + } + int subLen = length() - beginIndex; + if (subLen < 0) { + throw new StringIndexOutOfBoundsException(subLen); + } + if (beginIndex == 0) { + return this; + } + return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen) + : StringUTF16.newString(value, beginIndex, subLen); + } + + /** + * Returns a string that is a substring of this string. The + * substring begins at the specified {@code beginIndex} and + * extends to the character at index {@code endIndex - 1}. + * Thus the length of the substring is {@code endIndex-beginIndex}. + *

+ * Examples: + *

+     * "hamburger".substring(4, 8) returns "urge"
+     * "smiles".substring(1, 5) returns "mile"
+     * 
+ * + * @param beginIndex the beginning index, inclusive. + * @param endIndex the ending index, exclusive. + * @return the specified substring. + * @exception IndexOutOfBoundsException if the + * {@code beginIndex} is negative, or + * {@code endIndex} is larger than the length of + * this {@code String} object, or + * {@code beginIndex} is larger than + * {@code endIndex}. + */ + public String substring(int beginIndex, int endIndex) { + int length = length(); + checkBoundsBeginEnd(beginIndex, endIndex, length); + int subLen = endIndex - beginIndex; + if (beginIndex == 0 && endIndex == length) { + return this; + } + return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen) + : StringUTF16.newString(value, beginIndex, subLen); + } + + /** + * Returns a character sequence that is a subsequence of this sequence. + * + *

An invocation of this method of the form + * + *

+     * str.subSequence(begin, end)
+ * + * behaves in exactly the same way as the invocation + * + *
+     * str.substring(begin, end)
+ * + * @apiNote + * This method is defined so that the {@code String} class can implement + * the {@link CharSequence} interface. + * + * @param beginIndex the begin index, inclusive. + * @param endIndex the end index, exclusive. + * @return the specified subsequence. + * + * @throws IndexOutOfBoundsException + * if {@code beginIndex} or {@code endIndex} is negative, + * if {@code endIndex} is greater than {@code length()}, + * or if {@code beginIndex} is greater than {@code endIndex} + * + * @since 1.4 + * @spec JSR-51 + */ + public CharSequence subSequence(int beginIndex, int endIndex) { + return this.substring(beginIndex, endIndex); + } + + /** + * Concatenates the specified string to the end of this string. + *

+ * If the length of the argument string is {@code 0}, then this + * {@code String} object is returned. Otherwise, a + * {@code String} object is returned that represents a character + * sequence that is the concatenation of the character sequence + * represented by this {@code String} object and the character + * sequence represented by the argument string.

+ * Examples: + *

+     * "cares".concat("s") returns "caress"
+     * "to".concat("get").concat("her") returns "together"
+     * 
+ * + * @param str the {@code String} that is concatenated to the end + * of this {@code String}. + * @return a string that represents the concatenation of this object's + * characters followed by the string argument's characters. + */ + public String concat(String str) { + if (str.isEmpty()) { + return this; + } + if (coder() == str.coder()) { + byte[] val = this.value; + byte[] oval = str.value; + int len = val.length + oval.length; + byte[] buf = Arrays.copyOf(val, len); + System.arraycopy(oval, 0, buf, val.length, oval.length); + return new String(buf, coder); + } + int len = length(); + int olen = str.length(); + byte[] buf = StringUTF16.newBytesFor(len + olen); + getBytes(buf, 0, UTF16); + str.getBytes(buf, len, UTF16); + return new String(buf, UTF16); + } + + /** + * Returns a string resulting from replacing all occurrences of + * {@code oldChar} in this string with {@code newChar}. + *

+ * If the character {@code oldChar} does not occur in the + * character sequence represented by this {@code String} object, + * then a reference to this {@code String} object is returned. + * Otherwise, a {@code String} object is returned that + * represents a character sequence identical to the character sequence + * represented by this {@code String} object, except that every + * occurrence of {@code oldChar} is replaced by an occurrence + * of {@code newChar}. + *

+ * Examples: + *

+     * "mesquite in your cellar".replace('e', 'o')
+     *         returns "mosquito in your collar"
+     * "the war of baronets".replace('r', 'y')
+     *         returns "the way of bayonets"
+     * "sparring with a purple porpoise".replace('p', 't')
+     *         returns "starring with a turtle tortoise"
+     * "JonL".replace('q', 'x') returns "JonL" (no change)
+     * 
+ * + * @param oldChar the old character. + * @param newChar the new character. + * @return a string derived from this string by replacing every + * occurrence of {@code oldChar} with {@code newChar}. + */ + public String replace(char oldChar, char newChar) { + if (oldChar != newChar) { + String ret = isLatin1() ? StringLatin1.replace(value, oldChar, newChar) + : StringUTF16.replace(value, oldChar, newChar); + if (ret != null) { + return ret; + } + } + return this; + } + + /** + * Tells whether or not this string matches the given regular expression. + * + *

An invocation of this method of the form + * str{@code .matches(}regex{@code )} yields exactly the + * same result as the expression + * + *

+ * {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#matches(String,CharSequence) + * matches(regex, str)} + *
+ * + * @param regex + * the regular expression to which this string is to be matched + * + * @return {@code true} if, and only if, this string matches the + * given regular expression + * + * @throws PatternSyntaxException + * if the regular expression's syntax is invalid + * + * @see java.util.regex.Pattern + * + * @since 1.4 + * @spec JSR-51 + */ + public boolean matches(String regex) { + return Pattern.matches(regex, this); + } + + /** + * Returns true if and only if this string contains the specified + * sequence of char values. + * + * @param s the sequence to search for + * @return true if this string contains {@code s}, false otherwise + * @since 1.5 + */ + public boolean contains(CharSequence s) { + return indexOf(s.toString()) >= 0; + } + + /** + * Replaces the first substring of this string that matches the given regular expression with the + * given replacement. + * + *

An invocation of this method of the form + * str{@code .replaceFirst(}regex{@code ,} repl{@code )} + * yields exactly the same result as the expression + * + *

+ * + * {@link java.util.regex.Pattern}.{@link + * java.util.regex.Pattern#compile compile}(regex).{@link + * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(str).{@link + * java.util.regex.Matcher#replaceFirst replaceFirst}(repl) + * + *
+ * + *

+ * Note that backslashes ({@code \}) and dollar signs ({@code $}) in the + * replacement string may cause the results to be different than if it were + * being treated as a literal replacement string; see + * {@link java.util.regex.Matcher#replaceFirst}. + * Use {@link java.util.regex.Matcher#quoteReplacement} to suppress the special + * meaning of these characters, if desired. + * + * @param regex + * the regular expression to which this string is to be matched + * @param replacement + * the string to be substituted for the first match + * + * @return The resulting {@code String} + * + * @throws PatternSyntaxException + * if the regular expression's syntax is invalid + * + * @see java.util.regex.Pattern + * + * @since 1.4 + * @spec JSR-51 + */ + public String replaceFirst(String regex, String replacement) { + return Pattern.compile(regex).matcher(this).replaceFirst(replacement); + } + + /** + * Replaces each substring of this string that matches the given regular expression with the + * given replacement. + * + *

An invocation of this method of the form + * str{@code .replaceAll(}regex{@code ,} repl{@code )} + * yields exactly the same result as the expression + * + *

+ * + * {@link java.util.regex.Pattern}.{@link + * java.util.regex.Pattern#compile compile}(regex).{@link + * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(str).{@link + * java.util.regex.Matcher#replaceAll replaceAll}(repl) + * + *
+ * + *

+ * Note that backslashes ({@code \}) and dollar signs ({@code $}) in the + * replacement string may cause the results to be different than if it were + * being treated as a literal replacement string; see + * {@link java.util.regex.Matcher#replaceAll Matcher.replaceAll}. + * Use {@link java.util.regex.Matcher#quoteReplacement} to suppress the special + * meaning of these characters, if desired. + * + * @param regex + * the regular expression to which this string is to be matched + * @param replacement + * the string to be substituted for each match + * + * @return The resulting {@code String} + * + * @throws PatternSyntaxException + * if the regular expression's syntax is invalid + * + * @see java.util.regex.Pattern + * + * @since 1.4 + * @spec JSR-51 + */ + public String replaceAll(String regex, String replacement) { + return Pattern.compile(regex).matcher(this).replaceAll(replacement); + } + + /** + * Replaces each substring of this string that matches the literal target + * sequence with the specified literal replacement sequence. The + * replacement proceeds from the beginning of the string to the end, for + * example, replacing "aa" with "b" in the string "aaa" will result in + * "ba" rather than "ab". + * + * @param target The sequence of char values to be replaced + * @param replacement The replacement sequence of char values + * @return The resulting string + * @since 1.5 + */ + public String replace(CharSequence target, CharSequence replacement) { + String tgtStr = target.toString(); + String replStr = replacement.toString(); + int j = indexOf(tgtStr); + if (j < 0) { + return this; + } + int tgtLen = tgtStr.length(); + int tgtLen1 = Math.max(tgtLen, 1); + int thisLen = length(); + + int newLenHint = thisLen - tgtLen + replStr.length(); + if (newLenHint < 0) { + throw new OutOfMemoryError(); + } + StringBuilder sb = new StringBuilder(newLenHint); + int i = 0; + do { + sb.append(this, i, j).append(replStr); + i = j + tgtLen; + } while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0); + return sb.append(this, i, thisLen).toString(); + } + + /** + * Splits this string around matches of the given + * regular expression. + * + *

The array returned by this method contains each substring of this + * string that is terminated by another substring that matches the given + * expression or is terminated by the end of the string. The substrings in + * the array are in the order in which they occur in this string. If the + * expression does not match any part of the input then the resulting array + * has just one element, namely this string. + * + *

When there is a positive-width match at the beginning of this + * string then an empty leading substring is included at the beginning + * of the resulting array. A zero-width match at the beginning however + * never produces such empty leading substring. + * + *

The {@code limit} parameter controls the number of times the + * pattern is applied and therefore affects the length of the resulting + * array. + *

    + *
  • + * If the limit is positive then the pattern will be applied + * at most limit - 1 times, the array's length will be + * no greater than limit, and the array's last entry will contain + * all input beyond the last matched delimiter.

  • + * + *
  • + * If the limit is zero then the pattern will be applied as + * many times as possible, the array can have any length, and trailing + * empty strings will be discarded.

  • + * + *
  • + * If the limit is negative then the pattern will be applied + * as many times as possible and the array can have any length.

  • + *
+ * + *

The string {@code "boo:and:foo"}, for example, yields the + * following results with these parameters: + * + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Split example showing regex, limit, and result
RegexLimitResult
:2{@code { "boo", "and:foo" }}
5{@code { "boo", "and", "foo" }}
-2{@code { "boo", "and", "foo" }}
o5{@code { "b", "", ":and:f", "", "" }}
-2{@code { "b", "", ":and:f", "", "" }}
0{@code { "b", "", ":and:f" }}
+ * + *

An invocation of this method of the form + * str.{@code split(}regex{@code ,} n{@code )} + * yields the same result as the expression + * + *

+ * + * {@link java.util.regex.Pattern}.{@link + * java.util.regex.Pattern#compile compile}(regex).{@link + * java.util.regex.Pattern#split(java.lang.CharSequence,int) split}(strn) + * + *
+ * + * + * @param regex + * the delimiting regular expression + * + * @param limit + * the result threshold, as described above + * + * @return the array of strings computed by splitting this string + * around matches of the given regular expression + * + * @throws PatternSyntaxException + * if the regular expression's syntax is invalid + * + * @see java.util.regex.Pattern + * + * @since 1.4 + * @spec JSR-51 + */ + public String[] split(String regex, int limit) { + /* fastpath if the regex is a + (1)one-char String and this character is not one of the + RegEx's meta characters ".$|()[{^?*+\\", or + (2)two-char String and the first char is the backslash and + the second is not the ascii digit or ascii letter. + */ + char ch = 0; + if (((regex.length() == 1 && + ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) || + (regex.length() == 2 && + regex.charAt(0) == '\\' && + (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 && + ((ch-'a')|('z'-ch)) < 0 && + ((ch-'A')|('Z'-ch)) < 0)) && + (ch < Character.MIN_HIGH_SURROGATE || + ch > Character.MAX_LOW_SURROGATE)) + { + int off = 0; + int next = 0; + boolean limited = limit > 0; + ArrayList list = new ArrayList<>(); + while ((next = indexOf(ch, off)) != -1) { + if (!limited || list.size() < limit - 1) { + list.add(substring(off, next)); + off = next + 1; + } else { // last one + //assert (list.size() == limit - 1); + int last = length(); + list.add(substring(off, last)); + off = last; + break; + } + } + // If no match was found, return this + if (off == 0) + return new String[]{this}; + + // Add remaining segment + if (!limited || list.size() < limit) + list.add(substring(off, length())); + + // Construct result + int resultSize = list.size(); + if (limit == 0) { + while (resultSize > 0 && list.get(resultSize - 1).isEmpty()) { + resultSize--; + } + } + String[] result = new String[resultSize]; + return list.subList(0, resultSize).toArray(result); + } + return Pattern.compile(regex).split(this, limit); + } + + /** + * Splits this string around matches of the given regular expression. + * + *

This method works as if by invoking the two-argument {@link + * #split(String, int) split} method with the given expression and a limit + * argument of zero. Trailing empty strings are therefore not included in + * the resulting array. + * + *

The string {@code "boo:and:foo"}, for example, yields the following + * results with these expressions: + * + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + *
Split examples showing regex and result
RegexResult
:{@code { "boo", "and", "foo" }}
o{@code { "b", "", ":and:f" }}
+ * + * + * @param regex + * the delimiting regular expression + * + * @return the array of strings computed by splitting this string + * around matches of the given regular expression + * + * @throws PatternSyntaxException + * if the regular expression's syntax is invalid + * + * @see java.util.regex.Pattern + * + * @since 1.4 + * @spec JSR-51 + */ + public String[] split(String regex) { + return split(regex, 0); + } + + /** + * Returns a new String composed of copies of the + * {@code CharSequence elements} joined together with a copy of + * the specified {@code delimiter}. + * + *
For example, + *
{@code
+     *     String message = String.join("-", "Java", "is", "cool");
+     *     // message returned is: "Java-is-cool"
+     * }
+ * + * Note that if an element is null, then {@code "null"} is added. + * + * @param delimiter the delimiter that separates each element + * @param elements the elements to join together. + * + * @return a new {@code String} that is composed of the {@code elements} + * separated by the {@code delimiter} + * + * @throws NullPointerException If {@code delimiter} or {@code elements} + * is {@code null} + * + * @see java.util.StringJoiner + * @since 1.8 + */ + public static String join(CharSequence delimiter, CharSequence... elements) { + Objects.requireNonNull(delimiter); + Objects.requireNonNull(elements); + // Number of elements not likely worth Arrays.stream overhead. + StringJoiner joiner = new StringJoiner(delimiter); + for (CharSequence cs: elements) { + joiner.add(cs); + } + return joiner.toString(); + } + + /** + * Returns a new {@code String} composed of copies of the + * {@code CharSequence elements} joined together with a copy of the + * specified {@code delimiter}. + * + *
For example, + *
{@code
+     *     List strings = List.of("Java", "is", "cool");
+     *     String message = String.join(" ", strings);
+     *     //message returned is: "Java is cool"
+     *
+     *     Set strings =
+     *         new LinkedHashSet<>(List.of("Java", "is", "very", "cool"));
+     *     String message = String.join("-", strings);
+     *     //message returned is: "Java-is-very-cool"
+     * }
+ * + * Note that if an individual element is {@code null}, then {@code "null"} is added. + * + * @param delimiter a sequence of characters that is used to separate each + * of the {@code elements} in the resulting {@code String} + * @param elements an {@code Iterable} that will have its {@code elements} + * joined together. + * + * @return a new {@code String} that is composed from the {@code elements} + * argument + * + * @throws NullPointerException If {@code delimiter} or {@code elements} + * is {@code null} + * + * @see #join(CharSequence,CharSequence...) + * @see java.util.StringJoiner + * @since 1.8 + */ + public static String join(CharSequence delimiter, + Iterable elements) { + Objects.requireNonNull(delimiter); + Objects.requireNonNull(elements); + StringJoiner joiner = new StringJoiner(delimiter); + for (CharSequence cs: elements) { + joiner.add(cs); + } + return joiner.toString(); + } + + /** + * Converts all of the characters in this {@code String} to lower + * case using the rules of the given {@code Locale}. Case mapping is based + * on the Unicode Standard version specified by the {@link java.lang.Character Character} + * class. Since case mappings are not always 1:1 char mappings, the resulting + * {@code String} may be a different length than the original {@code String}. + *

+ * Examples of lowercase mappings are in the following table: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Lowercase mapping examples showing language code of locale, upper case, lower case, and description
Language Code of LocaleUpper CaseLower CaseDescription
tr (Turkish)\u0130\u0069capital letter I with dot above -> small letter i
tr (Turkish)\u0049\u0131capital letter I -> small letter dotless i
(all)French Friesfrench frieslowercased all chars in String
(all) + * ΙΧΘΥΣιχθυσlowercased all chars in String
+ * + * @param locale use the case transformation rules for this locale + * @return the {@code String}, converted to lowercase. + * @see java.lang.String#toLowerCase() + * @see java.lang.String#toUpperCase() + * @see java.lang.String#toUpperCase(Locale) + * @since 1.1 + */ + public String toLowerCase(Locale locale) { + return isLatin1() ? StringLatin1.toLowerCase(this, value, locale) + : StringUTF16.toLowerCase(this, value, locale); + } + + /** + * Converts all of the characters in this {@code String} to lower + * case using the rules of the default locale. This is equivalent to calling + * {@code toLowerCase(Locale.getDefault())}. + *

+ * Note: This method is locale sensitive, and may produce unexpected + * results if used for strings that are intended to be interpreted locale + * independently. + * Examples are programming language identifiers, protocol keys, and HTML + * tags. + * For instance, {@code "TITLE".toLowerCase()} in a Turkish locale + * returns {@code "t\u005Cu0131tle"}, where '\u005Cu0131' is the + * LATIN SMALL LETTER DOTLESS I character. + * To obtain correct results for locale insensitive strings, use + * {@code toLowerCase(Locale.ROOT)}. + * + * @return the {@code String}, converted to lowercase. + * @see java.lang.String#toLowerCase(Locale) + */ + public String toLowerCase() { + return toLowerCase(Locale.getDefault()); + } + + /** + * Converts all of the characters in this {@code String} to upper + * case using the rules of the given {@code Locale}. Case mapping is based + * on the Unicode Standard version specified by the {@link java.lang.Character Character} + * class. Since case mappings are not always 1:1 char mappings, the resulting + * {@code String} may be a different length than the original {@code String}. + *

+ * Examples of locale-sensitive and 1:M case mappings are in the following table. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Examples of locale-sensitive and 1:M case mappings. Shows Language code of locale, lower case, upper case, and description.
Language Code of LocaleLower CaseUpper CaseDescription
tr (Turkish)\u0069\u0130small letter i -> capital letter I with dot above
tr (Turkish)\u0131\u0049small letter dotless i -> capital letter I
(all)\u00df\u0053 \u0053small letter sharp s -> two letters: SS
(all)FahrvergnügenFAHRVERGNÜGEN
+ * @param locale use the case transformation rules for this locale + * @return the {@code String}, converted to uppercase. + * @see java.lang.String#toUpperCase() + * @see java.lang.String#toLowerCase() + * @see java.lang.String#toLowerCase(Locale) + * @since 1.1 + */ + public String toUpperCase(Locale locale) { + return isLatin1() ? StringLatin1.toUpperCase(this, value, locale) + : StringUTF16.toUpperCase(this, value, locale); + } + + /** + * Converts all of the characters in this {@code String} to upper + * case using the rules of the default locale. This method is equivalent to + * {@code toUpperCase(Locale.getDefault())}. + *

+ * Note: This method is locale sensitive, and may produce unexpected + * results if used for strings that are intended to be interpreted locale + * independently. + * Examples are programming language identifiers, protocol keys, and HTML + * tags. + * For instance, {@code "title".toUpperCase()} in a Turkish locale + * returns {@code "T\u005Cu0130TLE"}, where '\u005Cu0130' is the + * LATIN CAPITAL LETTER I WITH DOT ABOVE character. + * To obtain correct results for locale insensitive strings, use + * {@code toUpperCase(Locale.ROOT)}. + * + * @return the {@code String}, converted to uppercase. + * @see java.lang.String#toUpperCase(Locale) + */ + public String toUpperCase() { + return toUpperCase(Locale.getDefault()); + } + + /** + * Returns a string whose value is this string, with all leading + * and trailing space removed, where space is defined + * as any character whose codepoint is less than or equal to + * {@code 'U+0020'} (the space character). + *

+ * If this {@code String} object represents an empty character + * sequence, or the first and last characters of character sequence + * represented by this {@code String} object both have codes + * that are not space (as defined above), then a + * reference to this {@code String} object is returned. + *

+ * Otherwise, if all characters in this string are space (as + * defined above), then a {@code String} object representing an + * empty string is returned. + *

+ * Otherwise, let k be the index of the first character in the + * string whose code is not a space (as defined above) and let + * m be the index of the last character in the string whose code + * is not a space (as defined above). A {@code String} + * object is returned, representing the substring of this string that + * begins with the character at index k and ends with the + * character at index m-that is, the result of + * {@code this.substring(k, m + 1)}. + *

+ * This method may be used to trim space (as defined above) from + * the beginning and end of a string. + * + * @return a string whose value is this string, with all leading + * and trailing space removed, or this string if it + * has no leading or trailing space. + */ + public String trim() { + String ret = isLatin1() ? StringLatin1.trim(value) + : StringUTF16.trim(value); + return ret == null ? this : ret; + } + + /** + * Returns a string whose value is this string, with all leading + * and trailing {@link Character#isWhitespace(int) white space} + * removed. + *

+ * If this {@code String} object represents an empty string, + * or if all code points in this string are + * {@link Character#isWhitespace(int) white space}, then an empty string + * is returned. + *

+ * Otherwise, returns a substring of this string beginning with the first + * code point that is not a {@link Character#isWhitespace(int) white space} + * up to and including the last code point that is not a + * {@link Character#isWhitespace(int) white space}. + *

+ * This method may be used to strip + * {@link Character#isWhitespace(int) white space} from + * the beginning and end of a string. + * + * @return a string whose value is this string, with all leading + * and trailing white space removed + * + * @see Character#isWhitespace(int) + * + * @since 11 + */ + public String strip() { + String ret = isLatin1() ? StringLatin1.strip(value) + : StringUTF16.strip(value); + return ret == null ? this : ret; + } + + /** + * Returns a string whose value is this string, with all leading + * {@link Character#isWhitespace(int) white space} removed. + *

+ * If this {@code String} object represents an empty string, + * or if all code points in this string are + * {@link Character#isWhitespace(int) white space}, then an empty string + * is returned. + *

+ * Otherwise, returns a substring of this string beginning with the first + * code point that is not a {@link Character#isWhitespace(int) white space} + * up to to and including the last code point of this string. + *

+ * This method may be used to trim + * {@link Character#isWhitespace(int) white space} from + * the beginning of a string. + * + * @return a string whose value is this string, with all leading white + * space removed + * + * @see Character#isWhitespace(int) + * + * @since 11 + */ + public String stripLeading() { + String ret = isLatin1() ? StringLatin1.stripLeading(value) + : StringUTF16.stripLeading(value); + return ret == null ? this : ret; + } + + /** + * Returns a string whose value is this string, with all trailing + * {@link Character#isWhitespace(int) white space} removed. + *

+ * If this {@code String} object represents an empty string, + * or if all characters in this string are + * {@link Character#isWhitespace(int) white space}, then an empty string + * is returned. + *

+ * Otherwise, returns a substring of this string beginning with the first + * code point of this string up to and including the last code point + * that is not a {@link Character#isWhitespace(int) white space}. + *

+ * This method may be used to trim + * {@link Character#isWhitespace(int) white space} from + * the end of a string. + * + * @return a string whose value is this string, with all trailing white + * space removed + * + * @see Character#isWhitespace(int) + * + * @since 11 + */ + public String stripTrailing() { + String ret = isLatin1() ? StringLatin1.stripTrailing(value) + : StringUTF16.stripTrailing(value); + return ret == null ? this : ret; + } + + /** + * Returns {@code true} if the string is empty or contains only + * {@link Character#isWhitespace(int) white space} codepoints, + * otherwise {@code false}. + * + * @return {@code true} if the string is empty or contains only + * {@link Character#isWhitespace(int) white space} codepoints, + * otherwise {@code false} + * + * @see Character#isWhitespace(int) + * + * @since 11 + */ + public boolean isBlank() { + return indexOfNonWhitespace() == length(); + } + + private int indexOfNonWhitespace() { + if (isLatin1()) { + return StringLatin1.indexOfNonWhitespace(value); + } else { + return StringUTF16.indexOfNonWhitespace(value); + } + } + + /** + * Returns a stream of lines extracted from this string, + * separated by line terminators. + *

+ * A line terminator is one of the following: + * a line feed character {@code "\n"} (U+000A), + * a carriage return character {@code "\r"} (U+000D), + * or a carriage return followed immediately by a line feed + * {@code "\r\n"} (U+000D U+000A). + *

+ * A line is either a sequence of zero or more characters + * followed by a line terminator, or it is a sequence of one or + * more characters followed by the end of the string. A + * line does not include the line terminator. + *

+ * The stream returned by this method contains the lines from + * this string in the order in which they occur. + * + * @apiNote This definition of line implies that an empty + * string has zero lines and that there is no empty line + * following a line terminator at the end of a string. + * + * @implNote This method provides better performance than + * split("\R") by supplying elements lazily and + * by faster search of new line terminators. + * + * @return the stream of lines extracted from this string + * + * @since 11 + */ + public Stream lines() { + return isLatin1() ? StringLatin1.lines(value) + : StringUTF16.lines(value); + } + + /** + * This object (which is already a string!) is itself returned. + * + * @return the string itself. + */ + public String toString() { + return this; + } + + /** + * Returns a stream of {@code int} zero-extending the {@code char} values + * from this sequence. Any char which maps to a surrogate code + * point is passed through uninterpreted. + * + * @return an IntStream of char values from this sequence + * @since 9 + */ + @Override + public IntStream chars() { + return StreamSupport.intStream( + isLatin1() ? new StringLatin1.CharsSpliterator(value, Spliterator.IMMUTABLE) + : new StringUTF16.CharsSpliterator(value, Spliterator.IMMUTABLE), + false); + } + + + /** + * 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. + * + * @return an IntStream of Unicode code points from this sequence + * @since 9 + */ + @Override + public IntStream codePoints() { + return StreamSupport.intStream( + isLatin1() ? new StringLatin1.CharsSpliterator(value, Spliterator.IMMUTABLE) + : new StringUTF16.CodePointsSpliterator(value, Spliterator.IMMUTABLE), + false); + } + + /** + * Converts this string to a new character array. + * + * @return a newly allocated character array whose length is the length + * of this string and whose contents are initialized to contain + * the character sequence represented by this string. + */ + public char[] toCharArray() { + return isLatin1() ? StringLatin1.toChars(value) + : StringUTF16.toChars(value); + } + + /** + * Returns a formatted string using the specified format string and + * arguments. + * + *

The locale always used is the one returned by {@link + * java.util.Locale#getDefault(java.util.Locale.Category) + * Locale.getDefault(Locale.Category)} with + * {@link java.util.Locale.Category#FORMAT FORMAT} category specified. + * + * @param format + * A format string + * + * @param args + * Arguments referenced by the format specifiers in the format + * string. If there are more arguments than format specifiers, the + * extra arguments are ignored. The number of arguments is + * variable and may be zero. The maximum number of arguments is + * limited by the maximum dimension of a Java array as defined by + * The Java™ Virtual Machine Specification. + * The behaviour on a + * {@code null} argument depends on the conversion. + * + * @throws java.util.IllegalFormatException + * If a format string contains an illegal syntax, a format + * specifier that is incompatible with the given arguments, + * insufficient arguments given the format string, or other + * illegal conditions. For specification of all possible + * formatting errors, see the Details section of the + * formatter class specification. + * + * @return A formatted string + * + * @see java.util.Formatter + * @since 1.5 + */ + public static String format(String format, Object... args) { + return new Formatter().format(format, args).toString(); + } + + /** + * Returns a formatted string using the specified locale, format string, + * and arguments. + * + * @param l + * The {@linkplain java.util.Locale locale} to apply during + * formatting. If {@code l} is {@code null} then no localization + * is applied. + * + * @param format + * A format string + * + * @param args + * Arguments referenced by the format specifiers in the format + * string. If there are more arguments than format specifiers, the + * extra arguments are ignored. The number of arguments is + * variable and may be zero. The maximum number of arguments is + * limited by the maximum dimension of a Java array as defined by + * The Java™ Virtual Machine Specification. + * The behaviour on a + * {@code null} argument depends on the + * conversion. + * + * @throws java.util.IllegalFormatException + * If a format string contains an illegal syntax, a format + * specifier that is incompatible with the given arguments, + * insufficient arguments given the format string, or other + * illegal conditions. For specification of all possible + * formatting errors, see the Details section of the + * formatter class specification + * + * @return A formatted string + * + * @see java.util.Formatter + * @since 1.5 + */ + public static String format(Locale l, String format, Object... args) { + return new Formatter(l).format(format, args).toString(); + } + + /** + * Returns the string representation of the {@code Object} argument. + * + * @param obj an {@code Object}. + * @return if the argument is {@code null}, then a string equal to + * {@code "null"}; otherwise, the value of + * {@code obj.toString()} is returned. + * @see java.lang.Object#toString() + */ + public static String valueOf(Object obj) { + return (obj == null) ? "null" : obj.toString(); + } + + /** + * Returns the string representation of the {@code char} array + * argument. The contents of the character array are copied; subsequent + * modification of the character array does not affect the returned + * string. + * + * @param data the character array. + * @return a {@code String} that contains the characters of the + * character array. + */ + public static String valueOf(char data[]) { + return new String(data); + } + + /** + * Returns the string representation of a specific subarray of the + * {@code char} array argument. + *

+ * The {@code offset} argument is the index of the first + * character of the subarray. The {@code count} argument + * specifies the length of the subarray. The contents of the subarray + * are copied; subsequent modification of the character array does not + * affect the returned string. + * + * @param data the character array. + * @param offset initial offset of the subarray. + * @param count length of the subarray. + * @return a {@code String} that contains the characters of the + * specified subarray of the character array. + * @exception IndexOutOfBoundsException if {@code offset} is + * negative, or {@code count} is negative, or + * {@code offset+count} is larger than + * {@code data.length}. + */ + public static String valueOf(char data[], int offset, int count) { + return new String(data, offset, count); + } + + /** + * Equivalent to {@link #valueOf(char[], int, int)}. + * + * @param data the character array. + * @param offset initial offset of the subarray. + * @param count length of the subarray. + * @return a {@code String} that contains the characters of the + * specified subarray of the character array. + * @exception IndexOutOfBoundsException if {@code offset} is + * negative, or {@code count} is negative, or + * {@code offset+count} is larger than + * {@code data.length}. + */ + public static String copyValueOf(char data[], int offset, int count) { + return new String(data, offset, count); + } + + /** + * Equivalent to {@link #valueOf(char[])}. + * + * @param data the character array. + * @return a {@code String} that contains the characters of the + * character array. + */ + public static String copyValueOf(char data[]) { + return new String(data); + } + + /** + * Returns the string representation of the {@code boolean} argument. + * + * @param b a {@code boolean}. + * @return if the argument is {@code true}, a string equal to + * {@code "true"} is returned; otherwise, a string equal to + * {@code "false"} is returned. + */ + public static String valueOf(boolean b) { + return b ? "true" : "false"; + } + + /** + * Returns the string representation of the {@code char} + * argument. + * + * @param c a {@code char}. + * @return a string of length {@code 1} containing + * as its single character the argument {@code c}. + */ + public static String valueOf(char c) { + if (COMPACT_STRINGS && StringLatin1.canEncode(c)) { + return new String(StringLatin1.toBytes(c), LATIN1); + } + return new String(StringUTF16.toBytes(c), UTF16); + } + + /** + * Returns the string representation of the {@code int} argument. + *

+ * The representation is exactly the one returned by the + * {@code Integer.toString} method of one argument. + * + * @param i an {@code int}. + * @return a string representation of the {@code int} argument. + * @see java.lang.Integer#toString(int, int) + */ + public static String valueOf(int i) { + return Integer.toString(i); + } + + /** + * Returns the string representation of the {@code long} argument. + *

+ * The representation is exactly the one returned by the + * {@code Long.toString} method of one argument. + * + * @param l a {@code long}. + * @return a string representation of the {@code long} argument. + * @see java.lang.Long#toString(long) + */ + public static String valueOf(long l) { + return Long.toString(l); + } + + /** + * Returns the string representation of the {@code float} argument. + *

+ * The representation is exactly the one returned by the + * {@code Float.toString} method of one argument. + * + * @param f a {@code float}. + * @return a string representation of the {@code float} argument. + * @see java.lang.Float#toString(float) + */ + public static String valueOf(float f) { + return Float.toString(f); + } + + /** + * Returns the string representation of the {@code double} argument. + *

+ * The representation is exactly the one returned by the + * {@code Double.toString} method of one argument. + * + * @param d a {@code double}. + * @return a string representation of the {@code double} argument. + * @see java.lang.Double#toString(double) + */ + public static String valueOf(double d) { + return Double.toString(d); + } + + /** + * Returns a canonical representation for the string object. + *

+ * A pool of strings, initially empty, is maintained privately by the + * class {@code String}. + *

+ * When the intern method is invoked, if the pool already contains a + * string equal to this {@code String} object as determined by + * the {@link #equals(Object)} method, then the string from the pool is + * returned. Otherwise, this {@code String} object is added to the + * pool and a reference to this {@code String} object is returned. + *

+ * It follows that for any two strings {@code s} and {@code t}, + * {@code s.intern() == t.intern()} is {@code true} + * if and only if {@code s.equals(t)} is {@code true}. + *

+ * All literal strings and string-valued constant expressions are + * interned. String literals are defined in section 3.10.5 of the + * The Java™ Language Specification. + * + * @return a string that has the same contents as this string, but is + * guaranteed to be from a pool of unique strings. + * @jls 3.10.5 String Literals + */ + public native String intern(); + + /** + * Returns a string whose value is the concatenation of this + * string repeated {@code count} times. + *

+ * If this string is empty or count is zero then the empty + * string is returned. + * + * @param count number of times to repeat + * + * @return A string composed of this string repeated + * {@code count} times or the empty string if this + * string is empty or count is zero + * + * @throws IllegalArgumentException if the {@code count} is + * negative. + * + * @since 11 + */ + public String repeat(int count) { + if (count < 0) { + throw new IllegalArgumentException("count is negative: " + count); + } + if (count == 1) { + return this; + } + final int len = value.length; + if (len == 0 || count == 0) { + return ""; + } + if (len == 1) { + final byte[] single = new byte[count]; + Arrays.fill(single, value[0]); + return new String(single, coder); + } + if (Integer.MAX_VALUE / count < len) { + throw new OutOfMemoryError("Repeating " + len + " bytes String " + count + + " times will produce a String exceeding maximum size."); + } + final int limit = len * count; + final byte[] multiple = new byte[limit]; + System.arraycopy(value, 0, multiple, 0, len); + int copied = len; + for (; copied < limit - copied; copied <<= 1) { + System.arraycopy(multiple, 0, multiple, copied, copied); + } + System.arraycopy(multiple, 0, multiple, copied, limit - copied); + return new String(multiple, coder); + } + + //////////////////////////////////////////////////////////////// + + /** + * Copy character bytes from this string into dst starting at dstBegin. + * This method doesn't perform any range checking. + * + * Invoker guarantees: dst is in UTF16 (inflate itself for asb), if two + * coders are different, and dst is big enough (range check) + * + * @param dstBegin the char index, not offset of byte[] + * @param coder the coder of dst[] + */ + void getBytes(byte dst[], int dstBegin, byte coder) { + if (coder() == coder) { + System.arraycopy(value, 0, dst, dstBegin << coder, value.length); + } else { // this.coder == LATIN && coder == UTF16 + StringLatin1.inflate(value, 0, dst, dstBegin, value.length); + } + } + + /* + * Package private constructor. Trailing Void argument is there for + * disambiguating it against other (public) constructors. + * + * Stores the char[] value into a byte[] that each byte represents + * the8 low-order bits of the corresponding character, if the char[] + * contains only latin1 character. Or a byte[] that stores all + * characters in their byte sequences defined by the {@code StringUTF16}. + */ + String(char[] value, int off, int len, Void sig) { + if (len == 0) { + this.value = "".value; + this.coder = "".coder; + return; + } + if (COMPACT_STRINGS) { + byte[] val = StringUTF16.compress(value, off, len); + if (val != null) { + this.value = val; + this.coder = LATIN1; + return; + } + } + this.coder = UTF16; + this.value = StringUTF16.toBytes(value, off, len); + } + + /* + * Package private constructor. Trailing Void argument is there for + * disambiguating it against other (public) constructors. + */ + String(AbstractStringBuilder asb, Void sig) { + byte[] val = asb.getValue(); + int length = asb.length(); + if (asb.isLatin1()) { + this.coder = LATIN1; + this.value = Arrays.copyOfRange(val, 0, length); + } else { + if (COMPACT_STRINGS) { + byte[] buf = StringUTF16.compress(val, 0, length); + if (buf != null) { + this.coder = LATIN1; + this.value = buf; + return; + } + } + this.coder = UTF16; + this.value = Arrays.copyOfRange(val, 0, length << 1); + } + } + + /* + * Package private constructor which shares value array for speed. + */ + String(byte[] value, byte coder) { + this.value = value; + this.coder = coder; + } + + byte coder() { + return COMPACT_STRINGS ? coder : UTF16; + } + + byte[] value() { + return value; + } + + private boolean isLatin1() { + return COMPACT_STRINGS && coder == LATIN1; + } + + @Native static final byte LATIN1 = 0; + @Native static final byte UTF16 = 1; + + /* + * StringIndexOutOfBoundsException if {@code index} is + * negative or greater than or equal to {@code length}. + */ + static void checkIndex(int index, int length) { + if (index < 0 || index >= length) { + throw new StringIndexOutOfBoundsException("index " + index + + ",length " + length); + } + } + + /* + * StringIndexOutOfBoundsException if {@code offset} + * is negative or greater than {@code length}. + */ + static void checkOffset(int offset, int length) { + if (offset < 0 || offset > length) { + throw new StringIndexOutOfBoundsException("offset " + offset + + ",length " + length); + } + } + + /* + * Check {@code offset}, {@code count} against {@code 0} and {@code length} + * bounds. + * + * @throws StringIndexOutOfBoundsException + * If {@code offset} is negative, {@code count} is negative, + * or {@code offset} is greater than {@code length - count} + */ + static void checkBoundsOffCount(int offset, int count, int length) { + if (offset < 0 || count < 0 || offset > length - count) { + throw new StringIndexOutOfBoundsException( + "offset " + offset + ", count " + count + ", length " + length); + } + } + + /* + * Check {@code begin}, {@code end} against {@code 0} and {@code length} + * bounds. + * + * @throws StringIndexOutOfBoundsException + * If {@code begin} is negative, {@code begin} is greater than + * {@code end}, or {@code end} is greater than {@code length}. + */ + static void checkBoundsBeginEnd(int begin, int end, int length) { + if (begin < 0 || begin > end || end > length) { + throw new StringIndexOutOfBoundsException( + "begin " + begin + ", end " + end + ", length " + length); + } + } + + /** + * Returns the string representation of the {@code codePoint} + * argument. + * + * @param codePoint a {@code codePoint}. + * @return a string of length {@code 1} or {@code 2} containing + * as its single character the argument {@code codePoint}. + * @throws IllegalArgumentException if the specified + * {@code codePoint} is not a {@linkplain Character#isValidCodePoint + * valid Unicode code point}. + */ + static String valueOfCodePoint(int codePoint) { + if (COMPACT_STRINGS && StringLatin1.canEncode(codePoint)) { + return new String(StringLatin1.toBytes((char)codePoint), LATIN1); + } else if (Character.isBmpCodePoint(codePoint)) { + return new String(StringUTF16.toBytes((char)codePoint), UTF16); + } else if (Character.isSupplementaryCodePoint(codePoint)) { + return new String(StringUTF16.toBytesSupplementary(codePoint), UTF16); + } + + throw new IllegalArgumentException( + format("Not a valid Unicode code point: 0x%X", codePoint)); + } +} + + +} diff --git a/SetTest1.java b/SetTest1.java new file mode 100644 index 0000000..e63d2ba --- /dev/null +++ b/SetTest1.java @@ -0,0 +1,21 @@ +import java.util.*; + +class SetTest1{ + public static void main(String []args) { + String string1= "ABFED"; + String string2= "AFBHI"; + + Set set1 = string2CharSet(string1); + set1.retainAll(string2CharSet(string2)); + + System.out.println(set1.toString()); + } + + private static Set string2CharSet(String s1) { + Set set1=new HashSet(); + Character[] cha1 = s1.chars().mapToObj(c -> (char) c).toArray(Character[]::new); + set1.addAll(Arrays.asList(cha1)); + return set1; + } + +} \ No newline at end of file diff --git a/WF b/WF new file mode 100644 index 0000000..b2eedb6 --- /dev/null +++ b/WF @@ -0,0 +1,29 @@ +00000000: cafe babe 0000 0037 0020 0a00 0700 1108 .......7. ...... +00000010: 0012 0900 0600 1309 0014 0015 0a00 1600 ................ +00000020: 1707 0018 0700 1901 0001 7801 0012 4c6a ..........x...Lj +00000030: 6176 612f 6c61 6e67 2f53 7472 696e 673b ava/lang/String; +00000040: 0100 063c 696e 6974 3e01 0003 2829 5601 ......()V. +00000050: 0004 436f 6465 0100 0f4c 696e 654e 756d ..Code...LineNum +00000060: 6265 7254 6162 6c65 0100 0474 6573 7401 berTable...test. +00000070: 000a 536f 7572 6365 4669 6c65 0100 0f46 ..SourceFile...F +00000080: 696e 616c 466c 6167 312e 6a61 7661 0c00 inalFlag1.java.. +00000090: 0a00 0b01 0006 4669 6e61 6c3f 0c00 0800 ......Final?.... +000000a0: 0907 001a 0c00 1b00 1c07 001d 0c00 1e00 ................ +000000b0: 1f01 000a 4669 6e61 6c46 6c61 6731 0100 ....FinalFlag1.. +000000c0: 106a 6176 612f 6c61 6e67 2f4f 626a 6563 .java/lang/Objec +000000d0: 7401 0010 6a61 7661 2f6c 616e 672f 5379 t...java/lang/Sy +000000e0: 7374 656d 0100 036f 7574 0100 154c 6a61 stem...out...Lja +000000f0: 7661 2f69 6f2f 5072 696e 7453 7472 6561 va/io/PrintStrea +00000100: 6d3b 0100 136a 6176 612f 696f 2f50 7269 m;...java/io/Pri +00000110: 6e74 5374 7265 616d 0100 0770 7269 6e74 ntStream...print +00000120: 6c6e 0100 1528 4c6a 6176 612f 6c61 6e67 ln...(Ljava/lang +00000130: 2f53 7472 696e 673b 2956 0020 0006 0007 /String;)V. .... +00000140: 0000 0001 0002 0008 0009 0000 0002 0001 ................ +00000150: 000a 000b 0001 000c 0000 002b 0002 0001 ...........+.... +00000160: 0000 000b 2ab7 0001 2a12 02b5 0003 b100 ....*...*....... +00000170: 0000 0100 0d00 0000 0e00 0300 0000 0300 ................ +00000180: 0400 0400 0a00 0500 1100 0e00 0b00 0100 ................ +00000190: 0c00 0000 2700 0200 0100 0000 0bb2 0004 ....'........... +000001a0: 2ab4 0003 b600 05b1 0000 0001 000d 0000 *............... +000001b0: 000a 0002 0000 0007 000a 0008 0001 000f ................ +000001c0: 0000 0002 0010 ......