Кофе-брейк #133. Как получить только часть массива в Java. Интерфейсы и абстрактные классы в Java

Статья из группы Random

Как получить только часть массива в Java

Источник: Asyncq Копирование части массива — весьма распространенная операция, с которой сталкивается каждый разработчик. В этой статье мы увидим традиционный императивный стиль и современный код декларативного стиля с лямбда-выражением и потоковым API. Кофе-брейк #133. Как получить только часть массива в Java. Интерфейсы и абстрактные классы в Java - 1

Императивный подход

Императивный стиль программирования давно распространен в Java. Поэтому для Java-разработчиков естественно писать приведенный ниже код для копирования определенной части исходного массива. Для этого достаточно просто перебрать элементы, отфильтровывая только те из них, которые необходимы, и записать их в окончательный массив.

 private static int[] copyArray(){
        int[] numbers = {1,2,3,4,5,6,7};
        int[] subArray = new int[numbers.length-3];
        int j =3;
        for (int i=0;i<subArray.length;i++){
            subArray[i] = numbers[j+i];
        }
        System.out.println(Arrays.toString(subArray));
        return subArray;
    }
Многие из нас часто забывают, что в Java-библиотеке Arrays есть удобный метод copyOfRange. Этот метод можно использовать для копирования части массива путем передачи в индекс и из него.

private static int[] copyArray1(){
  int[] numbers = {1,2,3,4,5,6,7};
  int[] subArray = Arrays.copyOfRange(numbers,3,numbers.length);
  System.out.println(Arrays.toString(subArray));
  return subArray;
}

Декларативный подход

Начиная с Java 8 мы можем использовать API потоков для копирования части массива. В приведенном ниже коде мы можем передавать int[] и отфильтровывать только значения, превышающие 3, и, наконец, копировать их в массив.

private static void copyArray2(){
        int[] numbers = {1,2,3,4,5,6,7};
        // copy with values
        int[] subArray = Arrays.stream(numbers).filter(a-> a>3).toArray();
        System.out.println(Arrays.toString(subArray));
    }
Приведенный выше код является копией части массива на основе значений, но мы также можем копировать на основе индекса. Ниже кода мы транслируем Intstream from i=0; i=len(array). Обычно в императивном коде мы пишем цикл for от начального индекса к конечному индексу и перебираем каждый элемент. Аналогично мы можем сделать с помощью Intstream и получить доступ к элементу index.

// copy with index
int[] subArray1 = IntStream
                .range(0, numbers.length)
                .filter(i -> i > 3)
                .map(a->numbers[a]).toArray();

System.out.println(Arrays.toString(subArray1));
Хотя описанный выше метод работает, у нас есть другой способ, в котором мы можем использовать AtomicInteger для копирования части массива. У него есть метод getAndIncrement, который по существу предоставляет индекс и увеличивает его на 1.

// copy with index
AtomicInteger atomicInteger = new AtomicInteger();
int[] subArray2 = Arrays.stream(numbers).filter(i -> atomicInteger.getAndIncrement() > 3).toArray();
System.out.println(Arrays.toString(subArray2));

Заключение

В этой статье мы обсудили, как можно скопировать часть массива Java, используя императивный и декларативный стили. Я бы предпочел работать в декларативном стиле, так как он делает мой код более читабельным и менее подробным.

Интерфейсы и абстрактные классы в Java

Источник: Devgenius При изучении языка Java мы непременно сталкиваемся с концепцией под названием Interfaces. Интерфейсы — одна из ключевых особенностей Java, поэтому каждый разработчик должен знать, как их применять. Важно помнить, что у интерфейсов есть как свои преимущества, так и недостатки. Давайте углубимся в понимание интерфейсов. При реализации интерфейсов мы сталкиваемся с абстрактными классами. Что такое абстрактные классы? Зачем они нужны? Что такое интерфейс? Как они используются? Почему в интерфейсах применяются абстрактные классы? Ответы на все эти вопросы вы получите в этой статье. Кофе-брейк #133. Как получить только часть массива в Java. Интерфейсы и абстрактные классы в Java - 2

Что такое интерфейс?

Интерфейс — это особый механизм в Java, который описывает поведение и помогает достичь абстракции. Он во многом похож на класс, потому что имеет статические константы и абстрактные методы. Интерфейсы могут иметь только абстрактные методы (методы без тела). Краткое различие между интерфейсом и абстрактным классом:
  • У интерфейса ни один метод не реализован, все они публичные и нет переменных класса.
  • Абстрактный класс — это класс, у которого не реализован один или больше методов.
Начиная с Java 9 мы также можем использовать в интерфейсах методы private, default и static. А теперь давайте перейдем к простой логике интерфейса, которая используется для достижения абстракции.

Что такое абстракция?

Давайте возьмем пример из реальной жизни. Мы все используем приложения на мобильных телефонах. Всякий раз, когда мы хотим использовать какое-либо приложение, мы должны создать в нем учетную запись. Когда мы регистрируемся через свой номер телефона, на наш мобильный приходит одноразовый пароль. Мы знаем, что пароль приходит после нажатия кнопки “Получить пароль” в приложении, но мы не знаем, как эта система работает в бэкенде и что на самом деле происходит после нажатия кнопки. Так вот, процесс успешного выполнения задач без отображения пользователю того, что на самом деле происходит в бэкенде, известен как абстракция. В Java мы можем достичь абстракции, используя интерфейсы и абстрактные классы.

