Простые приложения на Java
Простые приложения на Java
Java представляет собой объектно-ориентированный язык программирования, который широко используется для создания настольных приложений, серверных систем и мобильных решений. Язык отличается строгой типизацией, автоматическим управлением памятью (Garbage Collection) и кроссплатформенностью благодаря виртуальной машине Java (JVM).
В данной главе рассматриваются практические примеры простых консольных приложений. Каждый пример демонстрирует ключевые концепции языка: работу со строками, массивами, коллекциями, файловым вводом-выводом, сетевым взаимодействием и многопоточностью.
Генератор случайных паролей
Это приложение демонстрирует работу с классом String, массивами символов, интерфейсом Random и циклами. Код создает пароль заданной длины, выбирая символы из набора букв, цифр и специальных знаков.
Разбор кода
- Массивы: Хранение допустимых символов.
- Random: Генерация индексов для выбора случайного символа.
- StringBuilder: Эффективное построение итоговой строки без создания множества временных объектов.
import java.util.Random;
public class PasswordGenerator {
public static void main(String[] args) {
int length = 12;
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*";
StringBuilder password = new StringBuilder();
Random random = new Random();
for (int i = 0; i < length; i++) {
int index = random.nextInt(chars.length());
char ch = chars.charAt(index);
password.append(ch);
}
System.out.println("Сгенерированный пароль: " + password.toString());
}
}
Ключевые моменты:
- Использование
StringBuilderвместо конкатенации строк в цикле повышает производительность. - Метод
nextInt(int bound)возвращает случайное целое число от 0 (включительно) до указанного значения (исключительно).
Сортировщик текстового файла
Приложение читает текст из файла, разбивает его на слова, сортирует их по алфавиту и записывает результат в новый файл. Это пример работы с потоками ввода-вывода (InputStreamReader, BufferedReader) и коллекциями (ArrayList, Collections).
Разбор кода
- NIO и IO: Классы
Files,Paths,FileReaderдля чтения данных. - Коллекции: Список
ArrayListдля хранения слов. - Сортировка: Алгоритм
Collections.sort().
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.stream.Collectors;
public class TextSorter {
public static void main(String[] args) {
Path inputPath = Paths.get("input.txt");
Path outputPath = Paths.get("output_sorted.txt");
try {
// Чтение всего содержимого файла
String content = Files.readString(inputPath);
// Разбиение на слова (по пробелам и знакам препинания)
List<String> words = Arrays.stream(content.split("\\s+"))
.filter(word -> !word.isEmpty())
.collect(Collectors.toList());
// Сортировка списка
Collections.sort(words);
// Запись результата
String sortedContent = String.join("\n", words);
Files.writeString(outputPath, sortedContent);
System.out.println("Файл успешно отсортирован. Количество слов: " + words.size());
} catch (IOException e) {
System.err.println("Ошибка при работе с файлом: " + e.getMessage());
}
}
}
Ключевые моменты:
- Метод
Files.readString(доступен в Java 11+) упрощает чтение файлов. - Регулярное выражение
\\s+позволяет корректно разделить текст по любому количеству пробельных символов. - Обработка исключений через блок
try-catchгарантирует безопасность программы при отсутствии файла.
Консольный калькулятор
Простой интерактивный калькулятор, выполняющий арифметические операции (+, -, *, /). Пример демонстрирует работу с пользовательским вводом (Scanner), условными операторами и обработкой ошибок деления на ноль.
Разбор кода
- Scanner: Получение данных от пользователя.
- Условная логика: Оператор
switchдля выбора операции. - Типы данных: Переход от
Stringкdoubleдля вычислений.
import java.util.Scanner;
public class ConsoleCalculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
boolean running = true;
while (running) {
System.out.print("Введите первое число (или 'q' для выхода): ");
String input1 = scanner.nextLine();
if (input1.equalsIgnoreCase("q")) {
break;
}
double num1 = Double.parseDouble(input1);
System.out.print("Выберите операцию (+, -, *, /): ");
String operation = scanner.nextLine();
System.out.print("Введите второе число: ");
double num2 = Double.parseDouble(scanner.nextLine());
double result = 0;
boolean validOperation = true;
switch (operation) {
case "+":
result = num1 + num2;
break;
case "-":
result = num1 - num2;
break;
case "*":
result = num1 * num2;
break;
case "/":
if (num2 == 0) {
System.out.println("Ошибка: Деление на ноль!");
validOperation = false;
} else {
result = num1 / num2;
}
break;
default:
System.out.println("Неверная операция.");
validOperation = false;
}
if (validOperation) {
System.out.printf("Результат: %.2f%n", result);
}
}
System.out.println("Программа завершена.");
scanner.close();
}
}
Характерная черта Java: Строгая проверка типов. Попытка сложить строку и число вызовет ошибку компиляции, что предотвращает многие типы runtime-ошибок.
Трекер задач в JSON
Приложение сохраняет список задач в файл формата JSON и загружает его обратно. Для работы с JSON используется библиотека org.json или встроенные возможности, но в примере ниже показана реализация на основе простого сериализатора вручную или с использованием стандартной библиотеки Jackson (предполагается наличие зависимости). Для автономности примера будет использован простой формат, имитирующий JSON, либо структура класса.
Примечание: В реальных проектах используют Jackson или Gson. Здесь представлен пример с ручным парсингом для демонстрации логики.
Разбор кода
- POJO (Plain Old Java Object): Класс
Taskдля представления задачи. - Файловая система: Создание директорий и запись/чтение файлов.
- JSON-структура: Представление данных в виде строковой формы.
import java.io.*;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.List;
class Task {
private int id;
private String description;
private boolean completed;
public Task(int id, String description) {
this.id = id;
this.description = description;
this.completed = false;
}
@Override
public String toString() {
return "{\"id\":" + id + ",\"description\":\"" + description + "\",\"completed\":" + completed + "}";
}
// Упрощенный метод для создания объекта из строки (для примера)
public static Task fromJson(String jsonStr) {
// В реальном проекте используйте JsonParser
return null;
}
}
public class TaskTracker {
private static final String FILE_PATH = "Задачи.json";
private List<Task> Задачи = new ArrayList<>();
public void loadTasks() {
Path path = Paths.get(FILE_PATH);
if (Files.exists(path)) {
try {
String content = Files.readString(path);
// Здесь должна быть логика парсинга JSON строки в объекты Task
System.out.println("Задачи загружены (демо режим).");
} catch (IOException e) {
System.err.println("Ошибка чтения: " + e.getMessage());
}
}
}
public void saveTasks() {
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < Задачи.size(); i++) {
sb.append(Задачи.get(i).toString());
if (i < Задачи.size() - 1) sb.append(",");
}
sb.append("]");
try {
Files.writeString(Paths.get(FILE_PATH), sb.toString());
System.out.println("Задачи сохранены.");
} catch (IOException e) {
System.err.println("Ошибка записи: " + e.getMessage());
}
}
public void addTask(String desc) {
int id = Задачи.size() > 0 ? Задачи.get(Задачи.size() - 1).getId() + 1 : 1;
Задачи.add(new Task(id, desc));
}
public static void main(String[] args) {
TaskTracker tracker = new TaskTracker();
tracker.loadTasks();
tracker.addTask("Купить продукты");
tracker.addTask("Изучить Java");
tracker.saveTasks();
}
}
Рекомендация: Для продакшн-кода обязательно используйте библиотеку Jackson Databind или Gson. Они берут на себя всю сложность сериализации и десериализации.
Простой HTTP-сервер и клиент
Java предоставляет возможности для создания сетевых приложений через пакет java.net. Ниже приведен пример минимального сервера, слушающего порт, и клиента, отправляющего запрос.
Разбор кода
- ServerSocket: Объект для прослушивания входящих соединений.
- Socket: Объект для установления соединения.
- Потоки ввода/вывода:
InputStream,OutputStreamдля передачи данных.
// --- Сервер ---
import java.io.*;
import java.net.*;
public class SimpleHttpServer {
public static void main(String[] args) throws IOException {
int port = 8080;
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Сервер запущен на порту " + port);
while (true) {
Socket clientSocket = serverSocket.accept();
handleClient(clientSocket);
}
}
private static void handleClient(Socket socket) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
String requestLine = in.readLine();
System.out.println("Запрос: " + requestLine);
String response = "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"\r\n" +
"Hello from Java Server!";
out.println(response);
socket.close();
}
}
// --- Клиент ---
import java.io.*;
import java.net.*;
public class HttpClient {
public static void main(String[] args) throws IOException {
URL url = new URL("http://localhost:8080");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int status = connection.getResponseCode();
System.out.println("Статус ответа: " + status);
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println("Ответ сервера: " + response.toString());
}
}
Характерная черта Java: Встроенная поддержка TCP/IP на низком уровне. Не требуется подключение внешних драйверов для базовой сетевой коммуникации.
Отправитель HTTP-запросов (REST API)
Этот пример расширяет функциональность клиента, позволяя отправлять POST-запросы с данными в формате JSON. Используется HttpURLConnection для настройки заголовков и отправки тела запроса.
import java.io.*;
import java.net.*;
public class RestApiClient {
public static void main(String[] args) throws IOException {
String apiUrl = "https://jsonplaceholder.typicode.com/posts";
String jsonInput = "{ \"title\": \"foo\", \"body\": \"bar\", \"userId\": 1 }";
URL url = new URL(apiUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
try (OutputStream os = conn.getOutputStream()) {
byte[] input = jsonInput.getBytes("utf-8");
os.write(input, 0, input.length);
}
int responseCode = conn.getResponseCode();
System.out.println("Отправлен запрос. Код ответа: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_CREATED) {
System.out.println("Ресурс успешно создан.");
}
conn.disconnect();
}
}
Утилита для сканирования директорий
Приложение обходит структуру папок и выводит список всех файлов с указанием их размера и пути. Используется рекурсивный обход или класс Files.walk.
Разбор кода
- Files.walk: Поток путей, представляющий дерево директорий.
- Фильтрация: Исключение скрытых файлов или определенных расширений.
import java.io.IOException;
import java.nio.file.*;
import java.util.stream.Stream;
public class DirectoryScanner {
public static void main(String[] args) {
Path startPath = Paths.get("."); // Текущая директория
try (Stream<Path> stream = Files.walk(startPath)) {
stream
.filter(Files::isRegularFile) // Только файлы
.forEach(path -> {
long size = 0;
try {
size = Files.size(path);
} catch (IOException e) {
// Игнорирование ошибок доступа
}
System.out.printf("%s (%d байт)%n", path, size);
});
} catch (IOException e) {
System.err.println("Ошибка сканирования: " + e.getMessage());
}
}
}
Скрипт для создания резервного копирования файлов
Приложение копирует файлы из одной директории в другую с добавлением временной метки к имени файла. Это демонстрирует работу с StandardCopyOption и манипуляцию именами файлов.
import java.io.IOException;
import java.nio.file.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class BackupUtility {
public static void main(String[] args) {
Path sourceDir = Paths.get("source_data");
Path backupDir = Paths.get("backup_data");
try {
// Создание директории бэкапа, если её нет
Files.createDirectories(backupDir);
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");
String timestamp = now.format(formatter);
// Поиск всех файлов в источнике
try (var stream = Files.list(sourceDir)) {
stream.forEach(file -> {
try {
String fileName = file.getFileName().toString();
String nameWithoutExt = fileName.substring(0, fileName.lastIndexOf('.'));
String ext = fileName.substring(fileName.lastIndexOf('.'));
Path newPath = backupDir.resolve(nameWithoutExt + "_" + timestamp + ext);
Files.copy(file, newPath, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Скопировано: " + fileName + " -> " + newPath.getFileName());
} catch (Exception e) {
System.err.println("Ошибка копирования " + file + ": " + e.getMessage());
}
});
}
} catch (IOException e) {
System.err.println("Критическая ошибка: " + e.getMessage());
}
}
}
Мониторинг дискового пространства
Утилита отображает информацию о свободном и занятом месте на диске. Используется класс FileStore из пакета java.nio.file.
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
public class DiskSpaceMonitor {
public static void main(String[] args) {
File root = new File("/"); // Корневая директория
try {
FileStore store = FileSystems.getDefault().getFileStore(root.toPath());
long totalSize = store.getTotalSpace();
long usableSize = store.getUsableSpace();
long usedSize = totalSize - usableSize;
System.out.println("Диск: " + root.getAbsolutePath());
System.out.println("Общий размер: " + formatBytes(totalSize));
System.out.println("Занято: " + formatBytes(usedSize));
System.out.println("Свободно: " + formatBytes(usableSize));
System.out.println("Процент использования: " + (totalSize > 0 ? (usedSize * 100 / totalSize) : 0) + "%");
} catch (IOException e) {
System.err.println("Ошибка получения информации о диске: " + e.getMessage());
}
}
private static String formatBytes(long bytes) {
if (bytes < 1024) return bytes + " B";
if (bytes < 1024 * 1024) return bytes / 1024 + " KB";
if (bytes < 1024 * 1024 * 1024) return bytes / (1024 * 1024) + " MB";
return bytes / (1024L * 1024 * 1024) + " GB";
}
}
Парсер URL и проверка доступности ресурса
Приложение принимает URL, разбирает его компоненты (протокол, хост, путь) и проверяет, доступен ли ресурс по HTTP.
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.UnknownHostException;
public class UrlChecker {
public static void main(String[] args) {
String urlString = "https://example.com";
try {
URL url = new URL(urlString);
System.out.println("Анализ URL: " + urlString);
System.out.println("Протокол: " + url.getProtocol());
System.out.println("Хост: " + url.getHost());
System.out.println("Порт: " + url.getPort());
System.out.println("Путь: " + url.getPath());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("HEAD"); // HEAD запрос быстрее GET
connection.setConnectTimeout(5000); // 5 секунд таймаут
connection.connect();
int statusCode = connection.getResponseCode();
System.out.println("Статус кода: " + statusCode);
if (statusCode >= 200 && statusCode < 300) {
System.out.println("Ресурс доступен.");
} else {
System.out.println("Ресурс недоступен или вернул ошибку.");
}
connection.disconnect();
} catch (UnknownHostException e) {
System.out.println("Ошибка: Хост не найден.");
} catch (IOException e) {
System.out.println("Ошибка сети: " + e.getMessage());
}
}
}
Конвертер форматов дат
Работа с датами в Java требует внимания к деталям. Приведен пример конвертации между старым форматом SimpleDateFormat (для совместимости) и новым API java.time (рекомендуемый стандарт с Java 8).
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public class DateConverter {
public static void main(String[] args) {
String dateString = "2026-05-06 14:30:00";
String inputPattern = "yyyy-MM-dd HH:mm:ss";
String outputPattern = "dd/MM/yyyy HH:mm";
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern(inputPattern);
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern(outputPattern);
try {
LocalDateTime dateTime = LocalDateTime.parse(dateString, inputFormatter);
// Конвертация в другой формат
String formattedDate = dateTime.format(outputFormatter);
System.out.println("Исходная строка: " + dateString);
System.out.println("Преобразованная строка: " + formattedDate);
// Пример получения даты сегодня
LocalDate today = LocalDate.now();
System.out.println("Сегодня: " + today);
} catch (DateTimeParseException e) {
System.out.println("Неверный формат даты: " + e.getMessage());
}
}
}
Утилита для просмотра запущенных процессов
Приложение выводит список активных процессов операционной системы с их идентификаторами (PID) и названиями. В Java для этого используется класс ProcessHandle.
import java.util.Comparator;
import java.util.stream.Stream;
public class ProcessViewer {
public static void main(String[] args) {
System.out.println("Список запущенных процессов:");
System.out.println("PID\t\tName");
System.out.println("---------------------------");
// Stream API для обработки процесса
try (Stream<ProcessHandle> processes = ProcessHandle.allProcesses()) {
processes
.sorted(Comparator.comparingLong(ProcessHandle::pid))
.forEach(process -> {
long pid = process.pid();
String name = process.info().command().orElse("N/A");
// Ограничение вывода первых 100 символов имени
if (name.length() > 100) {
name = name.substring(0, 97) + "...";
}
System.out.printf("%d\t%s%n", pid, name);
});
}
}
}
Характерная черта Java: Класс ProcessHandle предоставляет безопасный и удобный способ взаимодействия с процессами ОС без необходимости вызова нативных библиотек.
См. также
Другие статьи этого же раздела в боковом меню (как на странице «О разделе»). JDK (Java Разработка Kit) — полный комплект разработчика. Включает — Компилятор javac для преобразования исходного кода в байт-код, Виртуальную машину JVM для выполнения байт-кода, Стандартные… Фундамент для начинающего программиста - что повторить, как работать, чего ожидать. Набор советов, правил, принципов и обычаев в разработке на этом языке. Use-after-free — это обращение к участку памяти после его освобождения. Программа продолжает использовать указатель на объект, память которого уже возвращена системе управления памятью. Библиотеки, фреймворки, инструменты сборки, тестирования, развёртывания и мониторинга. Что такое пакет и пакетная структура, как собираются проекты на Java. Справочник-шпаргалка по конфигурациям в Java — типы, синтаксис, стандартная библиотека, типовые паттерны. Не заменяет пошаговое обучение. Учебный курс — раздел. Гайд по установке и настройке с написанием первой программы и её запуском. Кавычки, точки, запятые, скобки и прочие знаки препинания. Это полный справочник всех ключевых слов языка Java, включая основные, контекстные и зарезервированные слова. Набор функций, которые включены в стандартную библиотеку языка. Типизация, набор правил определения типа данных значений языка.Основы языка Java
Что требуется знать перед началом изучения языка программирования Java
Рекомендации по разработке на Java
История языка Java
Экосистема Java-приложений
Структура и сборки Java-проектов
Справочник по конфигурациям в Java
Первая программа на Java
Синтаксис и пунктуация в Java
Ключевые слова в Java
Встроенные функции и методы Java
Типы данных и переменные в Java