函数式编程java
A. java lambda表达式是什么
lambda表达式是JAVA8中提供的一种新的特性,它支持JAVA也能进行简单的“函数式编程”。它是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。
函数式接口:
这个是理解Lambda表达式的重点,也是产生lambda表达式的“母体”,这里我们引用一个比较容易理解的说法:函数式接口是 一个只有一个抽象方法(不包含object中的方法)的接口。
这个需要说明一点,就是在Java中任何一个对象都来自Object 所有接口中自然会继承自Object中的方法,但在判断是否是函数式接口的时候要排除Object中的方法。
B. java函数式编程是炫技编程吗
函数式编程(Functional Programming)是一种编程风格,它是相对于指令式编程风格而言的,常见的面向对象编程就是指令式编程风格。
指令式编程是面向计算机硬件的抽象,有变量(对应着存储单元),赋值语句(获取、存储指令),表达式(内存引用和算术运算)和控制语句(跳转语句)。
而函数式编程是面向数学的抽象,将计算描述为一种表达式求值。这里的函数实际就是数学中的函数,即自变量到因变量的映射。也就是说,一个函数的值仅决定于函数参数的值,不依赖其他状态。
函数式编程是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。
在函数式语言当中,函数作为一等公民,可以在任何地方定义,在函数内或函数外,可以作为函数的参数或返回值,可以对函数进行组合,也可以将函数赋值给变量。严格意义上的函数式编程意味着不适用可变的变量,赋值,循环和其他命令式控制结构进行编程。
函数式编程风格带来的好处是:
函数式编程使用不可变对象作为变量,不会修改变量的值,而是返回一个新的值,如此这样,更容易理清头绪,使得单元测试和调试更加容易;
可以很自由地传递不可变对象,但对于可变对象来说,传递给其他代码之前,需要先建造一个以防万一的副本;
一旦不可变对象完成构造以后,就不会有线程因为并发访问而破坏对象内部状态,因为根本没有线程可以改变不可变对象的状态;
不可变对象让哈希表键值更安全,所以哈希表键要求必须是不可变对象,否则使用可变对象,如果对象状态发生变化,那么在哈希表中就找不到这个对象了;
具体到编程语言,Scala(静态语言)和Python(动态语言)都能比较的支持函数式编程风格,但是它们都不是纯函数式的,也就是说它们同时支持指令式风格和函数式风格。而Java基本是指令式风格,但自从Java8引入lambda表达式以后也开始部分支持函数式风格。函数式编程最典型的是诸如map, flatMap, rece, filter等函数,它们的特点是支持某个函数作为上面这些函数的参数
C. Java8的函数式编程怎么样
使用函数式代码的好处:
减少了可变量(Immutable Variable)的声明
能够更好的利用并行(Parallelism)
代码更加简洁和可读
函数式接口
函数式接口就是仅声明了一个方法的接口,比如我们熟悉的Runnable,Callable,Comparable等都可以作为函数式接口。当然,在Java 8中,新添加了一类函数式接口,如Function,Predicate,Consumer,Supplier等。
D. java开发的缺点有哪些
我认为Java语言的10大问题是:x0dx0a1、缺少闭包(closure):我想这个不需要解释了。函数式编程已经存在几十年了,但最近几年,它们获得了越来越多的关注,最主要的原因,是它可以自然地编写并行程序。我部分的同意Joshua Bloch强调在Java中引入闭包的问题需要再想一想(BGGA提议的方式真的很糟),至少闭包的缺失,使得在Java中做任何真正的函数式编程都是不可能的。x0dx0a2、缺少一等函数:这个问题与前一个有些关联,但我认为它更糟糕。在Java里,要达到类似效果的唯一方式,是使用着名的、丑陋悲惨的单方法匿名内部类,但这看上去的确是一个拙劣的方法。甚至在C#中,也通过代理机制,提供了一个更好的实现。x0dx0a3、原生类型(Primitive types):如果在Java中一切皆对象,那是多么完美啊,但他们偏偏不这样设计。因而,这一点导致了一些问题,比如,不能把一个int放到集合(Collection)里,这个在Java5中通过自动装箱特性得到了解决(下面会提到)。它也造成了传值与传引用上的困扰,原生类型数据是通过值传给方法的(复制一份拷贝,然后传给函数),而真正的对象是通过传递(译注:其实是复制对象地址再传递,因此应该也是传值方式,只是由于函数内部可通过这个对象地址访问对象,因此效果上类似传引用)。x0dx0a4、自动装箱(Autoboxing)和自动拆箱(autounboxing):这个特性是为了解决因原生类型的存在所导致的问题,在Java5引入的。它允许静默地转换原生类型到相应的对象,但这常常导致其它的问题。比如Integer可以为null,但int不能,因此这时JVM只能抛出一个难以调试的空指针异常(NullPointerException)。此外,它还可能导致其它奇怪的行为,就像下面的例子,我们就很难理解,变量test为什么是false:x0dx0aIntger a = new Integer(1024);x0dx0aIntger b = new Integer(1024);x0dx0aboolean test = a < b || a == b || a > b;x0dx0a5、缺少范型具类化:范型是Java5引入的一个很酷的特征,但是为了保持与旧版本Java的兼容性,导致缺失某些重要的特性,尤其是不能在运行时反省范型的类型。例如,你有一个方法,接受List参数,如果传进来一个List,你却不能知道运行里该范型的确切类型。同理,你也不能创建范型数组。这意味着,尽管下面的代码看起来很自然,但却不编译不了:x0dx0aList[] listsOfStrings = new List[3];x0dx0a6、不可避免的范型警告:你有发现过自己陷入不可能去掉的关于范型的警告么?如果你像我一样大量使用范型,我打赌你碰到过。事实上,是这个问题的规模化症状,让他们认为需要引入一个特定的注解(@SuppressWarnings("unchecked"))来处理这种情况,我觉得,范型应该可能被设计的更好。x0dx0a7、不能传void给方法调用:我得承认,这种给方法传递void的需求,乍一看有些怪异。我喜欢DSL,当我实现自己的DSL库(lambdaj)的一个特定特性时,我不得不需要一个方法声明成这样的签名:void doSomething(Object parameter),这里为这个方法传进来的参数parameter,是另一个方法调用的结果,它唯一的目的,是注册调用(的对象)自身,以可以在以后执行它。让我吃惊的是,即使println方法返回void,看上去也并没有一个好理由,不允许我把代码写成这样,:x0dx0adoSomething(System.out.println("test"));x0dx0a8、没有原生的代理机制:代理是一种非常有效和应用广泛的模式,但Java提供的代理机制,只针对接口,而不是具体类。这是为什么象cblib这样提供这种机制的库,被如此多的主流框架,如Spring和Hibernate,采用的原因。此外,由于cglib通过运行时创建被代理类的子类来实现的,因此这些种方式有一个众所周知的限制——不能代理final类,比如String。x0dx0a9、差劲的Switch...case语句:Java规定,switch...case只能选择int和enum(Java5开始)。这一点如果跟更现代的语言如Scala相比,看起来简直太弱了。x0dx0a10、受检查异常(Checked exception):类似原生类型,受检查异常也已经成为Java的一个罪孽之源。它迫使程序员必须做下面两件极其糟糕讨厌的事情中的一个:让你的代码里充斥大量的、糟糕难读的、容易出错的try...catch语句,而这样做的最大意义,只是将捕获的异常,包装成运行时异常,然后再重新抛出;或者是让大量的抛出声明子句污染你的API,让接口缺少灵活性和可扩展性。x0dx0a真正的问题是,这里我提到的这几大主要问题,唯一的解决办法,是要做一个痛苦的决择,定义一套新的语言规范,放下当前版本的向后兼容性。我猜他们永远也不会这么做,虽然我相信,如果编写一个能够自动转换旧Java源码的程序,让它们与假设的新版本兼容,并不是很困难。最后,这就是我决定开始寻找一个更好的JVM兼容语言的原因。
E. java支持的编程范式
Java编程范式
1.命令式编程
核心内容就是:“用语句更改程序的状态”
大多数流行的编程语言都或多或少基于命令式编程发展而来,命令式语言最典型的实例就是C语言
2.面向对象编程
面向对象编程经常与命令式编程联系在一起,在实践当中,两者是可以共存的。Java就是这种协作的生动证明
面向对象基于四个基本原则:封装、继承、多态、抽象
3.声明式编程
与命令式编程相反,声明式编程它指定程序应该做什么,而不具体说明怎么做。
纯粹的声明式语言包括数据库查询语言(如SQL和Xpath)以及正则表达式。
与命令式编程语言相比,声明式编程语言更加抽象,它们并不模拟硬件结构,因此不会改变程序状态,而是将它们转换为新状态,并且更接近数学逻辑
通常,非命令是的编程范式都被认为属于声明式类别。
4.函数式编程
函数式编程是声明式编程的子范式,与命令式编程相反,函数式变成不会改变程序的内部状态。
在函数式编程术语中,函数类似于数学函数,函数的输出仅依赖于其参数,而不管程序的状态如何,完全不受函数式是何时执行的影响
函数式语言受欢迎的原因之一是它们可以轻松的在并行环境中运行,这与多线程不太一样,函数式语言支持并行的关键在于它们的基本原理:函数仅依赖与输入参数而不依赖于程序的状态。它们可以在任何地方运行,然后将多个并行执行的结果连接起来并进一步使用
F. Java函数式编程语言是什么
函数式编程语言的核心是它以处理数据的方式处理代码。这意味着函数应该是第一等级(First-class)的值,并且能够被赋值给变量,传递给函数等等。
事实上,很多函数式语言比这走得更远,将计算和算法看得比它们操作的数据更重要。其中有些语言想分离程序状态和函数(以一种看起来有点对立的方式,使用面向对象的语言,这通常会将它们联系得更紧密)。
Clojure编程语言就是一个这样的例子,尽管它运行于基于类的Java虚拟机,Clojure的本质是函数式语言,并且在高级语言源程序中不直接公布类和对象(尽管提供了与Java良好的互操作性)。