О единственном дубликате в массиве целых чисел
Задан массив (или ArrayList, как вам больше нравится) целых чисел, в котором содержатся элементы Integer от 1 до 100. В этом массиве есть один и только один продублированный элемент. Как его найти?
Такие задачи для Java-программиста привычнее, чем предыдущие три. Потому что она не о знании тонкостей языка, которые почти никогда не используются, а о логике.
Первый необузданный порыв — решать перебором — пропадает довольно быстро, когда включается голова или там установка «я же программист, я же умный». Плохо только, что на собеседовании, в условиях стресса, этого может и не произойти. Так что думайте сейчас, прежде, чем заглядывать в решение!
Алгоритм решения следующий:
Посчитайте сумму всех чисел от 1 до 100. Думаем, вы знаете, как это можно сделать (например, с помощью знаменитого метода Гаусса)
Теперь считаете сумму элементов вашего массива или ArrayList’а.
И… вычитаете первую сумму из второй.
Бинго! Полученное число — и есть значение дублирующегося элемента.
Код решения java-задачи для ArrayList.
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class FindDuplicate {
private static void findDuplicate(List<Integer> elements) {
//находим сумму всех уникальных элементов списка
int distinctSum = elements.stream().distinct().mapToInt(e -> e).sum();
//находим сумму всех элементов списка
int totalSum = elements.stream().mapToInt(e -> e).sum();
System.out.println("Элемент, который повторяется : " + (totalSum - distinctSum));
}
public static void main(String[] args) {
//создаем список последовательных элементов на промежутке [1..101).
List <Integer> elements = IntStream.range(1, 101).boxed().collect(Collectors.toList());
//устанавливаем элементу с индексом 53 значение 23
elements.set(53, 23);
findDuplicate(elements);
}
}
Другое решение
import java.util.List;
import java.util.ArrayList;
public class Duplicate {
public int findDuplicateNumber(List<Integer> numbers) {
int highestNumber = numbers.size() - 1;
int total = getSum(numbers);
int duplicate = total - (highestNumber * (highestNumber + 1) / 2);
return duplicate;
}
public int getSum(List<Integer> numbers) {
int sum = 0;
for (int num : numbers) {
sum = sum + num;
}
return sum;
}
public static void main(String a[]) {
List <Integer> numbers = new ArrayList <Integer>();
for (int i = 1; i < 100; i++) {
numbers.add(i);
}
//добавляем дубликат в список
numbers.add(25);
Duplicate dn = new Duplicate();
System.out.println("Элемент, который повторяется: " + dn.findDuplicateNumber(numbers));
}
}
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
О неединственном дубликате в массиве целых чисел
Если предыдущая задачка показалась вам слишком лёгкой, то попробуйте решить следующую: дан лист целых чисел от 1 до 100. В нём есть дубликаты (больше одного). Как найти элементы, которые встречаются больше одного раза (найти сам элемент и указать, сколько раз он встречается)?
Решение
Тут логичнее всего для решения использовать такую структуру, как HashMap, поскольку она хранит данные парами «ключ-значение».
Код решения Java-задачи:
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SomeDuplicates {
private static void findDuplicates(List<Integer> elements) {
HashMap <Integer, Integer > duplicates = new HashMap < >();
//заполняем Map duplicates значениями по принципу:
// ключ – значение элемента, значение – сколько раз он встречается
elements.forEach(e -> duplicates.put(e, duplicates.get(e) == null ? 1 : duplicates.get(e) + 1));
//из duplicates убираем все элементы, которые встретились не более 1 раза,
//и сохраняем //результат в список (для удобства обработки на следующем шаге)
List <Map.Entry <Integer, Integer> >
result = duplicates.entrySet().stream().filter(d -> d.getValue() > 1).collect(Collectors.toList());
//выводим результат для всех элементов в списке result
result.forEach(e -> System.out.println(String.format("Элемент %d встречается %d раз", e.getKey(), e.getValue())));
}
public static void main(String[] args) {
List <Integer> elements = IntStream.range(1, 101).boxed().collect(Collectors.toList());
elements.set(97, 23);
elements.set(27, 51);
elements.set(99, 23);
findDuplicates(elements);
}
}
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Когда имеет смысл предпочесть абстрактный класс интерфейсу и наоборот?
Это продолжение предыдущих вопросов по абстрактным классам и интерфейсам. Если вы знаете, каковы их синтаксические различия, то ответ на этот вопрос не доставит вам проблем, так как именно они служат определяющим фактором принятия решения. Поскольку в опубликованный интерфейс практически невозможно добавить новый метод, в случае потенциальной необходимости доработки лучше использовать абстрактный класс. Развивать абстрактные классы в Java проще, чем интерфейсы. Аналогично, если в интерфейсе слишком много методов и реализация их всех становится настоящей головной болью, лучше создать абстрактный класс для реализации по умолчанию. Этому паттерну следуют и в пакете коллекций Java, абстрактный класс
AbstractList
обеспечивает реализацию по умолчанию для интерфейса List.Используйте абстрактные классы, если:
Вы хотите поделиться кодом между несколькими тесно связанными классами.
- Вы ожидаете, что классы, которые расширяют ваш абстрактный класс, имеют много общих методов или полей, или требуют других модификаторов доступа, кроме public (например, protected и private).
- Вы хотите объявить нестатические или не-final поля. Это позволяет вам определять методы, которые могут получить доступ и изменить состояние объекта, которому они принадлежат.
Используйте интерфейсы, если:
- Вы ожидаете, что несвязанные классы будут реализовывать ваш интерфейс. Например, интерфейсы Comparable и Cloneable реализуются многими несвязанными классами.
- Вы хотите определить поведение конкретного типа данных, но вам не важно, кто его реализует.
- Вы хотите использовать множественное наследование типа.
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Когда я начинал работать с MongoDB и Java, мне часто приходилось сталкиваться с трудностями при выборе правильной операции обновления из различных методов, предоставляемых MongoDB. Даже во время код-ревью я получал комментарии от рецензента, где мне предлагали воспользоваться, к примеру, findAndModify() вместо updateMulti().
Здесь мы обсудим различные типы операций обновления в MongoDB и то, чем они отличаются друг от друга. Я буду использовать Java 8 с фреймворком SpringBoot и реализовывать пользовательские сценарии, которые можно найти на Github.
Мы будем оценивать все операции обновления на основе пяти параметров.
- Критерии поиска (Search Criteria).
- Значение обновления (весь документ или определение обновления).
- Возвращаемое значение (весь документ или статистика результатов обновления).
- Поведение по умолчанию, если соответствующий(е) документ(ы) не найден(ы). (вставлять/не вставлять/гибкий ответ).
- Дельта-обновление.
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Ответ
Да, абстрактные классы могут реализовывать интерфейсы с помощью ключевого слова implements. Поскольку они абстрактные, то не обязаны реализовывать все методы. Наличие абстрактного базового класса и интерфейса для объявления типа является рекомендуемой практикой.
Пример — интерфейс
java.util.List
и соответствующий абстрактный класс java.util.AbstractList
. Поскольку AbstractList реализует все общие методы, то конкретные реализации (например, LinkedList
и ArrayList
) не должны реализовать все методы, как в случае, если бы они реализовали интерфейс List
напрямую. Это решение сочетает преимущество использования интерфейса для объявления типа и гибкость абстрактного класса для реализации всего общего поведения в одном месте.
В книге Джошуа Блоха «Java. Эффективное программирование» есть отличная глава на тему использования интерфейсов и абстрактных классов в Java, для лучшего понимания имеет смысл её изучить.
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Напишите метод, который проверяет, входит ли в массив заданный элемент или нет.
Используйте перебор и двоичный поиск для решения этой задачи.
Сравните время выполнения обоих решений для больших массивов (например, 100000000 элементов).
/*
Просто перебираем, пока не найдет.
Если ничего не найдём, вернём -1
*/
public static int bruteForce(double[] array, double key) {
for (int i = 0; i < array.length; i++) {
if (array[i] == key)
return i;
}
return -1;
}
/*
Двоичный поиск
*/
public static int binarySearchRecursively(double[] sortedArray, double key) {
return binarySearchRecursively(sortedArray, key, 0, sortedArray.length);
}
/**
* Вспомогательный метод для {@link #binarySearchRecursively(double[], double)}
*
* Будем делить отрезок пополам, но не копировать, а просто "сдвигать границы",
* и вызывать этот же метод рекурсивно. Для этого используем low и high
*
* @param sortedArray сортированный массив
* @param key искомое значение
* @param low от какого значения ищем
* @param high до какого значения ищем
* @return индекс элемента
*/
private static int binarySearchRecursively
(double[] sortedArray, double key, int low, int high) {
int middle = (low + high) / 2; // середина
if (high < low) { // больше делить нечего
return -1;
}
if (key == sortedArray[middle]) { // если нашёлся
return middle;
} else if (key < sortedArray[middle]) { // ищем в левой половине
return binarySearchRecursively(
sortedArray, key, low, middle - 1);
} else {
return binarySearchRecursively( // ищем в правой половине
sortedArray, key, middle + 1, high);
}
}
// Вспомогательный метод для тестов
private static double[] generateRandomArray(int length) {
double[] array = new double[length];
for (int i = 0; i < array.length; i++) {
array[i] = Math.random();
}
return array;
}
public static void main(String[] args) {
double[] array = generateRandomArray(100000000);
Arrays.sort(array); // нужно сначала отсортировать
/*
Строго говоря,
измерять время выполнения так не совсем корректно,
лучше использовать benchmarks
см. https://habr.com/ru/post/349914/
Но масштаб будет понятен
*/
long time = System.currentTimeMillis(); // текущее время, unix-time
bruteForce(array, 0.5);
System.out.println(System.currentTimeMillis() - time);
time = System.currentTimeMillis();
binarySearchRecursively(array, 0.5);
System.out.println(System.currentTimeMillis() - time);
}
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача:
Напишите метод, который проверяет, входит ли в массив заданный элемент или нет.
Используйте перебор и двоичный поиск для решения этой задачи.
Сравните время выполнения обоих решений для больших массивов (например, 100000000 элементов).
Решение:
/*
Просто перебираем, пока не найдет.
Если ничего не найдём, вернём -1
*/
public static int bruteForce(double[] array, double key) {
for (int i = 0; i < array.length; i++) {
if (array[i] == key)
return i;
}
return -1;
}
/*
Двоичный поиск
*/
public static int binarySearchRecursively(double[] sortedArray, double key) {
return binarySearchRecursively(sortedArray, key, 0, sortedArray.length);
}
/**
* Вспомогательный метод для {@link #binarySearchRecursively(double[], double)}
*
* Будем делить отрезок пополам, но не копировать, а просто "сдвигать границы",
* и вызывать этот же метод рекурсивно. Для этого используем low и high
*
* @param sortedArray сортированный массив
* @param key искомое значение
* @param low от какого значения ищем
* @param high до какого значения ищем
* @return индекс элемента
*/
private static int binarySearchRecursively
(double[] sortedArray, double key, int low, int high) {
int middle = (low + high) / 2; // середина
if (high < low) { // больше делить нечего
return -1;
}
if (key == sortedArray[middle]) { // если нашёлся
return middle;
} else if (key < sortedArray[middle]) { // ищем в левой половине
return binarySearchRecursively(
sortedArray, key, low, middle - 1);
} else {
return binarySearchRecursively( // ищем в правой половине
sortedArray, key, middle + 1, high);
}
}
// Вспомогательный метод для тестов
private static double[] generateRandomArray(int length) {
double[] array = new double[length];
for (int i = 0; i < array.length; i++) {
array[i] = Math.random();
}
return array;
}
public static void main(String[] args) {
double[] array = generateRandomArray(100000000);
Arrays.sort(array); // нужно сначала отсортировать
/*
Строго говоря,
измерять время выполнения так не совсем корректно,
лучше использовать benchmarks
см. https://habr.com/ru/post/349914/
Но масштаб будет понятен
*/
long time = System.currentTimeMillis(); // текущее время, unix-time
bruteForce(array, 0.5);
System.out.println(System.currentTimeMillis() - time);
time = System.currentTimeMillis();
binarySearchRecursively(array, 0.5);
System.out.println(System.currentTimeMillis() - time);
}
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Прежде всего, нам нужно понять, что такое число Армстронга. Число Армстронга это число, значение которого равно сумме цифр, из которых оно состоит, возведенных в степень, равную количеству цифр в этом числе. Как пример - число 371:
371 = 3*3*3 + 7*7*7 + 1*1*1 = 27 + 343 + 1 = 371
Если у вас число четырехзначное:
8208 = 8*8*8*8 + 2*2*2*2 + 0*0*0*0 + 8*8*8*8 = 4096 + 16 + 0 + 4096 = 8208
Выполняя решение, для начала мы объявляем целочисленные переменные tempNumber, x и y. Мы инициализировали переменную y значением 0. Затем мы создаем переменную qurentNumber и присваиваем ей целочисленное значение, которое мы собираемся проверить является ли оно числом Армстронга (в нашем случае это 371). Затем мы присвоили нашей переменной tempNumber то значение, которое хранится в проверяемой переменной qurentNumber.
Далее в цикле while мы переменной a присваиваем остаток от деления числа qurentNumber на 10 – и получим число единиц в изначальном числе qurentNumber. Затем мы заменяем значение переменной qurentNumber на результат деления введенного числа на 10. Нашей переменной y, значение которой изначально было установлено как 0, присваивается результат y + (x* x * x). Таким образом во время первой итерации в y попадет результат возведения в нужную степень значения числа единиц в изначальном числе, при следующей итерации в y к степени числа единиц добавится результат возведения в степень числа десятков, и так далее по всем разрядам до конца числа qurentNumber с права налево.
Наконец, мы используем оператор if-else для проверки, будет ли полученное значение переменной y равно значению переменной tempNumber (в которой хранится исходное число). Если y = tempNumber, то загаданное число является числом Армстронга, иначе - нет.
public class SeventeenthTask{
public static void main(String[] args) {
int y=0, x, tempNumber;
int qurentNumber=371; //Данное число мы будем проверять на то, является ли оно числом Армстронга
tempNumber = qurentNumber;
while(qurentNumber >0)
{
x= qurentNumber %10;
qurentNumber = qurentNumber /10;
y=y+(x*x*x);
}
if(tempNumber ==y)
System.out.println("Данное число является числом Армстронга");
else
System.out.println("Данное число не является числом Армстронга");
}
}
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Ответ:
В этой программе мы инициализировали массив с 10 случайными элементами, из которых мы собираемся найти второе по величине число. Далее мы создали две целочисленные переменные, которым будем присваивать значения двух целых чисел из массива - самого большого и второго по величине. Обе переменные изначально получают значения первого по индексу элемента массива. Затем мы выводим на экран все элементы, используя цикл for.
Дальнейшая логика работы программы в том, чтобы используя цикл for обойти массив.
При обходе, если элемент массива с текущим индексом больше, чем значение, хранящееся в переменной biggest, тогда переменной secondBiggest присваиваем значение, хранящееся в biggest, а переменной biggest – новое наибольшее значение в соответствии со значением текущего элемента массива. Опять же, если элемент по текущему индексу больше, чем secondBiggest, то присвойте secondBiggest значение этого элемента.
Это будет повторяться для каждой итерации и, в конечном итоге, после завершения обхода массива в цикле вы получите элементы наибольший и второй по величине элементы массива в переменных biggest и secondBiggest соответственно.
public class SixteenthTask {
public static void main(String[] args)
{
int numbersArray[] = { 10, 15, 32, 100, 16, 11, 98, 36, 95, 33 };
int biggest= numbersArray[0];
int secondBiggest = numbersArray[0];
System.out.println("Полученный массив: ");
for (int i = 0; i < numbersArray.length; i++)
{
System.out.print(numbersArray[i] + "\t");
}
for (int i = 0; i < numbersArray.length; i++)
{
if (numbersArray[i] > biggest)
{
secondBiggest = biggest;
biggest = numbersArray[i];
}
else if (numbersArray[i] > secondBiggest && numbersArray[i] != biggest)
{
secondBiggest = numbersArray[i];
}
}
System.out.println("\nВторое по величине число:" + secondBiggest);
}
}
На экране получим:
Полученный массив:
10 15 32 100 16 11 98 36 95 33
Второе по величине число: 98
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
☕🧵 Введение в многопоточность в Java. Часть 2. Жизненный цикл потоков, Thread.join() и потоки-демоны
https://proglib.io/p/vvedenie-v-mnogopotochnost-v-java-chast-2-zhiznennyy-cikl-potokov-thread-join-i-potoki-demony-2022-11-30
@javatg
https://proglib.io/p/vvedenie-v-mnogopotochnost-v-java-chast-2-zhiznennyy-cikl-potokov-thread-join-i-potoki-demony-2022-11-30
@javatg
Библиотека программиста
☕🧵 Введение в многопоточность в Java. Часть 2. Жизненный цикл потоков, Thread.join() и потоки-демоны
В этой части узнаем, какие состояния проходят потоки в своем жизненном цикле, что такое ожидание потоков и что такое потоки-демоны.
Ответ:
В этой программе мы инициализировали массив с 10 случайными элементами, из которых мы собираемся найти второе по величине число. Далее мы создали две целочисленные переменные, которым будем присваивать значения двух целых чисел из массива - самого большого и второго по величине. Обе переменные изначально получают значения первого по индексу элемента массива. Затем мы выводим на экран все элементы, используя цикл for.
Дальнейшая логика работы программы в том, чтобы используя цикл for обойти массив.
При обходе, если элемент массива с текущим индексом больше, чем значение, хранящееся в переменной biggest, тогда переменной secondBiggest присваиваем значение, хранящееся в biggest, а переменной biggest – новое наибольшее значение в соответствии со значением текущего элемента массива. Опять же, если элемент по текущему индексу больше, чем secondBiggest, то присвойте secondBiggest значение этого элемента.
Это будет повторяться для каждой итерации и, в конечном итоге, после завершения обхода массива в цикле вы получите элементы наибольший и второй по величине элементы массива в переменных biggest и secondBiggest соответственно.
public class SixteenthTask {
public static void main(String[] args)
{
int numbersArray[] = { 10, 15, 32, 100, 16, 11, 98, 36, 95, 33 };
int biggest= numbersArray[0];
int secondBiggest = numbersArray[0];
System.out.println("Полученный массив: ");
for (int i = 0; i < numbersArray.length; i++)
{
System.out.print(numbersArray[i] + "\t");
}
for (int i = 0; i < numbersArray.length; i++)
{
if (numbersArray[i] > biggest)
{
secondBiggest = biggest;
biggest = numbersArray[i];
}
else if (numbersArray[i] > secondBiggest && numbersArray[i] != biggest)
{
secondBiggest = numbersArray[i];
}
}
System.out.println("\nВторое по величине число:" + secondBiggest);
}
}
На экране получим:
Полученный массив:
10 15 32 100 16 11 98 36 95 33
Второе по величине число: 98
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Ответ:
Это простая программа, в которой у нас есть строковая переменная st1.
Другая строковая переменная st2 инициализируется с помощью метода replaceAll, который является встроенным методом для удаления n числа пробелов. В итоге мы выводим на экран st2, которая уже не содержит пробелов.
public class EighteenthTask
{
public static void main(String[] args)
{
String st1 = "Мы готовимся к интервью на вакансию Java разработчика";
//Используем метод replaceAll()
String st2 = st1.replaceAll("\\s", "");
System.out.println(st2);
}
}
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Ответ:
Чтобы проверить, является ли число или строка палиндромом или нет, вы можете использовать любую переворачивающую строки программу, из описанных выше,.
Что вам нужно сделать, так это добавить один оператор if-else. Если исходная строка равна перевернутой строке, то число является палиндромом, в противном случае - нет.
import java.util.Scanner;
public class EighthTask{
public static void main (String[] args) {
String inputString, reversedString = "";
Scanner scannerQ = new Scanner(System.in);
int stringLength;
System.out.println("Введите число или строку");
inputString = scannerQ.nextLine();
stringLength = inputString.length();
for (int x = stringLength -1; x>=0; x--) {
reversedString = reversedString + inputString.charAt(x);
}
System.out.println("перевернутое значение: " + reversedString);
if(inputString.equals(reversedString))
System.out.println("Введенное значение является палиндромом");
else
System.out.println("Введенное значение не является палиндромом");
}
}
На экране получим:
Для строки-
Введите число или строку
dfggg
перевернутое значение: gggfd
Введенное значение не является палиндромом
Для числа-
Введите число или строку
777
перевернутое значение: 777
Введенное значение является палиндромом
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
class Test{
private int id;
private Integer id2;
public Test(int id, Integer id2) {
System.out.println("Создаем екзепляр Test");
this.id = id;
this.id2 = id2;
}
public Integer doIt(){
return id + id2;
}
}
class Test1{
private Test test;
private static int i;
public Test1() {
System.out.println("Создаем екзепляр Test1");
this.test = new Test(i, 10);
}
public Test getTest() {
return test;
}
}
class Main {
public static void main(String[] args) {
Test1 test1 = new Test1();
System.out.println(test1.getTest().doIt());
// Test test = new Test(null, 1);
// test.doIt();
}
}
Пишите ваши варианты ответов в комментариях.
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Для чего нужна Double Brace инициализация в Java?
Double Brace инициализация используется в Java для наполнения коллекций(set, list, map, queue) одновременно с их объявлением. В случае если вам необходимо создать unmodifiable коллекцию, без Double Brace инициализации нам будет необходимо создать список, положить туда необходимое кол-во элементов и создать из этого списка unmodifiableList используя Collections класс. Используя Double Brace инициализацию мы имеем возможность "положить" в unmodifiableList все необходимые элементы сразу при объявлении.
@javatg
Double Brace инициализация используется в Java для наполнения коллекций(set, list, map, queue) одновременно с их объявлением. В случае если вам необходимо создать unmodifiable коллекцию, без Double Brace инициализации нам будет необходимо создать список, положить туда необходимое кол-во элементов и создать из этого списка unmodifiableList используя Collections класс. Используя Double Brace инициализацию мы имеем возможность "положить" в unmodifiableList все необходимые элементы сразу при объявлении.
@javatg
Здесь мы для начала вставили три элемента в переменную типа HashMap с именем keyValue, используя функцию put().
Размер переменной keyValue можно получить с помощью метода size(). После этого мы использовали цикл While для обхода keyValue, которая содержит по одной паре ключ-значение для каждого элемента. Ключи и значения могут быть получены с помощью методов getKey() и getValue().
Аналогично, мы используем расширенный цикл for, на элементах «qurentMe2» в HashMap.
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class SixthTask{
public static void main(String[] args) {
HashMap<Integer,String> keyValue = new HashMap<Integer,String>();
keyValue.put(1, "Hello");
keyValue.put(2, "World");
keyValue.put(3, "Have a nice day!");
System.out.println(keyValue.size());
System.out.println("Цикл While:");
Iterator iter = keyValue.entrySet().iterator();
while(iter.hasNext()) {
Map.Entry qurentMe = (Map.Entry) iter.next();
System.out.println("Ключ это " + qurentMe.getKey() + " Значение это " + qurentMe.getValue());
}
System.out.println("Цикл For:");
for(Map.Entry qurentMe2: keyValue.entrySet()) {
System.out.println("Ключ это: " + qurentMe2.getKey() + " Значение это: " + qurentMe2.getValue());
}
}
}
На экране получим:
3
Цикл While:
Ключ это 1 Значение это Hello
Ключ это 2 Значение это World
Ключ это 3 Значение это Have a nice day!
Цикл For:
Ключ это: 1 Значение это: Hello
Ключ это: 2 Значение это: World
Ключ это: 3 Значение это: Have a nice day!
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
В следующем примере кода показан один из способов написания интерфейса с методом default и статическим методом:
public interface Interface1 {
// regular abstract method
void method1(String str);
default void log(String str) {
System.out.println("I1 logging::" + str);
}
static boolean isNull(String str) {
System.out.println("Interface Null Check");
return str == null ? true : "".equals(str) ? true : false;
}
}
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM
Допустим нужно удалить n элементов с позиции m в списке. Вместо выполнения удаления одного элемента n раз (каждый раз смещая на 1 позицию элементы, стоящие «правее» в списке), нужно выполнить смещение всех элементов, стоящих «правее» n + m позиции на n элементов «левее» к началу списка. Таким образом, вместо выполнения n итераций перемещения элементов списка, все выполняется за 1 проход. Но если говорить об общей эффективности - то самый быстрый способ будет с использованием System.arraycopy(), и получить к нему доступ можно через метод - subList(int fromIndex, int toIndex)
@javatg
Please open Telegram to view this post
VIEW IN TELEGRAM