Как реализовать subSequence в одну строку?
Всем привет! Есть задание написать статический класс AsciiCharSequence, реализующий компактное хранение последовательности ASCII-символов (их коды влезают в один байт) в массиве байт. По сравнению с классом String из Java 8, хранящим каждый символ как char, AsciiCharSequence будет занимать в два раза меньше памяти
Класс AsciiCharSequence должен:
реализовывать интерфейс java.lang.CharSequence;
иметь конструктор, принимающий массив байт;
определять методы length(), charAt(), subSequence() и toString()
Есть работающий код, но в нем нужно реализовать subSequence в одну строку. Как это сделать? Бьюсь над этим несколько дней, но видимо мозги уже замылились. Подскажите, как это реализовать?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
public static class AsciiCharSequence implements java.lang.CharSequence { private byte[] bytes; public AsciiCharSequence(byte[] bytes) { this.bytes = bytes.clone(); } @Override public int length() { return bytes.length; } @Override public char charAt(int i) { return (char) bytes[i]; } @Override public String toString() { return new String(bytes); } public AsciiCharSequence subSequence(int i, int j) { byte[] ex = new byte[j - i]; for (int a = 0; a j - i; a++) { ex[a] = (byte) this.charAt(i + a); } AsciiCharSequence x = new AsciiCharSequence(ex); return x; } }
Interface CharSequence
A CharSequence is a readable sequence of char values. This interface provides uniform, read-only access to many different kinds of char sequences. A char value represents a character in the Basic Multilingual Plane (BMP) or a surrogate. Refer to Unicode Character Representation for details.
This interface does not refine the general contracts of the equals and hashCode methods. The result of testing two objects that implement CharSequence for equality is therefore, in general, undefined. Each object may be implemented by a different class, and there is no guarantee that each class will be capable of testing its instances for equality with those of the other. It is therefore inappropriate to use arbitrary CharSequence instances as elements in a set or as keys in a map.
Method Summary
Method Details
length
Returns the length of this character sequence. The length is the number of 16-bit char s in the sequence.
charAt
Returns the char value at the specified index. An index ranges from zero to length() — 1 . The first char value of the sequence is at index zero, the next at index one, and so on, as for array indexing. If the char value specified by the index is a surrogate, the surrogate value is returned.
isEmpty
subSequence
Returns a CharSequence that is a subsequence of this sequence. The subsequence starts with the char value at the specified index and ends with the char value at index end — 1 . The length (in char s) of the returned sequence is end — start , so if start == end then an empty sequence is returned.
toString
Returns a string containing the characters in this sequence in the same order as this sequence. The length of the string will be the length of this sequence.
chars
Returns a stream of int zero-extending the char values from this sequence. Any char which maps to a surrogate code point is passed through uninterpreted. The stream binds to this sequence when the terminal stream operation commences (specifically, for mutable sequences the spliterator for the stream is late-binding). If the sequence is modified during that operation then the result is undefined.
codePoints
Returns a stream of code point values from this sequence. Any surrogate pairs encountered in the sequence are combined as if by 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 int values which are then passed to the stream. The stream binds to this sequence when the terminal stream operation commences (specifically, for mutable sequences the spliterator for the stream is late-binding). If the sequence is modified during that operation then the result is undefined.
compare
Compares two CharSequence instances lexicographically. Returns a negative value, zero, or a positive value if the first sequence is lexicographically less than, equal to, or greater than the second, respectively. The lexicographical ordering of CharSequence is defined as follows. Consider a CharSequence cs of length len to be a sequence of char values, cs[0] to cs[len-1]. Suppose k is the lowest index at which the corresponding char values from each sequence differ. The lexicographic ordering of the sequences is determined by a numeric comparison of the char values cs1[k] with cs2[k]. If there is no such index k, the shorter sequence is considered lexicographically less than the other. If the sequences have the same length, the sequences are considered lexicographically equal.
Report a bug or suggest an enhancement
For further API reference and developer documentation see the Java SE Documentation, which contains more detailed, developer-targeted descriptions with conceptual overviews, definitions of terms, workarounds, and working code examples. Other versions.
Java is a trademark or registered trademark of Oracle and/or its affiliates in the US and other countries.
Copyright © 1993, 2023, Oracle and/or its affiliates, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
All rights reserved. Use is subject to license terms and the documentation redistribution policy.
Как привести массив byte[] к виду CharSequence?
Нужно написать класс AsciiCharSequence , который реализует хранение последовательности ASCII-символов в массиве байт. По сравнению с классом String , хранящим каждый символ как char, AsciiCharSequence будет занимать меньше памяти.
Класс AsciiCharSequence должен:
- реализовывать интерфейс java.lang.CharSequence ;
- иметь конструктор, принимающий массив байт;
- определять методы length() , charAt() , subSequence() и toString()
public class AsciiCharSequence implements CharSequence < byte[] a1; public AsciiCharSequence(byte[] a)< //Конструктор класса a = this.a1; >@Override public String toString() < //Переопределение toString() return "AsciiCharSequence
Ответы (3 шт):
Просто создайте новый экземпляр своего типа:
@Override public CharSequence subSequence(int start, int end) < //Переопределение subSequence() return new AsciiCharSequence(Arrays.copyOfRange(a1, start, end)); >
Заметьте, что toString() вы переопределили неправильно. В документации ясно сказано:
String toString()
Returns a string containing the characters in this sequence in the same order as this sequence. The length of the string will be the length of this sequence.
То есть если вы переопределяете интерфейс CharSequence , вы обязаны вернуть в toString() строку, которая соответствует содержимому вашего CharSequence . Сделать это несложно:
@Override public String toString() < //Переопределение toString() return new String(a1, java.nio.charset.StandardCharsets.ISO_8859_1); >
Можно переписать класс в таком виде:
public class AsciiCharSequence implements CharSequence < private byte[] data; public AsciiCharSequence(byte[] data) < this.data = data; >@Override public int length() < return data.length; >@Override public char charAt(int index) < return (char) (data[index] & 0xff); >@Override public CharSequence subSequence(int start, int end) < int length = end - start; byte[] bytes = new byte[length]; for (int i = 0, j = start; i < length; i++, j++) < bytes[i] = data[j]; >return new AsciiCharSequence(bytes); > @Override public String toString() < return new String(data); >>
class AsciiCharSequence implements CharSequence < private byte[] byteSequence; public AsciiCharSequence(byte[] bytesSequence) < this.byteSequence = bytesSequence; >@Override public int length() < return byteSequence.length; >@Override public char charAt(int index) < return (char) byteSequence[index]; >@Override public CharSequence subSequence(int start, int end) < return new AsciiCharSequence(java.util.Arrays.copyOfRange(byteSequence, start, end)); >@Override public String toString() < return new String(byteSequence); >>