Зачем использовать интерфейс?

Существует три причины для использования интерфейса:
  • Для достижения абстракции.
  • Для поддержания функциональности множественного наследования.
  • Для достижения слабой связанности (loose coupling).

Как пользоваться интерфейсом?

Интерфейс объявляется с помощью ключевого слова interface. Он обеспечивает абстракцию, то есть объявляет структуру класса. Все методы в интерфейсе являются абстрактными и по умолчанию устанавливаются как общедоступные, статические и окончательные (public, static, final). Какой бы класс ни реализовывал интерфейс, он должен реализовывать все методы, объявленные в интерфейсе.

interface <interface_name>{  
       
     // declare constant fields  
     // declare methods that abstract   
     // by default. 
 }
Подобно абстракции интерфейсов, абстракция также может быть достигнута с использованием абстрактных классов.

Что такое абстрактные классы?

Абстрактные классы — это классы с ключевым словом abstract перед ними. Они содержат как абстрактные, так и конкретные методы (с телом). Абстрактные классы не могут быть созданы, они должны быть расширены, а их методы должны быть реализованы. Абстрактный класс описывает некий абстрактный объект (автомобиль, человека и так далее), а не только поведение. Запомните:
  • Абстрактный класс должен быть объявлен с ключевым словом abstract.
  • Могут быть абстрактные и неабстрактные методы.
  • Экземпляр абстрактного класса нельзя создать.
  • Он может иметь конструкторы и статические методы.
  • Он может иметь методы final, которые заставят подкласс не изменять тело метода.
Пример абстрактного класса с абстрактным методом: В этом примере Bike — это абстрактный класс, который содержит только один запуск абстрактного метода. Его реализация обеспечивается классом Honda.

abstract class Bike{  
  abstract void run();  
}  
class Honda4 extends Bike{  
void run(){System.out.println("running safely");}  
public static void main(String args[]){  
 Bike obj = new Honda4();  
 obj.run();  
}  
}
Абстрактный класс, имеющий конструктор, элемент данных и методы: Абстрактный класс может иметь элемент данных, абстрактный метод, тело метода (неабстрактный метод), конструктор и даже метод main().

//Example of an abstract class that has abstract and non-abstract methods  
 abstract class Bike{  
   Bike(){System.out.println("bike is created");}  
   abstract void run();  
   void changeGear(){System.out.println("gear changed");}  
 }  
//Creating a Child class which inherits Abstract class  
 class Honda extends Bike{  
 void run(){System.out.println("running safely..");}  
 }  
//Creating a Test class which calls abstract and non-abstract methods  
 class TestAbstraction2{  
 public static void main(String args[]){  
  Bike obj = new Honda();  
  obj.run();  
  obj.changeGear();
}
}
Теперь возникает главный вопрос. Если интерфейсы и абстрактные классы помогают в абстракции, то что из них лучше использовать? Ответ состоит в том, что Java не поддерживает множественное наследование, как это делает C++. То есть если нам нужно добиться множественного наследования, тогда нам стоит использовать интерфейсы. Иными словами абстрактные классы помогают от 1 до 100% случаев, а интерфейсы помогают в 100% случаев. Если нам нужно поведение — необходимо использовать интерфейс. Если речь про концептуальный объект — мы должны использовать абстрактный класс.

Пример интерфейса Java

В этом примере интерфейс Drawable имеет только один метод. Его реализация обеспечивается классами Rectangle и Circle. В реальном сценарии интерфейс определяется кем-то другим, а его реализация предоставляется различными поставщиками реализации. Более того, он используется кем-то еще. Часть реализации скрыта пользователем, использующим интерфейс.

//Interface declaration: by first user  
interface Drawable{  
void draw();  
}  
//Implementation: by second user  
class Rectangle implements Drawable{  
public void draw(){System.out.println("drawing rectangle");}  
}  
class Circle implements Drawable{  
public void draw(){System.out.println("drawing circle");}  
}  
//Using interface: by third user  
class TestInterface1{  
public static void main(String args[]){  
Drawable d=new Circle();//In real scenario, object is provided by method e.g. getDrawable()  
d.draw();  
}}

Множественное наследование в Java с помощью интерфейса

Если класс реализует несколько интерфейсов или интерфейс расширяет несколько интерфейсов, это называется множественным наследованием.

interface Printable{  
void print();  
}  
interface Showable{  
void show();  
}  
class A7 implements Printable,Showable{  
public void print(){System.out.println("Hello");}  
public void show(){System.out.println("Welcome");}  
  
public static void main(String args[]){  
A7 obj = new A7();  
obj.print();  
obj.show();  
 }  
}
Вопрос: Множественное наследование не поддерживается через класс в Java, но возможно через интерфейс, почему? Как уже объяснялось в разделе о наследовании, множественное наследование не поддерживается на примере класса из-за неоднозначности. Однако оно поддерживается на примере интерфейса, поскольку в нем нет неоднозначности. Причина в том, что его реализация обеспечивается классом реализации.
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