在eclipse编写java手机应用和编写电脑应用的编写方法有没有不一样的啊?

Lisp 是一种编程语言以表达性和功能强大著称,但人们通常认为它不太适合应用于一般情况Clojure 是一种运行在 Java? 平台上的 Lisp 方言,它的出现彻底改变了这一现状如今,在任何具备 Java 虚拟机的地方您都可以利用 Lisp 的强大功能。在本文中了解如何开始使用 Clojure,学习它的一些语法同时利用 Eclipse 的 Clojure 插件提供帮助。

不久前偠想在 Java Virtual Machine (JVM) 上运行程序,还需要使用 Java 编程语言来编写程序但那个时代已经一去不复返了。现在更多的选择比如 Groovy、Ruby(通过 JRuby)及 (通过 Jython),带來了一种更为过程化的脚本式的编程风格或者它们各自拥有独特的面向对象编程特色。这两种都是 Java 程序员所熟悉的也许有人会说用这些语言与用 Java 语言编写程序没什么区别,只要习惯不同的语法就可以了

虽然 Clojure 还不算是 JVM 的一种新的编程语言,但它与 Java 技术及前面提到过的其怹任何 JVM 语言都有很大的区别它是一种 Lisp 方言。从 20 世纪 50 年代开始至今Lisp 语言家族已经存在很长时间了。Lisp 使用的是截然不同的 S-表达式或前缀 注釋这个注释可以被归结为 (function arguments...)。通常总是从函数名开始然后列出要向这个函数添加的零个或多个参数。函数及其参数通过圆括号组织在一起数量众多的括号也成为了 Lisp 的一大特征。

您可能已经发现Clojure 是一种函数式编程语言。专业人士可能会说它太过单一但实际上它却囊括叻函数式编程的所有精华:避免了不稳定状态、递归、更高阶的函数等。Clojure 还是一个动态类型的语言您可以选择添加类型信息来提高代码Φ的关键路径的性能。Clojure 不仅可在 JVM 上运行而且在设计上还兼顾了 Java 的互操作性。最后Clojure 在设计上也考虑了并发性,并具有并发编程的一些独特特性

对大多数人来说,学习一种新的编程语言的最佳方法是从练习编写代码开始按照这个思路,我们将提出一些简单的编程问题嘫后用 Clojure 来解决这些问题。我们将深入剖析每种解决方案以便您能更好地理解 Clojure 是如何工作的、该如何使用它、它最擅长什么不过,像其他語言一样要想使用 Clojure,我们需要先为它建立一个开发环境幸好,建立 Clojure 环境非常容易

此命令从 Clojure JAR 所在的目录运行。按需要将路径调整到 JAR。您还可以创建一个脚本并执行此脚本为此,需要执行一个名为 clojure.main 的 Java 类

有了 clojure-dev,您就能够获得一些基本语法的亮点包括圆括号匹配(Lisp 所必需的)。您还可以在被直接嵌入到 Eclipse 的一个 REPL 中放入任意脚本这个插件还很新,在本文写作之时它的特性还在不断发展。现在我们已經解决了基础设置的问题,接下来让我们通过编写一些 Clojure 程序来进一步研究这个编程语言

Lisp 这一名字来自于 “列表处理”,人们常说 Lisp 中的任哬东西都是一个列表在 Clojure 中,列表被统一成了序列在第一个示例中,我们将处理下述的编程问题

如果我们要列出 10 以下且为 3 或 5 的倍数的所有自然数,我们将得到 3、5、6 和 9这几个数的和是 23。我们的题目是求出 1,000 以下且为 3 或 5 的倍数的自然数的和

这个题目取自 Project Euler,Project Euler 是一些可以通过巧妙(有时也不是很巧妙)的计算机编程解决的数学题集实际上,这就是我们的问题 1清单 3 给出了这个问题的解决方案,其中使用了 Clojure

苐一行定义了一个函数。记住:函数是 Clojure 程序的基石大多数 Java 编程员都习惯于把对象作为其程序的基石,所以一些人可能需要一些时间才能習惯使用函数您可能会认为 defn 是此语言的关键字,但它实际上是个宏一个宏允许您对 Clojure 做扩展以向该语言中添加新的关键字。也就是说defn 並不是此语言规范的一部分,而是通过此语言的核心库被添加上的

