Java中如何只获取数组的一部分
来源:
Asyncq 复制数组的一部分是每个开发人员都会遇到的非常常见的操作。在本文中,我们将看到传统的命令式风格和带有 lambda 表达式和流 API 的现代声明式风格代码。
命令式方法
命令式编程风格在 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 开始,我们可以使用 Streams API 来复制数组的一部分。在下面的代码中,我们可以传递
int[]并过滤掉大于3的值,最后将它们复制到数组中。
private static void copyArray2(){
int[] numbers = {1,2,3,4,5,6,7};
int[] subArray = Arrays.stream(numbers).filter(a-> a>3).toArray();
System.out.println(Arrays.toString(subArray));
}
上面的代码是对数组的一部分进行基于值的复制,但我们也可以基于索引进行复制。在代码下面,我们
从 i=0 广播 Intstream;i=len(数组)。通常,在命令式代码中,我们编写一个从开始索引到结束索引的
for循环,并迭代每个元素。我们可以使用 Intstream 执行相同的操作并访问
索引元素。
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。
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 语言时,我们肯定会遇到一个称为接口的概念。接口是 Java 的关键特性之一,因此每个开发人员都应该知道如何使用它们。重要的是要记住,接口既有优点也有缺点。让我们更深入地了解接口。在实现接口时,我们会遇到抽象类。什么是抽象类?需要它们做什么?什么是接口?它们是如何使用的?为什么接口使用抽象类?您将在本文中得到所有这些问题的答案。
什么是接口?
接口是Java中的一种特殊机制,用于描述行为并帮助实现抽象。它在很多方面与类相似,因为它具有静态常量和抽象方法。接口只能有抽象方法(没有主体的方法)。
接口和抽象类的简要区别:
- 该接口没有实现任何方法;它们都是公共的,并且没有类变量。
- 抽象类是没有实现一个或多个方法的类。
从 Java 9 开始,我们还可以在接口中使用
私有、
默认和
静态方法。现在让我们继续讨论用于实现抽象的简单接口逻辑。
什么是抽象?
让我们举一个现实生活中的例子。我们都在手机上使用应用程序。每当我们想要使用任何应用程序时,我们都必须在其中创建一个帐户。当我们通过电话号码注册时,一次性密码会发送到我们的手机上。我们知道在应用程序中单击“获取密码”按钮后会收到密码,但我们不知道该系统在后端如何工作以及单击该按钮后实际发生了什么。现在,成功完成任务而不向用户显示后端实际发生的情况的过程称为抽象。在Java中,我们可以使用接口和抽象类来实现抽象。
为什么要使用接口?
使用该接口的三个原因:
- 达到抽象的目的。
- 支持多重继承功能。
- 实现松耦合。
界面如何使用?
接口是使用
interface关键字声明的。它提供了抽象,即它声明了类的结构。接口中的所有方法都是抽象的,并且默认设置为 public、static 和 Final(
public、
static、
final)。无论什么类实现接口,都必须实现接口中声明的所有方法。
interface <interface_name>{
}
与接口抽象类似,抽象也可以使用抽象类来实现。
什么是抽象类?
抽象类是前面带有
abstract关键字的类。它们包含抽象方法和具体方法(带有主体)。抽象类不能被实例化,它们必须被扩展并且它们的方法必须被实现。抽象类描述一些抽象对象(汽车、人等),而不仅仅是行为。记住:
- 抽象类必须用abstract关键字声明。
- 可以有抽象方法和非抽象方法。
- 无法创建抽象类的实例。
- 它可以有构造函数和静态方法。
- 它可以有最终方法来强制子类不更改方法体。
具有抽象方法的抽象类的示例: 在此示例中,
Bike是一个抽象类,仅包含一个抽象方法 run。它的实现是由
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
()方法。
abstract class Bike{
Bike(){System.out.println("bike is created");}
abstract void run();
void changeGear(){System.out.println("gear changed");}
}
class Honda extends Bike{
void run(){System.out.println("running safely..");}
}
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 Drawable{
void draw();
}
class Rectangle implements Drawable{
public void draw(){System.out.println("drawing rectangle");}
}
class Circle implements Drawable{
public void draw(){System.out.println("drawing circle");}
}
class TestInterface1{
public static void main(String args[]){
Drawable d=new Circle();
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 中的类不支持多重继承,但通过接口可以,为什么? 正如继承部分中已经解释的那样,由于不明确,类示例中不支持多重继承。然而,它得到了接口示例的支持,因为它没有歧义。原因是它的实现是由实现类提供的。
GO TO FULL VERSION