Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,43 +1,86 @@
package edu.technopolis.advjava;

package edu.technopolis;
import java.io.Serializable;

/**
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Комментарии можно было не удалять. Или стоило написать свои, например, про особенности реализации.

* Реализованная специальным образом строка (аналог {@link java.lang.String}),
* хранящий содержимое строки кусочкам (chunks) для лучшего переиспользования памяти при активном
* создании подстрок.
*/
public class CustomString implements CharSequence, Serializable {
private final char[][] chunks;

/*
* todo add complimentary fields if required
*/
private char[][] chunks;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Immutability или неизменяемость - один из важных паттернов проектирования классов. К тому же final имеет важную семантику с точки зрения многопоточного программирования. Так что final стоит поставить на все поля класса.

int offset;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

стоит писать комментарии с объяснением того, что такое offset. Иначе через месяц будет сложно разобраться, что имелось в виду.

int count;
private int length;
int chunkSize;

public CustomString(String str) {
this.count = str.length();
this.length = str.length();
this.chunkSize =(int)Math.sqrt(this.length)+1;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Эта стратегия выбора размера кусочка (chunk), на которые разбиваются строки очень спорная. Ну, или напишите комментарий, почему она имеет право на жизнь. Я привёл в пример конкретную задачу - поместить "Войну и мир" в такую строку с возможностью переиспользования.
По-моему, стоило сделать конструктор (String source, int chunkSize) с возможностью передачи размера чанка, и перегрузить конструктор (с такую сигнатурой, как у вас), вызывая из него this(source, DEFAULT_CHUNK_SIZE), передав в него какое-то большое значение по умолчанию, к примеру 10 000 символов.

this.chunks = new char[chunkSize][chunkSize];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Кстати, в случае строки размером 1, вас размер чанка будет 2.

int k = 0;
for (int i = 0; i < chunkSize; i++){
for (int j = 0; j < chunkSize; j++) {
if (k < length) {
chunks[i][j] = str.charAt(k);
k++;
}
}
}
}

/*
* todo add constructor or group of constructors
*/
public CustomString(char[][] chunks, int offset, int count, int chunckSize) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Либо конструктор стоит сделать приватным, либо добавить большое кол-во проверок на совместимость аргументов, потому что неправильными настройками строки легко "прострелить себе ногу".

this.chunks = chunks;
this.offset = offset;
this.count = count;
this.chunkSize = chunckSize;

}

@Override
public int length() {
//todo implement length here
return count;
}

@Override
public char charAt(int index) {
//todo implement charAt here
if (index < 0 || index >= count) {
throw new IndexOutOfBoundsException("Out of bounds");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В исключение стоит включить информацию о том, что собственно вышло за пределы массива. Например, писать - требовался такой-то символ, но длинна строки всего столько-то.

}
return chunks[(index+offset)/chunkSize][(index+offset)%chunkSize];
}

@Override
public CharSequence subSequence(int start, int end) {
//todo implement subSequence here
if (start < 0 || start > end || end > length) {
throw new StringIndexOutOfBoundsException("Out of bounds");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Непоследовательность. 10 строками выше выкидывается другое исключение.

}
edu.technopolis.CustomString nc = new edu.technopolis.CustomString(chunks, offset + start, end - start + 1, chunkSize);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь нет смысла использовать полное имя строки. Достаточно CustomString

return nc;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь не совсем так реализован механизм переиспользования. Идея в том, чтобы использовать только те кусоки строки, которые нужны. Например, если вся "Война и мир" состоит из 1000 чанков, то в 4ом томе должно быть только 250 чанков. Иначе весь смысл разбиения на чанки теряется.

}

@Override
public String toString() {
//todo fold chunks into single char array
return new String(/* place folded char array here */);
StringBuilder outString = new StringBuilder();
for(int i = 0; i < count; i++){
outString.append(chunks[(offset + i)/chunkSize][(offset + i)%chunkSize]);
}
return outString.toString();
}

public void printStr(edu.technopolis.CustomString str){
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

метод либо статическим должен быть, либо печатать текщую строку.

for (int i = 0; i < count; i++) {
System.out.print(chunks[(offset + i)/chunkSize][(offset + i)%chunkSize]);
}
System.out.println();
}

public static void main (String[] args) {
edu.technopolis.CustomString s = new edu.technopolis.CustomString("Hello World!");
System.out.print("Начальная строка: ");
s.printStr(s);
System.out.println("Количество символов: " + s.length());
System.out.println("Шестой символ начальной строки: " + s.charAt(6));
System.out.println("Приведение начальной к String: " + s.toString());
edu.technopolis.CustomString subStr = (edu.technopolis.CustomString) s.subSequence(2,10);
System.out.print("Новая строка: ");
subStr.printStr(subStr);
System.out.println("Количество символов новой строки: "+subStr.length());
System.out.println("Шестой символ новой строки: " + subStr.charAt(6));
}
}