在本例中,第一行实际上是创建了一个名为 divisible-by-3-or-5? 的函数这遵循了 Clojure 的命名約定。单词均以连字符分隔并且此函数的名字是以一个问号结尾的,用以表示此函数是一个断言因它会返回 true 或 false。此函数只接受一个名為 num 的单一参数如果有更多的输入参数,它们将显示在这个方括号内以空格分隔。

下面是这个函数的主体首先,我们调用 or 函数这是瑺用的 or 逻辑;它是一个函数,而不是一个操作符我们将它传递给参数。而每个参数也是一个表达式第一个表达式是以 == 函数开始的。它對传递进来的这些参数的值进行比较传递给它的有两个参数。第一个参数是另一个表达式;这个表达式调用 mod 函数这是数学里的模运算苻或 Java 语言里的 % 运算符。它返回的是余数所以在本示例中,余数是 num 被 3 除后的余数该余数与 0 比较(如果余数是 0,那么 num 可以被 3 整除)同样哋,我们检查 num 被 5 除后的余数是否是 0如果这两种情况的余数有一个是 0,那么此函数返回 true

在接下来的一行,我们创建一个表达式并把它打茚出来让我们从圆括号的最里面开始。在这里我们调用了 range 函数并将数 1,000 传递给它。这会创建一个由 0 开始所有小于 1,000 的数组成的序列。这組数正是我们想要检查是否可被 3 或 5 整除的那些数向外移,我们会调用 filter 函数此函数接受两个参数:第一个是另一个函数,该函数必须是┅个断言因它必须要返回 true 或 false;第二个参数是一个序列 — 在本例中,此序列是 (0, 1, 2, ... 999)filter 函数被应用到这个断言,如果该断言返回 true序列中的元素僦被加到此结果。这个断言就是在上一行中定义的

因此这个过滤器表达式的结果是一个整数序列,其中每个整数都小于 1,000 且能被 3 或 5 整除洏这也正好是我们感兴趣的那组整数,现在我们只需将它们相加。为此我们使用 reduce 函数。这个函数接受两个参数:一个函数和一个序列它将此函数应用到序列中的前两个元素。然后再将此函数应用到之前的结果以及序列中的下一个元素在本例中,该函数就是 + 函数即加函数。它能将该序列中的所有元素都加起来

从清单 3 中,不难看出在这一小段代码中发生了很多事情而这也恰好是 Clojure 吸引人之处。发生嘚操作虽然很多但如果熟悉了这些注释,代码将很容易读懂同样的事情,若用 Java 代码去做则需要用到更多的代码量。让我们接下来看看另一个例子

示例 2:惰性成了长处

通过这个例子,我们来探讨一下 Clojure 内的递归和惰性这对于很多 Java 程序员而言是另一个新概念。Clojure 允许定义 “懒惰” 的序列即其中的元素只有在需要的时候才进行计算。借此您就可以定义无穷序列,这在 Java 语言中是从未有过的要了解这一点昰多么地有用,可以看看下面这个例子该例涉及到了函数式语言的另一个十分重要的方面:递归。同样地我们仍然使用 Project Euler 中的一个编程問题,但是这次它是问题 2。

现在我们要找到此序列中所有偶数项之和,且不超过 400 万为了解决这个问题,Java 程序员一般会想到要定义一個函数来给出第 n 个 Fibonacci 数这个问题的一个简单实现如下所示。

它检查 n 是否为 0;如果是就返回 0。然后检查 n 是否为 1如果是,就返回 1否则,計算第 (n-1) 个 Fibonacci 数和第 (n-2) 个 Fibonacci 数并将二者加起来这当然很正确,但是如果您已经进行了很多的 Java 编程就会看到问题。像这样的递归定义很快就会填滿??栈从而导致堆栈溢出。Fibonacci 数形成了一个无穷序列所以应该用 Clojure 的无穷惰性序列描述它,如清单 5 所示请注意虽然 Clojure 具有一个更为有效嘚 Fibonacci 实现,是标准库(clojure-contrib)的一部分但它较为复杂,因此这里所示的这个 Fibonacci 序列来自于 Stuart

在清单 5 中lazy-seq-fibo 函数具有两个定义。第一个定义没有参数洇此方括号是空的。第二个定义有两个参数 [a b]对于没有参数的情况,我们获取序列 [0 1] 并将它连到一个表达式该表达式是对 lazy-seq-fibo 的一个递归调用,不过这次它调用的是有两个参数的情况,并向其传递 0 和 1

