《Java8实战》笔记(15):面向对象和函数式编程的混合-Java 8和Scala的比较

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

while( n <= 6 ){

println(s"Hello ${n} bottles of beer")

n += 1

}

}

}

输出

Hello 2 bottles of beer

Hello 3 bottles of beer

Hello 4 bottles of beer

Hello 5 bottles of beer

Hello 6 bottles of beer

函数式Scala

Java 8以更加函数式的方式实现

public class Foo {

public static void main(String[] args) {

IntStream.rangeClosed(2, 6)

.forEach(n -> System.out.println("Hello " + n +

" bottles of beer"));

}

}

Scala来实现

object Beer {

def main(args: Array[String]){

2 to 6 foreach { n => println(s"Hello ${n} bottles of beer") }

}

}

基础数据结构:List、Set、Map、Tuple、Stream以及Option

创建集合

在Scala中创建集合是非常简单的

val authorsToAge = Map(“Raoul” -> 23, “Mario” -> 40, “Alan” -> 53)

Java中那样手工添加每一个元素:

Map<String, Integer> authorsToAge = new HashMap<>();

authorsToAge.put(“Raoul”, 23);

authorsToAge.put(“Mario”, 40);

authorsToAge.put(“Alan”, 53);

Scala轻松地创建List(一种单向链表)或者Set(不带冗余数据的集合)

val authors = List(“Raoul”, “Mario”, “Alan”)

val numbers = Set(1, 1, 2, 3, 5, 8)

Scala中,关键字val表明变量是只读的,并由此不能被赋值(就像Java中声明为final的变量一样)。而关键字var表明变量是可以读写的。

不可变与可变的比较

Scala的集合有一个重要的特质我们应该牢记在心,那就是我们之前创建的集合在默认情况下是只读的。这意味着它们从创建开始就不能修改。

更新一个Scala集合会生成一个新的集合

val numbers = Set(2, 5, 3);

val newNumbers = numbers + 8 //这里的操作符+会将8添加到Set中,创建并返回一个新的Set对象

println(newNumbers)

println(numbers)

Java中提供了多种方法创建不可修改的(unmodifiable)集合。下面的代码中,变量newNumbers是集合Set对象numbers的一个只读视图:

Set numbers = new HashSet<>();

Set newNumbers = Collections.unmodifiableSet(numbers);

这意味着你无法通过操作变量newNumbers向其中加入新的元素。不过,不可修改集合仅仅是对可变集合进行了一层封装。通过直接访问numbers变量,你还是能向其中加入元素。

与此相反,不可变(immutable)集合确保了该集合在任何时候都不会发生变化,无论有多少个变量同时指向它。

使用集合

val fileLines = Source.fromFile(“data.txt”).getLines.toList()

val linesLongUpper = fileLines.filter(l => l.length() > 10)

.map(l => l.toUpperCase())

元组

Java目前还不支持元组

Scala提供了名为元组字面量

val raoul = (“Raoul”, “+ 44 887007007”)

val alan = (“Alan”, “+44 883133700”)

Scala支持任意大小的元组

val book = (2014, “Java 8 in Action”, “Manning”)

val numbers = (42, 1337, 0, 3, 14)

你可以依据它们的位置,通过存取器(accessor) _1、_2(从1开始的一个序列)访问元组中的元素,比如:

println(book._1)

println(numbers._4)

Stream

Scala也提供了对应的数据结构,它采用延迟方式计算数据结构,名称也叫Stream!不过Scala中的Stream提供了更加丰富的功能,让Java中的Stream有些黯然失色。Scala中的Stream可以记录它曾经计算出的值,所以之前的元素可以随时进行访问。

除此之外,Stream还进行了索引,所以Stream中的元素可以像List那样通过索引访问。注意,这种抉择也附带着开销,由于需要存储这些额外的属性,和Java 8中的Stream比起来,Scala版本的Stream内存的使用效率变低了,因为Scala中的Stream需要能够回溯之前的元素,这意味着之前访问过的元素都需要在内存“记录下来”(即进行缓存)。

Option

Java8的Optional

public String getCarInsuranceName(Optional person, int minAge) {

return person.filter(p -> p.getAge() >= minAge)

.flatMap(Person::getCar)

.flatMap(Car::getInsurance)

.map(Insurance::getName)

.orElse(“Unknown”);

}

在Scala语言中,你可以使用Option使用Optional类似的方法实现该函数:

def getCarInsuranceName(person: Option[Person], minAge: Int) = person.filter(_.getAge() >= minAge)

.flatMap(_.getCar)

.flatMap(_.getInsurance)

.map(_.getName).getOrElse(“Unknown”)

函数


Scala中的一等函数

def isJavaMentioned(tweet: String) : Boolean = tweet.contains(“Java”)

def isShortTweet(tweet: String) : Boolean = tweet.length() < 20

Scala语言中,你可以直接传递这两个方法给内嵌的filter,如下所示

val tweets = List(

“I love the new features in Java 8”,

“How’s it going?”,

“An SQL query walks into a bar, sees two tables and says ‘Can I join you?’”

)

tweets.filter(isJavaMentioned).foreach(println)

tweets.filter(isShortTweet).foreach(println)

现在,让我们一起审视下内嵌方法filter的函数签名:

def filter[T](p: (T) => Boolean): List[T]

匿名函数和闭包

匿名函数

val isLongTweet : String => Boolean

= (tweet : String) => tweet.length() > 60

val isLongTweet : String => Boolean

= new Function1[String, Boolean] {

def apply(tweet: String): Boolean = tweet.length() > 60

}

isLongTweet.apply(“A very short tweet”)

如果用Java,你可以采用下面的方式:

Function<String, Boolean> isLongTweet = (String s) -> s.length() > 60;

boolean long = isLongTweet.apply(“A very short tweet”);

isLongTweet(“A very short tweet”)


闭包

闭包是一个函数实例,它可以不受限制地访问该函数的非本地变量。不过Java 8中的Lambda表达式自身带有一定的限制:它们不能修改定义Lambda表达式的函数中的本地变量值。这些变量必须隐式地声明为final。

Scala中的匿名函数可以取得自身的变量,但并非变量当前指向的变量值。

def main(args: Array[String]) {

var count = 0

val inc = () => count+=1

inc()

println(count)

inc()

println(count)

}

写在最后

学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!

最后再分享的一些BATJ等大厂20、21年的面试题,把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。

蚂蚁金服三面直击面试官的Redis三连,Redis面试复习大纲在手,不慌

Mybatis面试专题

蚂蚁金服三面直击面试官的Redis三连,Redis面试复习大纲在手,不慌

MySQL面试专题

蚂蚁金服三面直击面试官的Redis三连,Redis面试复习大纲在手,不慌

并发编程面试专题

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
在坚持!

最后再分享的一些BATJ等大厂20、21年的面试题,把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。

[外链图片转存中…(img-dh49sZGJ-1713429549382)]

Mybatis面试专题

[外链图片转存中…(img-TAo8lMfJ-1713429549382)]

MySQL面试专题

[外链图片转存中…(img-9DAWsHMe-1713429549383)]

并发编程面试专题

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-zAhDMcCM-1713429549384)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值