Лабораторная работа 1 2 лабораторная работа 2 31 лабораторная работа 3 44 лабораторная работа 4 74
Скачать 1.76 Mb.
|
ЛАБОРАТОРНАЯ РАБОТА №3Тема: Массивы. Операции над строками. Чтение и запись файлов. Обработка строк. Цель: Приобрести практические навыки разработки программных средств на языке java с использованием операций над строками, массивами, файлами. Теоретические сведения Рассматриваемые вопросы: 3.1 Массивы 3.2 Операции над строками 3.3 Управляющие операторы 3.4 Чтение строк 3.5 Чтение и запись файлов 3.6 Обработка строк 3.7 StringBuffer 3.1 Массивы Массив - это группа однотипных переменных, ссылка на которые выполняется по общему имени. java допускает создание массивов любого типа, которые могут иметь одно или больше измерений. Доступ к конкретному элементу массива осуществляется по eгo индексу. Массивы предлагают удобные средства группирования связанной информации. Одномерные массивы Одномерные массивы, по сути, представляют собой список однотипных переменных. Чтобы создать массив, вначале необходимо создать переменную массива требуемого типа. Общая форма объявления одномерного массива выглядит следующим образом: тип имя переменной []; Здесь тип задает базовый тип массива. Базовый тип определяет тип данных каждого из элементов, составляющих массив. Таким образом, базовый тип массива определяет тип данных, которые будет содержать массив. Например, следующий оператор объявляет массив month days, имеющий тип "массив элементов типа int": int monthdays[]; Хотя это объявление утверждает, что monthdays массив переменных, в действи тельности никакого массива еще не существует. Фактически значение массива monthdays установлено равным null, которое представляет массив без значений. Чтобы связать monthdays с реальным физическим массивом целочисленных значений, необходимо с помощью операции new распределить память и присвоить ее массиву monthdays. Общая форма операции new применительно к одномерным массивам выглядит следующим образом: переменная массива = new тип[размер]; тип определяет тип данных, для которых резервируется память, размер указывает количество элементов в массиве, а переменная массива - переменная массива, связанная с массивом. То есть, чтобы использовать операцию new для распределения памяти, потребуется указать тип и количество элементов, для которых нужно зарезервировать память. Элементы массива, для которых память была выделена операцией new, будут автоматически инициализированы нулевыми значениями. Следующий оператор резервирует память для 12-элементного массива целых значений и связывает их с массивом monthdays. monthdays new int[12]; После выполнения этого оператора monthdays будет ссылаться на массив, состоящий из 12 целочисленных значений. При этом все элементы массива будут инициализированы нулевыми значениями. Создание массива двухступенчатый процесс. Во-первых, необходимо объявить переменную нужногоo типа массива. Во-вторых, с помощью операции new необходимо распределить память для хранения массива и присвоить ее переменной мacсива. Таким образом, в java все массивы являются динамически распределяемыми. Приведем программу, которая создает массив числа дней в каждом месяце. // Демонстрация использования одномерного массива. class Array { public static void main (String args[]) int monthdays[]; monthdays new int[12]; monthdays[0] = 31; monthdays[1] = 28; monthdays[2] = 31; monthdays[3] = 30; monthdays[4] = 31; monthdays[5] = 30; monthdays[6] = 31; monthdays[7] = 31; monthdays[8] = 30; monthdays[9] = 31; monthdays[10] = 30; monthdays[11] = 31; System. out .println ("В апреле" + monthdays [3] + " дней."); } } Инициализатор массива - это разделяемый запятыми список выражений, заключенный в фигурные скобки. Запятые разделяют значения элементов массива. Массив будет автоматически создан достаточно большим, чтобы в нем могли уместиться все элементы, указанные в инициализаторе массива. В этом случае использование операции new не требуется. Например, чтобы сохранить количество дней каждого месяца, можно использовать следующий код, который создает и инициализирует массив целых значений: // Усовершенствованная версия предыдущей программы. class AutoArray { pиblic static void main(String args[]) { int monthdays[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; System.out.println("B апреле" + monthdays[3] + " дней.");}} Многомерные массивы В java многомерные массивы представляют собой массивы массивов. При объявлении переменной многомерного массива для указания каждого дополнительного индекса используют отдельный набор квадратных скобок. Например, следующий код объявляет переменную двумерного массива twoD. int twoD[] [] = new int[4] [5]; Многомерные массивы можно инициализировать. Для этого достаточно заключить инициализатор каждого измерения в отдельный набор фигурных скобок. Следующая программа создает матрицу, в которой каждый элемент содержит произведение индексов строки и столбца. Внутри инициализаторов массивов можно применять как значения констант, так и выражения. // Инициализация двумерного массива. class Matrix { public static void main(String args[]) double m[] [] { { 0*0, 1*0, 2*0, 3*0 }, { 0*1, 1*1, 2*1, 3*1 }, { 0*2, 1*2, 2*2, 3*2 }, { 0*3, 1*3, 2*3, 3*3 } } ; int i, j; for(i=0; i<4; i++) { for(j=0; j<4; j++) System.out.print(m[i][j] +" "); System.out.println(); }}} При выполнении эта прогpамма гeнерирует следующий вывод: 0.0 0.0 0.0 0.0 0.0 1.0 2.0 3.0 0.0 2.0 4.0 6.0 0.0 3.0 6.0 9.0 3.2 Операции над строками Тип String используют для объявления строковых переменных. Можно также объявлять массивы строк. Переменной типа String можно присваивать заключенную в кавычки строковую константу. Переменная тица String может быть присвоена другой переменной типа String. Объект типа String можно применять в качестве аргумента оператора println (). Например, рассмотрим следующий фрагмент кода: String str = "тестовая строка"; System.out.println(str); В этом примере str - объект типа String. Ему присвоена строка "тестовая строка", которая отображается оператором println(). 3.3 Управляющие операторы В языках программирования управляющие операторы используются для реализации переходов и ветвлении в потоке выполнения команд программы в соответствии с ее состоянием. Управляющие операторы jаvапрогpаммы можно разделить на следующие категории: операторы выбора, операторы цикла и операторы перехода. Операторы выбора позволяют программе выбирать различные ветви выполнения команд в соответствии с результатом выражения или состоянием переменной. Операторы цикла позволяют программе повторять выполнение одного или нескольких операторов (т.е. они образуют циклы). Операторы перехода обеспечивают возможность нелинейного выполнения программы. Операторы выбора В java поддерживаются два оператора выбора: if и switch. Эти операторы позволяют управлять порядком выполнения команд программы в соответствии с условиями, которые известны только во время выполнения. Оператор if Оператор if оператор условного выбора ветви jаvапрогpаммы. Eгo можно использовать для направления выполнения программы по двум различным ветвям. Общая форма этого оператора выглядит следующим образом: if (условие) оператор1; else оператор2; Здесь каждый оператор это одиночный оператор или составной оператор, заключенный в фигурные скобки (т.е. блок). Условие это любое выражение, возвращающее значение типа boolean. Выражение else не обязательно. Оператор if работает следующим образом: если условие истинно, программа выполняет оператор1. В противном случае она выполняет оператор2 (если он существует). Ни в одной из ситуаций программа не будет выполнять оба оператора. Пример: c1ass Ife1se { public static void main(String args[]) { int month = 4; // Апрель String season; if (month == 12 || month == 1 || month == 2) season = "зиме"; e1se if (month == 3 || month == 4 || month == 5) season = "весне"; e1se if (month == 6 || month == 7 || month == 8) season = "лету"; e1se if (month == 9 || month == 10 || month == 11) season = "осени"; e1se season = "вымьшленным месяцам"; Sуstеm.оut.рrintln("Апрель относится к" + season + "."); }} Программа создает следующий вывод: Апрель относится к весне Оператор switch Оператор switch - оператор ветвления в java. Он предлагает простой способ направления потока выполнения команд по различным ветвям кода в зависимости от значения управляющего выражения. Часто он оказывается эффективнее применения длинных последовательностей операторов ifelseif. Общая форма оператора switch имеет следующий вид: switch (выражение) { case значениеl: // последовательность операторов break; case значение2: // последовательность операторов break; case значениеN: // последовательность операторов break; default: // последовательность операторов, выполняемая по умолчанию Выражение должно иметь тип type, short, int или char. Тип каждого значения, указанногo в операторах case должен быть совместим с типом выражения. Каждое значение case должно быть уникальной символьной константой (т.е. постоянным значением, а не переменной). Дублирование значений case не допускается. Оператор switch работает следующим образом. Значение выражения сравнивается с каждым из значений констант в операторах case. При обнаружении совпадения программа выполняет последовательность кода, следующую за данным оператором case. Если значения ни одной из констант не совпадает со значением выражения, программа выполняет оператор default. Однако этот оператор не обязателен. При отсутствии совпадений со значениями case и отсутствии оператора default программа не выполняет никаких дальнейших действий. Оператор break внутри последовательности switch служит для прерывания последовательности операторов. Как только программа доходит до оператора break, она продолжает выполнение с первой строки кода, следующей за всем оператором switch. Этот оператор оказывает действие "выхода" из оператора switch. Ниже представлен простой пример использования оператора switch. class SampleSwitch { public static void main(String args[]) for(int i=0; i<6; i++) switch (i) { case 0: System.out.println("i равно нулю."); break; case 1: System.out.print1n("i равно единице."); break; case 2: System.out.print1n ("i равно двум."); break; case З: System.out.println("i равно трем."); break; default: System.out.print1n("i больше З."); Эта программа генерирует следующий вывод: i равно нулю. i равно единице. i равно двум. i равно трем. i больше З. i больше З. Операторы цикла Операторами цикла java являются for, whi1e и dо-whi1e. Эти операторы образуют конструкции, обычно называемые циклами. Как наверняка известно читателям, циклы многократно выполняют один и тот же набор инструкций до тех пор, пока не будет удовлетворено условие завершения цикла. Цикл while Оператор while наиболее часто используемый оператор циклa в java. Он повторяет оператор или блок операторов до тех пор, пока значение eгo управляющего выражения истинно. Он имеет следующую общую форму: whilе(условие) { / / тело цикла Условием может быть любое булевское выражение. Тело цикла будет выполняться до тех пор, пока условное выражение истинно. Когда условие становится ложным, управление передается строке кода, непосредственно следующей за циклом. Фигурные скобки могут быть опущены, только если в цикле повторяется только один оператор. Цикл do-while Если в начальный момент условное выражение, управляющее циклом whi1e, ложно, тело цикла вообще не будет выполняться. Однако иногда желательно выполнить тело цикла хотя бы один раз, даже если в начальный момент условное вырaжение ложно. Иначе говоря, существуют ситуации, когда проверку условия прерывания цикла желательно выполнять в конце цикла, а не в eгo начале. К счастью, java поддерживает именно такой цикл: dowhile. Этот цикл всегда выполняет тело цикла хотя бы один раз, поскольку eгo условное выражение проверяется в конце цикла. Общая форма цикла dowhile следующая: do { / / тело цикла } whi1e (условие); При каждом повторении цикла dowhile программа вначале выполняет тело цикла, а затем вычисляет условное выражение. Если это выражение истинно, цикл повторяется. В противном случае выполнение цикла прерывается, как и во всех циклах jаvа, выражение должно быть булевским. Цикл for Общая форма традиционного оператора for выглядит следующим образом: for (инициализация; условие; повторение) { // тело Если в цикле будет повторяться только один оператор, фигурные скобки можно опустить. Цикл for действует следующим образом. При первом запуске цикла программа выполняет инициализационную часть цикла. В общем случае это выражение; устанавливающее значение управляющей переменной цикла, которая действует в качестве счетчика, управляющего циклом. Важно понимать, что выражение инициализации выполняется только один раз. Затем программа вычисляет условие, которое должно быть булевским выражением. Как правило, выражение сравнивает значение управляющей переменной с целевым значением. Если это значение истинно, программа выполняет тело цикла. Если оно ложно, выполнение цикла прерывается. Затем программа выполняет часть повторение цикла. Обычно это выражение, которое увеличивает или уменьшает значение управляющей переменной. Затем программа повторяет цикл, при каждом прохождении вначале вычисляя условное выражение, затем выполняя тело цикла и выполняя выражение повторения. Процесс повторяется до тех пор, пока значение выражения повторения не станет ложным. Ниже приведена версия программы подсчета "тактов", в которой использован цикл for. class ForTick { public static void main(String args[]) int n; for(n=10; n>0; n--) System.out.println("Taкт " + n); }} Операторы перехода В java определены три оператора перехода: break, continue и return. Они передают управление другой части программы. В java оператор break находит три применения. Во-первых, он завершает последовательность операторов в операторе switch. Во-вторых, eгo можно использовать для выхода из цикла. И, в-третьих, eгo можно использовать в качестве "цивилизованной" формы оператора безусловного перехода ("goto"). Иногда требуется, чтобы повторение цикла осуществлялось с более раннего оператора eгo тела. То есть на данной конкретной итерации может требоваться продолжить выполнение цикла без обработки остального кода в eгo теле. По сути, это означает переход в теле цикла к eгo окончанию. Для выполнения этого действия служит оператор continue. В циклах whi1e и dowhi1e оператор continue вызывает передачу управления непосредственно управляющему условному выражению цикла. В цикли for управление передается вначале итерационной части цикла for, а потом условному выражению. Во всех этих трех циклах любой промежуточный код пропускается. Последний из управляющих операторов return. Eгo используют для выполнения явного возврата из метода. То есть он снова передает управление объекту, который вызвал данный метод. Как таковой этот оператор относится к операторам перехода. Оператор return можно использовать в любом месте метода для возврата управления тому объекту, который вызвал данный метод. Таким образом, оператор return немедленно прекращает выполнение метода, в котором он находится. Следующий пример иллюстрирует это. В данном случае оператор return при водит к возврату управления системе времени выполнения java, поскольку именно она вызывает метод main() . // Демонстрация использования оператора return. class Return { public static void main(String args[]) { boolean t = true; Sуstеm.оut.рrintln("До выполнения возврата."); if(t) return; // возврат к вызывающему объекту Sуstеm.оut.рrintln("Этот оператор выполняться не будет."); Вывод этой программы имеет вид: До выполнения возврата. 3.4 Чтение строк Чтобы прочесть строку с клавиатуры, используйте версию метода readLine() , который является членом класса BufferedReader. Егo общая форма такова: String readLine() throwsIOException он возвращает объект String. Следующая программа демонстрирует BufferedReader и метод readLine(). Программа читает и отображает строки текста до тех пор, пока не будет введено слово "стоп": // Чтение строк с консоли с применением BufferedReader. import java.io.*; class BRReadLines { public Static void main(String args[]) throwsIOException { // Создать BufferedReader с использованием System.in BufferedReader br=new BufferedReader(newInputStreamReader(System.in)); String str; Systеm.оut.рrintln("Вводите строки текста."); Sуstеm.оut.рrintln("Введите 'стоп' для завершения."); do { str br.readLine(); System.out.println(str); whilе(!str.еquаls("стоп")); }} 3.5 Чтение и запись файлов Два из наиболее часто используемых потоковых класса это FileInputStream и FileOutputStream, которые создают байтовые потоки, связанные с файлами. Чтобы открыть файл, нужно просто создать объект одного из этих классов, указав имя файла в качестве аргумента конструктора. Хотя оба класса имеют и дополнительные переопределенные конструкторы, мы будем использовать только следующие из них: FileInputStream(String fileName) throws FileNotFoundException FileOutputStream(String fileName) throws FileNotFoundException Здесь filename имя файла, который вы хотите открыть. Когда вы создаете входной поток, то если файл не существовал, возбуждается исключение Fi1eNotFoundException. Для выходных потоков, если файл не может быть создан, также возбуждается исключение FileNotFoundException. Когда выходной файл открыт, любой ранее существовавший файл с тем же именем уничтожается. Когда вы завершаете работу с файлом, вы должны закрыть eгo вызовом метода close(). Этот метод определен и в FileInputStream и в FileOutputStream, как пока зано ниже: void close() throws IOException Чтобы читать файл, вы можете применять версию метода read(), который определен в Fi1eInputStream. Это выглядит так: int read() throws IOException Всякий раз, когда вызывается этот метод, он читает единственный байт из файла и возвращает его как целое число. read() возвращает 1, когда достигнут конец файла. Метод может возбуждать исключение IOException. В следующей программе read () используется для ввода и отображения содержимого текстового файла, имя которого специфицировано в аргументе командной строки. Обратите внимание на блок try/catch, обрабатывающий две ошибки, которые могут возникнуть при работе программы когда указанный файл не найден, либо когда пользователь забыл указать имя файла. Вы можете применять тот же подход всякий раз при использовании аргументов командной строки. import java.io.*; class ShowFile { public static void main(String args[]) throws IOException { int i; FileInputStream fin; try { fin = new FileInputStream(args[0]); catch(FileNotFoundException е) { Sуstеm.оut.рrintln("Файл не найден"); return; catch(ArrayIndexOutOfBoundsException е) { System. out .println ("Использование: ShowFile Файл") ; return; } // читать символы до получения символа EOF (конец файла) do { i = fin. read () ; if(i != -l) System.out.print((char) i); } while(i !=-l); fin.close(); }} Для записи в файл нужно использовать метод write(), определенный в FileOutputStream. Eгo простейшая форма выглядит так: void write(int byteval) throws IOException Этот метод пишет в файл байт, переданный в byteval. Хотя byteval объявлен как целочисленный, в файл записываются только eгo младшие восемь бит. Если при записи произойдет ошибка, возбуждается исключение IOException. В следующем примере write() используется для копирования текстовorо файла: /* Копирование текстового файла. Для использования этой программы укажите имена исходноrо и целевого файлов. Например, чтобы скопировать файл FIRST.TXT в файл SECOND.TXT, используйте следующую командную строку: java CopyFile FIRST.TXT SECOND.TXT */ import java.id.*; class CopyFile { public static void main(String args[]) throws IOException { int i; FileInputStream fin; FileOutputStream fout; try { // открыть входной файл try { fin = new FileInputStream(args[0]); catch(FileNotFoundException е) { System.out.println("Входной файл не найден") ; return; } // открыть выходной файл try { fout = new FileOutputStream(args[l]); catch(FileNotFoundException е) { Sуstеm.оut.рrintln("Ошибка открытия выходноrо файла"); return; } catch(ArrayIndexOutOfBoundsException е) { Sуstеm.оut.рrintln("Использование: CopyFile Исходный Целевой"); return; } // Копировать файл try { do { i = fin.read(); if(i != -1) fout.write(i); } while(i != -1); catch(IOException е) { Sуstеm.оut.рrintln("Ошибка файла"); } fin.close(); fout.close(); }} В java ошибки передаются программе в виде исключений, а не через значение, возвращаемое read(). То есть, когда read() возвращает -1, это значит только одно: достигнут конец файла. 3.6 Обработка строк Как и в других языках программирования, в Java строка это последовательность символов. Но в отличие от многих других языков, в которых строки реализованы как массивы символов, в java строки реализованы в виде объектов типа String. Класс String поддерживает несколько конструкторов. Чтобы создать пустой объект типа String, вызывается конструктор по умолчанию. Например, следующий оператор создает экземпляр String, не содержащий в себе символов: String s = new String(); Часто будет требоваться создать строку, которая содержит начальное значение. Класс String предлагает множество конструкторов для этого. Чтобы создать String, инициализированный массивом символов, используйте следующий конструктор: String(char chars[]) Вот при меры: char chars[] { 'а', 'b', 'с' ); String s = new String(chars); Этот конструктор инициализирует s строкой "аbс". Вы можете задать под диапазон символьного массива в качестве инициализирующей строки с помощью следующего конструктора: String(char chars[ ], int startIndex, int numChars) Здесь startIndex указывает начало диапазона, а numChars количество символов, которые нужно использовать. Вот пример: char chars[] { 'а', 'b', 'с', 'd', 'е', 'f' }; String s = new String(char8, 2, З); Это инициализирует строку s символами "cde". Вы можете сконструировать объект String, который содержит ту же последовательность символов, что и другой объект String, используя конструктор: String(String strObj) Здесь strObj объект String. Рассмотрим следующий пример: // Конструировать один объект String из другого. class MakeString { public Static void main(String args[]) char с [] {' J', 'а', 'v', 'а'}; String s1 = new String(c); String s2 = new String(sl); System.out.println(s1); System.out.println(s2); Вывод этой программы будет выглядеть, как показано ниже: Java Java Как видите, sl и s2 содержат одинаковые строки. Длина строки это количество символов, из которых она состоит. Чтобы получить это значение, вызывайте метод length(): int length() Следующий фрагмент печатает 3, поскольку именно три символа содержит строка s: char chars[] { ‘ а ‘, ‘ b’, ‘с’ }; String s = new String(chars); System.out.print1n(s.1ength()); Для каждого строковoго литерала в jаvапрограмме автоматически конструируется объект String. Таким образом, можно использовать строковый литерал для инициализации объекта String. Например, следующий фрагмент кода создает две эквивалентные строки: char chars[] { 'а', 'b’, 'с ‘ }; String s1 = new String(chars); String s2 = "аbс"; / / используется строковый литерал В общем случае, jаvа не позволяет применять операции к объектам String. Одно исключение из правил применение операции +, которая соединяет две строки, порождая в результате объект String. Это позволяет соединять вместе серии операций +. Например, в следующем фрагменте кода осуществляется конкатенация трех строк: String аgе = "9"; String s = "Ему " + age + " лет."; System.out.println(s); В результате отображается строка "Ему 9 лет". Чтобы выделить единственный символ из String, вы можете сослаться непосредственно к индивидуальному символу с помощью метода charAt(). Он имеет следующую общую форму: char charAt(int where) Здесь where индекс символа, который нужно получить. Значение where должно быть не отрицательным и указывать положение в строке. charAt() возвращает символ, находящийся в указанном положении. Например, char ch; ch = "аbс". charAt(1) ; присваивает значение 'b' переменной ch. Если вам нужно извлечь более одного символа сразу, вы можете применить метод getChars(). Он имеет следующую общую форму: void getChars(int sourceStart, int sourceEnd, char target[ ], int targetStart) Здесь sourceStart указывает индекс начала подстроки, а sourceEпd индекс символа, следующего за концом требуемой подстроки. Таким образом, извлекается подстрока, содержащая символы от sourceStart до sourceEпd -1. Массив, который принимает выделенные символы, указан в параметре target. Индекс в массиве target, начиная с которoго будет записываться подстрока, передается в targetStart. Следует позаботиться о том, чтобы массив target был достаточного размера, чтобы в нем поместились все символы указанной подстроки. В следующей программе демонстрируется использование getChars() . class getCharsDemo { public static void main(String args[]) { String s = "Это демонстрация метода getChars."; int start = 4; int end = 8; char bиf [] = new char [end - start]; s.getChars(start, end, buf, 0); System.out.println(bиf); }} Вывод программы показан ниже: демо Сравнение equals() и операции == Метод equa1s() сравнивает символы внутри объекта String. Операция == сравнивает две ссылки на объекты и определяет, ссылаются ли они на один и тот же экземпляр. В следующей программе показано, как два разных объекта String мoгyт содержать одинаковые символы, но ссылки на эти объекты при сравнении будут не эквивалентными. // equals() против == class Equa1sNotEqualTo { public static void main(String args[]) { String s1 = "Привет"; String s2 = new String(s1); System.out.println(s1 +" equa1s" + s2 +"- >" + s1.equa1s(s2)); System.out.println(s1 + " " + s2 + "- > " + (s1 == s2)); }} Переменная sl ссылается на экземпляр String, созданный присвоением литерала "Привет". Объект, на который ссылается s2, создается с использованием sl в качестве инициализатора. Таким образом, содержимое обоих объектов String идентично, но это отличные друг от друга объекты. Это означает, что sl и s2 не ссылаются на один и тот же объект, а потому не равны (при сравнении операцией), как доказывает вывод предыдущей программы: Привет equa1s Привет -> true Привет == Привет -> fa1se Поиск строк Класс String предлагает два метода, которые позволяют выполнять поиск в строке определенного символа или подстроки. - indexОf() - ищет первое вхождение символа или подстроки. - 1astlndexOf() - ищет последнее вхождение символа или подстроки. Эти два метода перегружены несколькими разными способами. Во всех случаях эти методы возвращают позицию в строке (индекс), где символ или подстрока была найдена, либо -1 в случае неудачи. Чтобы найти первое вхождение символа: int indexOf(char ch) Чтобы найти последнее вхождение символа: int lastlndexOf(char ch) Здесь ch - символ, который нужно искать. Чтобы найти первое или последнее вхождение подстроки: int indexOf(String str) int lastlndexOf(String str) Здесь str задает искомую подстроку. Можно указать начальную позицию для поиска, воспользовавшись следующими фoрмами: int indexOf(int ch, int startIndex) int lastlndexOf(int ch, int startIndex) int indexOf(String str, int startIndex) int lastlndexOf(String str, int startIndex) Здесь startIndex задает начальную позицию поиска. Для indexOf() поиск начинается от startIndex до конца строки, а для 1astlndexOf () - от startIndex до нуля. Модификация строк Можно извлечь подстроку, используя substring(). Этот метод имеет две формы. Первая: String substring(int startIndex) Здесь startlndex указывает индекс, с которого начнется подстрока. Эта форма возвращает копию подстроки, которая начинается с позиции startlndex и продолжается до завершения вызывающей строки. Вторая форма substring() позволяет указать как начальный, так и конечный индексы подстроки: String substring(int startIndex, int eпdIndex) Здесь startlndex указывает индекс, с котopoгo начнется подстрока, а eпdlndex точку конца под строки. Возвращаемая строка содержит все символы, начиная от первой позиции и до последней, исключая ее. Можно соединить две подстроки, используя concat(), как показано ниже: String concat(String str) Этот метод создает новый объект, который содержит вызываемую строку с содержимым str, присоединенным к ее концу. concat () выполняет ту же функцию, что и операция +. Метод replace() имеет две формы. Первая заменяет в исходной строке все вхождения одного символа другим. Вот эта форма: String replace(char original, char replaceтent) Здесь original задает символ, который должен быть заменен replacement. Возвращается результирующая строка. Например: String s = "Hello".rep1ace('l', 'w'); помещает в s строку "Hewwo". Вторая форма replace() заменяет одну последовательность символов на другую. Она выглядит так: String replace(CharSequence original, CharSequence replacement) Метод trim() возвращает копию вызывающей строки, из которой удалены все вeдyщие и завершающие пробелы. Он имеет следующую общую форму: String trim() Вот пример: String s = " Hello World ".trim(); В результате в s будет помещена строка "HelloWorld". Метод trim() достаточно удобен при обработке других команд. Например, следующая программа приглашает пользователя ввести название штата, а затем отображает нaзвание города столицы штата. Она использует trim() для удаления всех ведущих и хвостовых пробелов, которые могут быть непреднамеренно введены пользователем. / / Использование trim() для обработки команд. import java.io.*; c1ass UseTrim { public static void main(String args[]) throws IOException // Создается BufferedReader с использованием System.in BufferedReader br=newBufferedReader(new InputStreamReader(System.in)); String str; Sуstеm.оut.рrintln("Введите 'стоп' для завершения."); Sуstеm.оut.рrintln("Введите штат "); do ( str = br.readLine(); str = str.trim(); // удалить пробелы if (str.equals ("Иллинойс") ) Sуstеm.оut.рrintln("Столица - Спрингфилд."); e1se if (str.equals ("Миссури")) Sуstеm.оut.рrintln("Столица - Джефферсон-сити."); e1se if (str.equals ("Калифорния") ) Sуstеm.оut.рrintln("Столица - Сакраменто."); e1se if (str.equa1s ("Вашингтон") ) Sуstеm.оut.рrintln("Столица - Олимпия."); / / ... whi1е(!str.еquа1s("стоп")); }} 3.7 StringBuffer StringBuffer - это класс, подобный String, который представляет большую часть функциональности строк. String представляет неизменяемые последовательности символов постоянной длины. В отличие от этого, StringBuffer представляет расширяемые и доступные для изменений последовательности символов. StringBuffer позволяет вставлять символы и под строки в середину либо добавлять их в конец. StringBuffer автоматически растет, чтобы обеспечить место для подобных расширений, и часто, чтобы обеспечить возможность возрастания, имеет больше предварительно выдeленных символов, чем фактически нужно в данный момент. java интенсивно использует оба класса. Конструкторы StringBuffer в StringBuffer определены следующие четыре конструктора: StringBuffer() StringBuffer(int size) StringBuffer(String str) StringBuffer(CharSequence chars) Конструктор по умолчанию (не имеющий параметров) резервирует место под 16 символов без перераспределения памяти. Вторая версия принимает целый аргумент, который явно устанавливает размер буфера. Третья версия принимает аргумент типа String, который устанавливает начальное содержимое объекта StringBuffer и резервирует 16 символов без повторноrо распределения. StringBuffer выделяет место под 16 дополнительных символов, коrда не указывается конкретный размер буфера, поскольку распределение памяти дорогостоящая операция в смысле временных затрат. Кроме тoгo, повторное распределение может фрагментировать память. Выделяя место под несколько дополнительных символов, StringBuffer снижает количество необходимых повторных распределений. Четвертый конструктор создает объект, содержащий последовательность символов из параметра chars. Текущую длину StringBuffer можно получить методом length(), а текущий объем выделенной памяти методом capacity(). Они имеют следующую общую форму: int length() int capacity() Значение отдельного символа может быть извлечено из StringBuffer методом charAt(). Вы можете установить значение символа внутри StringBuffer с помощью setCharAt(). Общая форма этих методов показана ниже: char charAt(int where) void setCharAt(int where, char ch) Для метода charAt() параметр where указывает индекс символа, который нужно извлечь. Для setCharAt() параметр where указывает индекс символа, который нужно ycтановить, а ch - eгo значение. Для обоих методов where должен быть неотрицательным и не должен находиться за пределами конца буфера. Чтобы скопировать подстроку из StringBuffer в массив, используйте метод getChars(). Он имеет следующую форму: void getChars(int sourceStart, int sourceEnd, char target[ ], int targetStart) Здесь sоurсеstаrt указывает индекс начала подстроки, а sоurсеЕnd индекс символа, следующего за концом требуемой подстроки. Это означает, что подстрока содержит символы от sоurсеStаrt до sоurсеЕпd - 1. Массив, который принимает символы, передается через target. Индекс внутри target, куда копируется подстрока, передается в параметре targetStart. Необходимо позаботиться о том, чтобы массив target был достаточного размера, чтобы вместить количество символов указанной подстроки. Метод append () соединяет строковое представление любого другого типа данных с концом вызывающего объекта StringBuffer. Он имеет несколько перегруженных вepсий. Вот несколько из eгo форм: StringBuffer append(String str) StringBuffer append(int num) StringBuffer append (Object obj) String.va1ueOf () вызывается для каждого параметра, чтобы получить eгo строковое представление. Результат добавляется к текущему объекту StringBuffer. Сам буфер возвращается каждой из версий append(). Метод insert() вставляет одну строку в другую. Он перегружен, чтобы принимать в параметре значения всех простых типов плюс объекты String, Object и CharSequence. Подобно append(), он обращается к String.valueOf() для получения строкового представления значения, с которым вызван. Эта строка затем вставляется в вызывающий объект StringBuffer. Существуют несколько форм этоrо метода: StringBиffer insert(int index, String str) StringBиffer insert(int index, char ch) StringBиffer insert(int index, Object obj) Здесь index указывает индекс позиции вызывающего объекта StringBuffer, в которой будет вставлена строка. Изменить порядок символов в объекте StringBuffer на обратный можно с помощью reverse(): StringBuffer reverse() Можно удалять символы из StringBuffer с помощью методов delete() и deleteCharAt(). Эти методы показаны ниже: StringBuffer delete(int startIndex, int endIndex) StringBuffer deleteCharAt(int loc) Метод delete() удаляет последовательность символов из вызывающего объекта. Здесь startlndex задает индекс первого символа, который надо удалить, а endlndex - индекс символа, следующего за последним из удаляемых. Таким образом, удаляемая подстрока начинается с startlndex и заканчивается endlndex - l. Возвращается результирующий объект StringBuffer. Метод de1eteCharAt() удаляет символ, находящийся в позиции loc. Возвращает результирующий объект StringBuffer. Можно заменить один набор символов другим внутри StringBuffer вызовом replace() . Сигнатура этого метода показана ниже: StringBuffer replace(int startIndex, int endIndex, String str) Подстрока, которую нужно заменить, задается индексами startlndex и endlndex. Таким образом, заменяется подстрока от символа startlndex до endlndex -l. Строка замены передается в str. Возвращается результирующий объект StringBuffer. В следующей программе демонстрируется использование rep1ace(). // Демонстрация применения replace() class replaceDemo { public static void main(String args[]) { StringBuffer sb = new. StringBuffer("This is а test."); sb.replace(5, 7, "was"); Sуstеm.оut.рrintln("после замены: "+ sb); }} Ниже показан вывод программы: После замены: This was а test. Индивидуальные задания: Вычислить величину (x1y1 + x3y3 + ... + x29y29)/(x2y2 + x4y4 + ... + x30y30) если числа для ввода заданы в следующем порядке и находятся в файле а1: x1, x2, ... , x30, y1, y2, ... , y30. Вычислить величину (x1y1 + x3y3 + ... + x29y29)/(x2y2 + x4y4 + ... + x30y30) если числа для ввода заданы в следующем порядке и находятся в файле а1: x1, y1, x2, y2, ... , x30, y30. Дан текст из 80 литер в файле f.txt. Напечатать сначала все цифры, входящие в него, а затем все остальные литеры, сохраняя при этом взаимное расположение литер в каждой из этих двух групп. Все отрицательные элементы массива x перенести в его начало, а все остальные - в конец, сохраняя исходное взаимное расположение как среди отрицательных, так и среди остальных элементов и записать в файл. Записать в текстовый файл литеры s[i] массива s в виде таблицы: s[1] s[2] s[3] ... s[n-1] s[n] s[2] s[3] s[4] ... s[n] s[1] ... s[n] s[1] s[2] ... s[n-2] s[n-1] Файл содержит таблицу координат 100 точек. Найти длину наиболее длинного отрезка, которые можно создать из этих точек. Задан файл целых чисел. Если его элементы упорядочены, вывести вторую половину. Задан файл целых чисел. Указать диапазон, в котором находятся его элементы. В файле задана строка символов. Упорядочить ее, таким образом, чтоб слова начинались с букв за алфавитом. В файле записан двумерный массив. Переместить его элементы по возрастанию произведений элементов каждого столбца. В файле задана квадратная матрица. Найти сумму элементов из нижнего и верхнего треугольников. В файле задана квадратная матрица. Найти минимальный элемент среди тех элементов, что расположены под главной диагональю. В файле задан двумерный массив. Среди минимальных элементов каждого рядка найти максимальный и вывести этот рядок. В файле задан двумерный массив. Найти сумму элементов того рядка, в котором расположен максимальный элемент. В файле задана квадратная матрица. Указать номера тех столбцов, элементы которых упорядочены по убыванию. Контрольные вопросы: Что такое массив, какие бывают массивы? Какие Вы знаете условные операторы? Какие существуют операторы цикла в java? Каким образом реализованы строки в java? Операции над строками. Что такое StringBuffer? Рекомендуемая литература Основная литература Шилдт Г., Ноутон П. Java 2. Наиболее полное руководство, 2001. Павловская Т.А., Щупак Ю.А. C++. Объектно-ориентированное программирование. Практикум. СПб. Питер, 2006. Г.Шилдт. Полный справочник по Java SE6 2007. Б.Эккель. Философия Java (4е издание), 2009. К. Арнольд, Д. Гослинг. Язык программирования Java. Питер Пресс, Санкт-Петербург, 1997. Дополнительная литература М. Эферган Java: справочник .- QUE Corporation, 1997, Издательство "Питер Ком", 1998 Д. Вебер Технология Java в подлиннике .- QUE Corporation, 1996, "BHV-Санкт-Петербург",1997. Н. Бартлетт, А. Лесли, С. Симкин Программирование на Java. Путеводитель .- The Coriolis Group,Inc.,1996, Издательство НИПФ "ДиаСофт Лтд.",1996 К. Джамса Библиотека программиста Java .- Jamsa Press, 1996, ООО "Попурри", 1996 К. Арнольд, Д. Гослинг Язык программирования Java .- Addison-Wesley Longman,U.S.A.,1996, Издательство "Питер-Пресс", 1997. |