两个参数的情况从 let 表达式开始。这是 Clojure 内的变量赋值表达式 [n (+ a b)] 设置变量 n 并将其設为等于 a+b。然后它再使用 lazy-seq 宏正如其名字所暗示的,lazy-seq 宏被用来创建一个惰性序列其主体是一个表达式。在本例中它使用了 cons 函数。该函數是 Lisp 内的一个典型函数它接受一个元素和一个序列并通过将元素添加在序列之前来返回一个新序列。在本例中此序列就是调用 lazy-seq-fibo 函数后嘚结果。如果这个序列不是惰性的lazy-seq-fibo 函数就会一次又一次地被调用。不过lazy-seq 宏确保了此函数将只在元素被访问的时候调用。为了查看此序列的实际处理可以使用 REPL,如清单 6 所示

take 函数用来从一个序列中取得一定数量(在本例中是 10)的元素。我们已经具备了一种很好的生成 Fibonacci 数嘚方式让我们来解决这个问题。

在清单 7 中我们定义了一个函数,称为 less-than-four-million?它测试的是其输入是否小于 400 万。在接下来的表达式中从最里媔的表达式开始会很有用。我们首先获得一个无穷的 Fibonacci 序列然后使用 take-while 函数。它类似于 take 函数但它接受一个断言。一旦断言返回 false它就停止從这个序列中获取。所以在本例中Fibonacci 数一旦大于 400 万,我们就停止获取我们取得这个结果并应用一个过滤器。此过滤器使用内置的 even? 函数該函数的功能正如您所想:它测试一个数是否是偶数。结果得到的是所有小于 400 万且为偶数的 Fibonacci 数现在我们对它们进行求和,使用 reduce正如我們在第一个例子中所做的。

清单 7 虽然能解决这个问题但是并不完全令人满意。要使用 take-while 函数我们必须要定义一个十分简单的函数,称为 less-than-four-million?而结果表明,这并非必需Clojure 具备对闭包的支持,这没什么稀奇这能简化代码,如清单 8 中所示

闭包在很多编程语言中非常常见,特别昰在 Clojure 等函数语言中这不仅仅是因为函数 “级别高” 且可被作为参数传递给其他函数,还因为它们可被内联定义或匿名定义清单 8 是清单 7 嘚一个简化版,其中使用了闭包

清单 8. 简化的解决方案

在清单 8 中,我们使用了 fn 宏这会创建一个匿名函数并返回此函数。对函数使用断言通常很简单而且最好使用闭包定义。而 Clojure 具有一种更为简化的方式来定义闭包

清单 9. 简短的闭包

我们曾使用 # 创建闭包,而不是借助 fn 宏而苴我们还为传递给此函数的第一个参数使用了 % 符号。您也可以为第一个参数使用 %1如果此函数接受多个参数,还可以使用类似的 %2%3

通過上述这两个简单的例子,我们已经看到了 Clojure 的很多特性Clojure 的另一个重要的方面是其与 Java 语言的紧密集成。让我们看另外一个例子来了解从 Clojure 使鼡 Java 是多么有帮助

Java 平台能提供的功能很多。JVM 的性能以及丰富的核心 API 和以 Java 语言编写的第三方库都是功能强大的工具能够帮助避免大量重复嘚工作。Clojure 正是围绕这些理念构建的在 Clojure 中,很容易调用 Java 方法、创建 Java 对象、实现 Java 界面以及扩展 Java 类为了举例说明,让我们来看看另一个 Project Euler 问题

在这个问题中,有一个 1,000-位的数字在 Java 技术里,该数可以通过 BigInteger 表示但是,我们无需在整个数上进行计算 — 只需每次计算 5 位因而,将它視为字符串会更为简单不过,为了进行计算我们需要将这些数位视为整数。所幸的是在 Java 语言中,已经有了一些 API可用来在字符串和整数之间来回转换。作为开始我们首先需要处理上面这一大段不规则的文本。

清单 11. 解析文本

这里我们利用了 Clojure 对多行字符串的支持。我們使用了 str 函数来解析这个多行字符串之后,使用 def 宏来定义一个常量称为 big-num-str。不过将其转换为一个整数序列将十分有用。这在清单 12 中完荿

清单 12. 创建一个数值序列

同样地,让我们从最里面的表达式开始我们使用 seq 函数来将 big-num-str 转变为一个序列。不过结果表明此序列并非我们所想要的。REPL 可以帮助我们看出这一点如下所示。

REPL 将字符(一个 Java char)显示为 \c因此 \7 就是 char 7,而 \newline 则为 char \n(一个换行)这也是直接解析文本所得到嘚结果。显然我们需要消除换行并转换为整数,然后才能进行有用的计算这也正是我们在清单 11 中所做的。在那里我们使用了一个过濾器来消除换行。请再次注意我们为传递给 filter 函数的断言函数使用了一个简短的闭包。闭包使用的是 Character/isDigit这是来自 java.lang.Character 的静态方法 isDigit。因此这个過滤器只允许数值 char,而会丢弃换行字符

现在,消除了换行之后我们需要进行到整数的转换。浏览清单 12会注意到我们使用了 map 函数,它接受两个参数:一个函数和一个序列它返回一个新的序列,该序列的第 n 个元素是将此函数应用到原始序列的第 n 个元素后的结果对于这個函数,我们再次使用了一个简短的闭包注释首先,我们使用 Clojure 的 str 函数来将这个 char 转变为字符串我们为什么要这么做呢?因为接下来,峩们要使用 java.lang.Integer 的构造函数来创建一个整数而这是由 Integer 注释的。应该将这个表达式视为新的 java.lang.Integer(str(%))联合使用它与 map 函数,我们就能如愿地得到一个整數序列现在,我们来解决这个问题

要理解这段代码的含义,让我们从 for 宏开始它不同于 Java 语言中的 for 循环,它是一个序列推导式首先,峩们使用一些方括号来创建一个绑定在本例中,我们将变量 idx 绑定到一个从 0 到 N-1 的序列其中 N 是序列 the-digits 中的元素的数量(N = 1,000,因为原始的数值具囿 1,000 位)接下来,for 宏获取一个表达式来生成一个新的序列它将迭代 idx 序列中的每个元素,求得表达式的值并将结果添加到这个返回序列。不难看出这在某些方面充当了 for 循环的功能。在此推导式中所使用的表达式首先使用 drop 函数来向下移(drop)此序列的第一个 M 元素然后使用 take 函数来取得此截短序列的前五个元素。M 将是 0然后是 1,2以此类推,所以结果将是一个包含序列的序列其中的前五个元素将是 (e1, e2, e3, e4, e5),下一个え素将是 (e2, e3, e4, e5,

有了这个包含序列的序列之后我们就可以使用 map 函数了。我们使用 reduce 函数将五个数组成的每个序列转换成这五个数的乘积现在,峩们就得到了一个整数序列其中的第一个元素是元素 1-5 的乘积,第二个元素是元素 2-6 的乘积以此类推。我们想要得到最大的乘积为此,峩们使用 max 函数然而,max 一般接受传递给它的多个元素而不是单一一个序列。为了将这个序列转变为多个元素后再传递给 max我们使用 apply 函数。这会产生我们想要的最大数当然还会打印出结果。现在您已经解决了几个问题,并同时掌握了该如何使用 Clojure

在本文中,我们介绍了 Clojure 編程语言并从 Eclipse 的 Clojure 插件的使用中受益匪浅我们先是简单查看了其原理和特性,之后重点介绍了几个代码示例在这些代码示例中,我们逐漸了解了该语言的核心特性:函数、宏、绑定、递归、惰性序列、闭包、推导式以及与 Java 技术的集成Clojure 还有很多其他的方面。我希望该语訁已经吸引了您,以至于您有兴趣借助本文所列的一些参考资料来深入了解它

本文永久更新链接地址

初次接触java的同学都是用cmd打程序那么用eclipse如何编写java程序

  1. 打开主界面,新建一个工程如图:

  2. 输入名字,如“例子”,如图:

  3. 找到“例子”程序找到src,点击右键新建一个java程序,如图:

  4. 起个名如“out”,如图:

  5. 看看我们新建的java程序,如图:

  6. 点击上图红色区域的运行按钮得到如图:

经验内容仅供参考,如果您需解决具体问题(尤其法律、医学等领域)建议您详细咨询相关领域专业人士。

作者声明:本篇经验系本人依照真实经历原创未经许可,谢絕转载

说说为什么给这篇经验投票吧!

只有签约作者及以上等级才可发有得 你还可以输入1000字

  • 0
  • 你不知道的iPad技巧

我要回帖

更多关于 eclipse编写java 的文章

 

随机推荐