by JoianSUN 如鹏网 | Java | 20150705
主要内容:
- 计算机基础常识
- Java语言介绍
- Java 开发环境的搭建
- Eclipse 开发第一个程序
- Eclipse 个性配置与基本操作
数据
:图片、文字、音频等;处理
:对数据进行的收集、存储、分类、计算、传输等』计算机硬件是计算机软件运行的基础『物质』。
主要硬件:『CPU、主板、内存、显卡、显示屏等』
软件主要分为两大类:系统软件和应用软件
系统软件(操作系统) | 应用软件 |
---|---|
DOS(Disk Operating System) Windows Unix Linux Mac | 系统软件自带应用『类似计算器、记事本』 |
Android IOS WindowsPhone | 用户自安装应用『QQ、YY、LOL』 |
P.S.
1)、DOS系统是命令行方式操作系统,为了便于用户的操作,后来产生了图形化界面操作的操作系统,也就是Windows系统
2)、系统软件和应用软件都是用计算机语言编写出来的,计算机语言调用底层指令处理数据
1、什么是软件?
软件是一系列按照特定顺序组织的计算机数据和指令的集合。
P.S.
1)、数据就是指现实生活中的年龄、姓名等信息
2)、指令就是告诉计算机如何对数据进行处理
2、软件开发是什么?
借助开发工具与计算机编程语言制作软件
1、自然语言
人与人之间沟通交流的各种表达符号
2、计算机语言
人与计算机之间进行信息交流沟通的一种特殊语言『C\C++、C#、Java、Python、Object-C…』
软件的出现实现了人与计算机之间的更好的交互。
两种交互方式:
命令行界面(Command Line Interface CLI):通过控制台输入特定的指令,让计算机完成制定操作。需要记忆大量的指令,较为麻烦,像是早期的DOS系统
图形化界面(Graphical User Interface GUI):为了方便用户的简便操作,由CLI逐渐发展而来交互方式。简单直观,易于接受和上手操作,像是由DOS而来Windows系统
开源『Open Source』
,完全面向对象
,安全可靠,与平台『操作系统』无关
的编程语言。P.S.
Java是允许使用者将应用程序通过Internet从远端服务器传输到本地机上进行执行的一种语言。
1、J2SE(Java 2 Platform Standard Edition)标准版
是为开发普通桌面和商务应用程序提供的解决方案。该技术体系是其他两者的基础,可以完成的一些桌面应用程序的开发,比如Java版的扫雷。
2、J2EE(Java 2 Platform Enterprise Edition)企业版
是为开发企业环境下的应用程序提供的解决方案。该技术体系中包含的技术如Servlet、Jsp等,主要针对于Web应用程序开发。
3、J2ME(Java 2 Platform Micro Edition)小型版
是为开发电子消费产品和嵌入式设备提供的解决方案。该技术体系主要应用于小型电子消费类产品,如手机中的应用程序等。
P.S.
1)Java 5.0版本之后,三种架构技术分别更名为JAVASE、JAVAEE、JAVAME。
2)由于现在已经出现了Android、IOS、Windows Phone等手机操作系统,所以J2ME架构基本上已经不再使用了。目前流行的手机软件主要是基于这些最新的手机操作系统进行开发。
3)SUN公司已被Oracle公司收购。
Java语言的特点:简单性、解释性、面向对象、高性能、分布式长处理、多线程、动态、安全、体系结构中立、开源『Open Source』
、跨平台性
。
1、 开源『Open Source』:开放源代码
2、 什么是跨平台性?
通过Java语言编写的应用程序可以在不同的操作系统平台中运行。亦即可移植性
。
一次编写, 到处运行『Write Once, Run Anywhere』
P.S.
国内操作系统市场基本已被Windows彻底征服,但国外用户对于操作系统确实有更多的不同的选择项。因此,程序员开发软件的需要考虑到跨平台性,而Java语言就具备了跨平台性的特点。
3、跨平台性的原理是什么?
只要在需要运行Java应用程序的操作系统中,先安装一个Java虚拟机(JVM : Java Virtual Machine) 即可,由JVM来调用操作系统底层指令解析、执行Java程序,从而在该操作系统中运行。
因为有了JVM,所以同一个Java程序在各种不同的操作系统中都可以执行。这样就实现了Java程序的跨平台性,也就是说Java语言具有好的可移植性*。
P.S.
1)、明确:JAVA语言具有跨平台性,但是JVM不具有跨平台性,在不同的操作系统下具有不同版本的JVM。
2)、用C\C++语言编写的程序在Windows系统中可以直接运行,在Linux中则不可以。这是因为Windows系统使用C\C++语言编写的,Windows中内置了C\C++的解析器,所以C\C++可以直接在Windows系统中运行。但Java语言编写的程序如果要在Windows系统中运行,就需要在Windows系统中安装一套能够解析、执行Java程序的软件,也就是JVM( Java虚拟机 )。类似的,在Linux、Mac系统中执行Java语言编写的程序也需要安装各自的系统对应的应用。通过这种方式,就实现了Java语言“一次编译,到处运行”的跨平台性。JVM的作用就是搭建了Java语言编写的程序与操作系统之间的桥梁。
使用任何一门语言之前必须首先搭建环境。
1、 JRE(Java Runtime Environment:Java有运行时环境)
包括Java虚拟机(JVM:Java Virtual Machine)和Java程序所需的核心类库(Java Class Library)。如果想要运行一个开发好的Java程序,计算机中只需要安装JRE就可以了。
2、 JDK(Java Development Kit::Java开发工具包)
JDK提供给Java开发人员使用的,其中主要包含了Java的开发工具以及JRE。所以理论上,安装了JDK就不需要单独安装JRE了。其中的开发工具有编译工具(javac.exe)、打包工具(jar.exe)等。
简而言之:使用JDK开发完成的Java程序交给JRE执行,由JVM保证跨平台性
。
为什么JDK中包含一个JRE呢?
1)开发完成的Java程序,需要执行得出结果以保证程序的正确性。
2)最重要的是:JDK中的开发工具(如javac.exe、jar.exe等)其实都是Java语言编写的应用程序。为了放方便使用才打包成exe文件。如果没有JRE,那么开发工具是没有办法正常执行的。
总结:
JRE = JVM + 类库(Java Class Library)
JDK = JRE + Java开发工具
P.S.
由于SUN公司已经被Oracle公司收购,访问www.java.sun.com时会自动跳转到http://www.oracle.com/technetwork/java.index.html
官网下载示意图下载示意图:
(1)、访问www.oracle.com,点击Downloads下的JavaforDevelopers。
(2)、点击JDK下的DOWNLOAD按钮。
P.S.
8u45代表JDK8版本,45代表子版本,u是update(更新)的缩写。
(3)、在下载之前,首先需要接受JDK的许可证协议,然后再点击jdk-8u45-windows-i586.exe(32位)/jdk-8u45-windows-x64.exe(64位)进行下载。
P.S.
Windowsx86对应的是windows32位系统。
Windowsx64对应的是windows64位系统。
2、安装JDK
(1)、双击“jdk-6u21-windows-i586.exe”文件,点击“下一步”。
(2)、继续点击“下一步”。
默认安装目录为“C:\ProgramFiles(x86)\Java\jdk1.6.0_21\”,可以通过“更改”按钮对安装路径进行自定义至”:\Java\jdk1.6.0_21\” 路径下。
P.S.
安装路径中不要有中文或者特殊符号如空格等,否则后期开发中可能出现一些莫名其妙的错误。
(3)、继续点击“下一步”。
正在安装中…复制文件结束,安装JDK完毕。
(4)、接下来出现的对话框是询问是否安装JRE(Java运行环境),这是可选的,因为JDK中已经包含开发环境和运行环境(JRE)两部分。所以不需要安装,一般情况建议安装,也可以直接点击“取消”按钮。
P.S.
如果你只运行已有的Java程序而不要进行Java程序的开发,那么只需安装JRE即可(因为JRE的体积较小)
如果点击下一步:
(5)、点击“关闭”按钮,安装完毕。
P.S.
- 1)、JDK无需每次都安装,因为其本身就是绿色版本,可以直接存入U盘,在任何计算机上都可以直接使用。
- 2)、采用安装的方式使用JDK的好处在于其会在注册表中被注册,当JDK出现新版本,会自动更新
1、JDK安装目录下的bin(binary)文件夹是二进制文件所在的目录,其中的exe文件(都是使用java语言编写)都是开发Java程序所需要的命令文件。
P.S.
这些命令文件并非是图形化方式操作的(双击执行是无效的),而是命令行方式操作的命令文件,所以需要首先打开命令行窗口。
2、打开DOS命令行窗口有两种方式。
(1)、点击”开始”–>”运行”–>”输入’cmd’”–>按下’Enter’键。『直接使用快捷键’Win + R
‘』
(2)、点击”开始”–>”所有程序”–>”附件”–>”命令提示符”。
(3)、Win7之后,可以在任意文件夹下,使用Shift + 右键菜单
–> 点击”在此处打开命令窗口”。
3、进入到JDK安装目录下的bin目录。
4、输入javac(.exe可以不写),出现如下显示,说明JDK已经可以使用了。
常用的DOS命令
dir(directory):列出当前目录下所有的文件以及文件夹
md(make directory):创建目录
rd(remove directory):删除目录
cd(change directory):进入指定目录
cd .. :退回到上一级目录
cd \ :退回到根目录
del (delete):删除文件或文件夹
cls:清空屏幕内容
exit:退出DOS命令
13个示例轻松掌握常用DOS命令:
(1)、查看D盘下的目录
(2)、查看指定文件夹下的目录使用cd 文件夹名称的时候,输入到一定长度,可是使用Tab
键快速补全。
当输入到“Baidu”的时候,使用Tab
键补全,获取的是以”Baidu”开头的所有文件夹的第一个(按照字符编码顺序列出所有”Baidu”开头的文件夹)
(3)、通过通配符的方式更方便的进入指定文件夹
P.S.
“cd Baidu*”命令中的”*”是一种通配符『
代表一个或多个字符
』,如果当前目录中有多个文件夹名称都能匹配,那么会自动进入第一个名称匹配的文件夹中。
(4)、退回上一级目录
(5)、退回到根目录
(6)、在D盘根目录下创建新的文件夹。
P.S.
早期操作计算机用DOS操作,因为需要记忆太多的命令,不利于普及,后期发展成图形界面,通过鼠标点击界面的形式操作计算机,底层实际上运行的依然是DOS命令。
(7)、删除文件夹
(8)、新建文件夹,并在此文件夹下创建一个文件,由于此文件夹非空,删除文件夹失败。『Windows 防止误删除采用的机制』
(9)、只有将文件夹下的所有文件和文件夹删除,才能删除该文件夹
P.S.
del *
或del *.*
命令表示删除当前目录下的所有文件。- Windows系统删除文件是从内向外删,文件夹内部的文件如果没有完全删除,文件夹删除必定会失败。
- 使用
rd /s
『提示是否确认删除』或rd /q /s
『不提示直接删除』。
(10)、输入help命令,可以查询所有命令功能
(11)、输入help命令,查询指定命令功能
(12)、输入cls命令,可以清空当前屏幕内容
(13)、输入exit命令,退出命令行工具!
之前在使用的时候,必须保证已经编写的.java
文件必须和javac.exe
在同一个目录下才可以正常的编译,这将会导致bin
文件夹越来越乱,给bin
目录下的文件内容带来了误删除的隐患。
为了能够在DOS命令行窗口中,在任何目录下都可以执行javac命令,就需要将javac.exe命令文件所在目录放在path环境变量中。
原理:
在DOS命令提示符窗口中输入某一个命令后,Windows系统会首先在当前目录下.
查找是否有命令可以执行。如果没有,Windows系统就会在path环境变量路径中查找。如果查找到,就会执行该命令。如果还没有找到,那么就会提示如下信息。
1、如何配置环境变量
(1)、右击“计算机”–>“属性”。
(2)、点击“高级系统配置”–>“高级”选项卡–>“环境变量”
(3)、将javac命令文件所在目录的路径放入path路径中,使用英文”;”分割。
P.S.
- 1)、一定要将javac命令文件所在目录的路径放入path环境变量的开头。否则,如果计算机上以前已经安装了其他版本的JDK并且也已经配置了path环境变量,那么先执行的javac命令就是以前的JDK安装目录下的javac命令。因为windows系统是按照path路径从头向后搜索各个目录的。
- 2)、环境变量中的各个路径之间一定要以分号进行分隔。
- 3)、设置path环境变量的时候千万不要删除掉原来的内容。否则,很多程序将无法运行。
(4)、点击确定。然后,一定要新开一个新的DOS命令行窗口,再输入javac命令,如果出现如下显示,说明path环境变量配置成功。
P.S.
如果一台计算机上安装了多个版本的JDK,通过javac-version可以确定当前使用的JDK版本。
2、环境变量配置技巧
(1)、新创建一个环境变量JAVA_HOME记录jdk安装目录的路径
(2)、在path环境变量中通过“%%”动态的获取JAVA_HOME的值即可
通过这种方式,如果JDK安装目录改变了,那么只需要修改JAVA_HOME环境变量即可,而不用再修改path环境变量。
P.S.
%JAVA_HOME% 表示动态获取名称为JAVA_HOME环境变量的值。
3、环境变量临时配置方式
如果在别人的计算机上进行Java程序的开发,设置path这样的系统环境变量就不太好,那么就可以采用设置临时环境变量的方式(通过DOS命令中set命令完成)。
(1)、用set命令查看本机的所有环境变量的信息。
(2)、用set命令(”set 变量名”)查看具体某一个环境变量的值。
(3)、用set命令(”set 变量名=”)清空一个环境变量的值。
(4)、用set命令(”set变量名=具体值”)给指定环境变量定义具体值。
(5)、想要在原有环境变量值基础上添加新值。
首先,通过“%变量名%”操作符获取到原有环境变量的值。然后,追加上新值,再赋值给该变量名即可
P.S.
临时配置环境变量的方式只在当前DOS命令行窗口有效。窗口关闭,配置即消失。
『开发工具编写好的Java源代码,由javac.exe进行编译,得到的.class字节码文件,交由java.exe解释执行,输出到Console控制台』
(1)、使用Win + R
,输入notepad
,调用记事本,输入以下代码:
class Demo
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
P.S.
1)HelloWorld:代表学习计算机语言的第一个入门小程序。现在泛指接触任何新事物的第一步。
2)class:是java中的关键字,用于定义类,java语言的程序代码都需要定义在类中。
3)关键字:被java语言赋予了特殊含义的单词,高级记事本中具有高亮显示『class、public、static、void』。
4)Demo:为了方便使用这个类,给类自定义的类名。
5){ }
:定义该类中代码的范围。
6)main方法的作用在于保证一个类可以独立运行,因为它是程序的入口。
7)System.out.print();语句用于告诉系统输出打印数据,可以将括号中的内容打印在控制台上。通过该语句可以直接在控制台看到jvm运行java程序后的结果
另请注意:
1)、
写代码,阅读性第一,功能性第二,一定要注意写代码的格式
!
2)、源文件名和类名可以不一致,但当class前有修饰符public时,则必须一致
。
————————————————————————————-自行验证
(2)、通过javac命令对该java文件进行编译。
① 有了java源文件,将其编译成JVM可以识别的文件。
② 在该源文件目录下,通过javac编译工具对Demo.java文件进行编译。
③ 如果程序没有错误,没有任何提示,就会在当前目录下出现一个Demo.class文件,该文件称为字节码文件,也就是可以执行的java的程序。
(3)、通过java命令对生成的class文件进行运行。
P.S.
使用java命令运行class文件,没有必要加上.class文件后缀
(4)、javac命令的作用是对java程序进行语法性检查,一旦出错,就会打印出错误信息。
由于System.out.println("hellojava")语句后面缺少分号,所以报错。根据报错的行数,找到错误的地方,进行修改。然后重编编译,运行。
(5)、java命令可以启动JVM,然后找到相应的class文件,再寻找程序入口,也就是main方法,然后调用该方法执行java程序。
找不到文件
错误可能原因:
1)文件名写错。
2)类文件不在当前路径下或者不在classpath(后面会将讲到)指定路径下。
3)后缀名问题。
“ 后缀名问题”查找及解决方案如下:
点击“工具”–>“文件夹选项”–>点击“查看”选项卡,并且勾选掉“隐藏已知文件类型的扩展名”。
然后就可以看到文件真正的后缀名为txt,所以找不到Demo.java文件。只需将修改后缀名为 “.java”,再重新编译、运行即可。
由于可能频繁执行多个class文件,并且多个class文件可能存储在不同的目录下,那么每次都在命令提示符窗口中切换目录会相当的麻烦。
classpath环境变量的作用类似于path环境变量,但是它的作用在于告诉JVM去哪里找到class文件。
JVM查找类文件的顺序:
示例:
1)、 在C盘根目录下新创建一个文件夹,命名为myclass,将C:\code目录下的Demo.class文件复制到此文件夹下。
copy srcDirectory destDirectory;
2)、 将C:\code文件夹中的源文件Demo.java修改为在控制台中打印 “你好,世界”,重新编译,生成Demo.class。
3)、如果想要执行C盘根目录下myclass文件夹中的Demo.class,又不想切换目录,由于JVM会先在classpath环境变量值的目录中查找要运行的类文件,可以通过设置环境变量classpath为“c:\myclass”实现。
set classpath=C:\myclass
示例:
1)、 删除C:\myclass目录下的Demo.class。
del C:\myclass\Demo.class
2)、 在C:\code目录下运行Demo.class文件,报错。
这是因为classpath环境变量已经被赋值,所以即使在 C:\code目录下存在Demo.class文件,JVM也根本不会去查找。
3)、classpath环境变量值的结尾处如果没有分号,那么JVM在classpath目录下没有找到要指定的类文件,也不会在当前目录下查找。即使当前目录下有,也不会运行。
4)、classpath环境变量值的结尾处如果加上分号,那么JVM在classpath目录下没有找到要指定的类文件,会在当前目录下再查找一次.
示例:
为环境变量classpath赋值后加上 “;” 分号,然后在C:\code目录下运行Demo.class文件,由下图可见,运行成功。
P.S.
- 建议配置classpath环境变量时,值的结尾处不要加分号,如果需要访问当前目录可以用“.”(代表当前目录)表示,这样可读性更好一些。
set classpath=.;%classpath%
- 1)、中文字体太小:窗口(Window)→首选项(Preferences)→常规(General)→外观(Appearance)→颜色和字体(Colors and Font)→基本(Basic)→双击“文本字体(Text Font)”在弹出窗选择“
Courier New
”。
- 2)、我喜欢大括号在同一行:首选项→Java→代码样式(CodeStyle)→格式化程序→编辑(Edit)→花括号(braces),都选“下一行”。写一个名字保存。
- 3)、配置项目的Java编译器版本:项目右键→属性→Java编译器(Compiler)→启用特定于项目的设置,选择相应版本,建议选择1.7以上,后续讲课也默认1.7。
- 4)、配置java的源代码,方便研究java类库源码、文档:首选项→Java→已安装的JRE→双击JRE→展开rt.jar→源代码链接,选择JDK中的src.zip。
- 5)、快捷键:
Ctrl+shift+F
格式化代码(如果没反应可能是和别的软件热键冲突,比如搜狗拼音,在输入法条中点击右键“设置属性”→“按键”→“系统功能快捷键”,看到了吗,把所有都取消吧);Alt+/
智能提示;Ctrl+鼠标
查看定义。
1)、切换工作空间的方法:退出重启,如果勾选了【将此值用作初始值并且不再询问】,则文件(File)→切换工作空间(switch workspace),从“工作空间”列表中选择(之前打开过的)或者浏览选择工作空间根目录(包含.metadata)。
2)、如何导入别人的项目到工作空间中:包资源管理器(Package Explorer)→导入(Import)→常规(General)→现有项目到工作空间中(Existing Projects into Workspace),对话框中选中“选择根目录(Select Root Directory)”→【浏览】→选择项目的根目录(包含.project文件)或者WorkSpace,选择要导入的项目即可。
主要内容涉及到的是:
- Java语言基础由关键字、标识符、注释、常量和变量、运算符、语句、方法和数组等组成。
定义:被Java语言赋予特定含义的单词。
特点:组成关键字的字符全部是小写的。
注意:const和goto作为保留字,暂时不可使用。可能在JDK更高的版本中,提升为关键字
// 蓝色字体就是关键字
public class Demo
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
P.S.
1、所有的关键字都不需要记忆,在后期的学习中会慢慢的掌握的
2、类名的首字母要大些,这是Java命名规范之一
3、写代码一定要注意代码规范,注重代码的阅读性
4、命名时,要做到见名知意,例如Abc就不是友好,Demo则可以
定义:程序中自定义的一些名称。类、方法、接口、变量等起名字的字符序列。
组成:26个大小写字母、0~9数字、_和$
_
和$
之外的特殊字符P.S.
1)、Java中严格区分大小写,例如:Demo和demo是不同的
2)、在起名字时,尽量做到见名知意,提高代码的阅读性
3)、公司中经常使用_
代表某一类名称,例如:_temp。通过$
分割主名称和子名称,例如:TrafficLamp$Red。
(1)、 包名命名规范
『包:相当于是Windows下的文件夹,用于解决相同类名问题』
包名必须均为小写。包名需要使用英文说明包内代码功能,最好不要采用拼音。
(2)、类名命名规范
Java类名称必须以大写字母开头,可以使用2-4个英文单词(尽量不要用缩写)组成每个单词的首字母大写。文件名称必须能说明文件内代码功能。
(3)、方法名命名规范
(4)、变量名命名规范
(5)、常量名命名规范
常量名也应当有一定的意义,常量名字母全部大写。如果是由多个单词构成,可以用下划线隔开
定义:由于注解说明解释程序的文字。
特点:提高了代码的阅读性。
(1)、单行注释
格式:
// 说明文字
(2)、多行注释
格式:
/*
* 说明文字
*/
(3)、文档注释
『Java特有』
格式:
/**
* 说明文字
* @author JoianSUN
*/
示例:
/**
* 我的 Hello World 程序。
* @author JoianSun
*/
class Demo
{
/*
* 主函数,是程序的入口。
* 它的出现可以保证程序的独立运行。
*/
public static void main(String[] args)
{
// 输出语句用于将括号内的数据打印到控制台。
System.out.println("Hello World");
}
}
P.S.
1)、对于单行和多行注释,被注释的文字,不会被JVM(java虚拟机)解释执行。所以,即使添加再多的注释,编译后生成的class文件占用硬盘字节多少不变。2)、对于文档注释,是java特有的注释,其中注释内容可以被JDK提供的工具javadoc所解析,生成一套以网页文件形式体现的该程序的说明文档。
3)、注释是一个程序员必须要具有的良好编程习惯。初学者编写程序必须养成习惯:先写注释再写代码。
4)、将自己的思想通过注释先整理出来,再用代码去体现,因为代码仅仅是思想的一种体现形式而已。
5)、单行注释可以嵌套单行注释,单行注释可以嵌套多行注释,多行注释可以嵌套单行注释。但是,多行注释不能嵌套多行注释,因为多行注释的开头会和被嵌套的多行注释的结尾配对,导致后面的注释失效。
6)、可以使用注释对代码中的错误进行定位。
方法:当程序运行报错时,将某些代码注释掉,然后重新编译,运行。如果程序不再报错,那么说明注释掉的部分代码中包含错误代码。
定义:程序执行过程中其值保持不变。
1、字面值常量:
- 1)、整数常量:所有整数。
- 2)、小数常量:所有小数。
- 3)、布尔(boolean)型常量:只有两个数值,true、false。
- 4)、字符常量:将一个数字字母或者符号用单引号(’’)标识,如:’a’。
- 5)、字符串常量:将一个或者多个字符用双引号(“”)标识,如:”helloworld”、”a”、”“(空字符串)。
- 6)、null常量:只有一个数值就是:null。
2、自定义常量(final关键字时讲解)
对于整数,有四种表现形式:
任何数据在计算机中都是以二进制的形式存在的,二进制早期由电信号开关演变而来。一个整数在内存中一样也是二进制的,但是使用一大串的1或者0组成的数值进行使用很麻烦。所以就想把一大串缩短点,将二进制中的三位用一位表示。这三位可以取到的最大值就是7,超过7就进位了,这就是八进制。但是对于过长的二进制变成八进制还是较长,所以出现的用4个二进制位表示一位的情况,四个二进制位最大是15,这就是十六进制。
规律:进制越大,表现形式越短。
P.S.
- 1Byte=8bit
- 1KiB=1024Byte
- 1MiB=1024KiB
- 1GiB=1024MiB
(1)、十进制转二进制
原理:对十进制数进行除2运算。
示例:求十进制数6的二进制数。
6/2=3余0
3/2=1余1
1/2=0余1
故,6(十进制)=110(二进制)。
(2)、二进制转十进制
原理:二进制乘以2的过程。
示例:求二进制数110的十进制数。
110= 0*20 + 1*21 + 1*22 = 0 + 2 + 4 = 6
附:括号中的数值代表次方。
(3)、十进制转八进制
原理:八进制,其实就是二进制位,3个二进制位,1个八进制位。
示例:求十进制数43的八进制数。
十进制43
二进制101011
三位分割000-101-011
八进制053
因此,43(十进制)=101011(二进制)=053(八进制)。
(4)、十进制转十六进制
原理:十六进制,其实就是二进制位,4个二进制位,1个十六进制位。
示例:求十进制数43的十六进制数。
十进制43
二进制101011
四位分割0010-1011
十六进制2(2)11(B)
因此,43(十进制)=101011(二进制)=0x2B(十六进制)
原理:负数的二进制表现形式就是对应的正数二进制取反加1。
示例:求-6的二进制表现形式,其实就是对应的正数6的二进制取反加1。
6
00000110
取反:11111001
加 1:00000001
——————–
11111010
P.S. 负数的二进制最高位永远是1。
定义:内存中的一个存储区域,该区域有自己的名称(变量名)和类型(数据类型),该区域的数据 可以在同一类型范围内不断变化。
特点:变量其实就是将不确定的数据进行存储,也就是需要在内存中开辟一个空间。
为什么要定义变量?
用来不断存放同一类型的常量,并可以重复使用。
定义变量的格式: 数据类型 变量名 = 初始值 ;
例如:byte b = 3;
P.S.
1)、格式是固定不变的,记住格式,以不变应万变
2)、变量的作用域(一对 { } 之间有效)
3)、变量只能存放某一种类型的数据
Java语言是强类型语言,对于每一种数据都定义了明确的具体的数据类型。在内存中分配额了不同大小的内存空间:
类型 | 字节数 |
---|---|
byte | 1 |
short | 2 |
int | 4 |
long | 8 |
float | 4 |
double | 8 |
char | 2 |
boolean | 1 |
Java语言的数据类型包括8种基本类型、3种引用类型。
P.S.
1)、整数默认类型:int类型; 小数类型默认:double类型 【很重要】
2)、double类型的小数值精度比float类型的小数更高。
错误示例1:
class VarDemo
{
public static void main(String[] args)
{
byte b = 3;
byte b = 8;
}
}
运行结果:“错误:已在方法中 main(String[] ) 中定义了变量b”
错误原因:同一个作用域中,同一个变量名只可以定义一次。
错误示例2:
class VarDemo
{
public static void main(String[] args)
{
long l = 123456789123;
System.out.println(l);
}
}
运行结果: “错误: 过大的整数:123456789123”
错误原因:由于整数类型默认是int
类型,如果超过了int
类型的范围,那么就会报错。即使是赋给long
类型的变量,但是由于后面的常量已经超出了int
的范围,同样导致错误。
解决方案:在数值后面加上一个L或l
(建议使用'L'
,可识别度 更高),就可以让编译器知道后面的常量是long类型的。
long l = 123456789123L;
错误示例3:
class VarDemo
{
public static void main(String[] args)
{
float f = 3.14;
System.out.println(f);
}
}
运行结果:“错误:不兼容的类型:从double转换到float可能会有损失”
错误原因:由于小数类型默认是double
(8 byte)类型,赋值给float
(4 byte)类型的变量,可能会损失精度,所以编译通不过。
解决方案:在数值后面加上一个F或f
(建议使用'F'
)让编译器知道后面的常量是float
类型
float f = 3.14F;
错误示例4:
class VarDemo
{
public static void main(String[] args)
{
int y;
System.out.println(y);
}
}
运行结果:“错误:可能尚未初始化变量y”
错误原因:变量需要必须先初始化,才可以使用
错误示例5:
class VarDemo
{
public static void main(String[] args)
{
int y = 1;
}
System.out.println(y);
}
运行结果:“错误:需要标识符”
错误原因:变量在其作用域{ }
之内才有效,可以使用。System.out.println(y);
已经超出了 变量y 的作用域,所以 此处的 y 是没有定义的。需要定义标识符 y 。
错误示例6:
class VarDemo
{
public static void main(String[] args)
{
char ch = 'a';
System.out.println(ch);
}
}
运行结果:“错误:非法标识符:’\uff1b’”。
错误原因:编写程序时,不能使用中文符号。 char ch = 'a';
中的’;’ 是中文下的分号。
类型转换在开发中也很常用,简单来说就是类型之间相互的转化,类型转换共分两种,自动类型转换『隐式类型转换』和强制类型转换『显示类型转换』。
(1)、自动类型转换『隐式类型转换』
定义:自动类型转换就是不需要我们手动对类型来进行强制转换。从小到大的转换
byte,short,char–>
int
–>long–>float–>double
byte,short,char三者之间不进行任何转换,运算时,先转换为 int 再运算
示例:
class VarDemo
{
public static void main(String[] args)
{
int x = 3;
byte b = 5;
x = x + b;
System.out.println(x);
}
}
运行结果: 8
说明:int类型的变量占4个字节,当byte类型的变量与其相加的时候,首先会将byte类型的变量自动转化为4个字节的int类型,然后再进行加法操作。
(2)、强制类型转换『显示类型转换』
定义:强制类型转换需要把类型进行手动转换,否则无法正常使用。是一种从大到小的转换
示例:
class VarDemo
{
public static void main(String[] args)
{
byte b = 3;
b = b + 200;
System.out.println(b);
}
}
运行结果:“错误:不兼容的类型:从int转换成byte可能会有损失”
错误原因:当byte类型的变量提升为int类型和int类型的常量200进行相加后,结果依然是int类型,再赋值给byte类型,当然会出现损失精度的错误。
解决方法:进行强制类型转换,也就是将占4个字节的int类型值,再强硬存储到占1个字节的byte变量中。
代码如下:
b = (byte)(b + 200);
运行结果: -53
说明:结果为-53的原因是,200+3结果是int类型的203,也就是二进制(四个字节)的 00000000 000000000 00000000 11001011,截取成占1个字节空间的byte类型的二进制也就是11001011。由于首位为1,所以是负数,转换为原码:除符号位外,其余部分取反加1,得1,0110101,原值是 -(00110101)即-53。
P.S.
明确:只有数值类型才能进行四则运算,非数值类型不可以。
示例:
class VarDemo
{
public static void main(String[] args)
{
System.out.println(true + 1);
}
}
运行结果:“错误:二元运算符 “+” 的操作数类型错误 【第一个类型:int 第二个类型:boolean】”
P.S.
明确:字符’0’的数值:49 字符’a’的数值:98 字符’A’的数值:66
char 类型数据也可以和 int 类型相加,但是首先 char 类型数据会被自动提升为 int 类型。
示例:
class VarDemo
{
public static void main(String[] args)
{
System.out.println('a' + 1);
System.out.println('你' + 1);
}
}
运行结果:
98
20321
说明:字符类型数据之所以能够自动提升为int类型是因为字符类型数据在计算机中也是用0、1表示的,int类型数据在计算机中也用0、1表示,所以char类型数据当然可以转换为int类型数据。但是,字符类型数据在计算机中使用0、1表示是按照何种顺序组合排列的则需要依据某个码表而定。Java中的内置码表是Unicode
,既包含中文,也包含英文。
P.S.
通过强转也可以把数字强转成字符。
示例:
class VarDemo
{
public static void main(String[] args)
{
System.out.println((char)('a' + 1));
}
}
运行结果: b
表达式的数据类型自动提升:
-
所有的byte型、short型和char的值将被提升到int型
如果一个操作数是long型,计算结果就是long型
如果一个操作数是float型,计算结果就是float型
如果一个操作数是double型,计算结果就是double型
1、说出报出如下错误的原因:
class VarDemo
{
public static void main(String[] args)
{
byte b = 3 + 7;
byte b1 = 3;
byte b1 = 7;
b = b1 + b3;
System.out.println(b);
}
}
运行结果:“错误:不兼容的类型:从int转换成byte可能会有损失”
错误原因:涉及到编译器编译程序时候的细节,之所以byte b=3+7;,没有报错,是因为3和7都是常量,编译器知道结果是10,并且在byte范围之内,因此就自动进行了强转,所以不会报错『如果是3+187的话,会报错:可能会损失精度』
。而b=b1+b2;
中b1和b2都是变量,编译器编译程序是一行一行编译的,它根本不知道b1和b2到底是多少,两个byte类型的数据相加时,首先都会被提升为int类型,他们的和也是int类型,其值可能会超过byte的范围,因此就会报错。
常量值的计算是在编译期间完成,变量值的运算是在运行时确认
。
而以下程序不会报错:
class VarDemo
{
public static void main(String[] args)
{
int x;
int x1 = Integer.MAX_VALUE;
int x2 = 2;
x = x1 + x2;
System.out.println(x);
}
}
说明:原因是因为int类型的两个变量相加,最后还是int类型,虽然结果溢出,但是编译时不会报错,因为是运行时错误。
2、说明以下问题:
byte b = 130 ; 可否通过编译?为什么?如何改进?改进之后的结果又是多少呢?请说明原因?
- 参看”(2)、强制类型转换『显示类型转换』”示例
3、写出以下代码片段的结果:
System.out.println("hello" + 'a' + 1);
System.out.println('a' + "hello" + 1);
System.out.println('a' + 1 + "hello");
解答:
helloa1
ahello1
99hello
4、问答题:Java语言中
char
是否可以存储中文汉字,为什么?解答:可以,因为中文汉字是2个字节组成,而Java中的
char
也是2个字节长度Java 语言使用的是 全球语言统一编码(
Unicode
)
示例1:
class OperatorDemo
{
public static void main(String[] args)
{
int x = 23;
x = 23 /12 + 1;
System.out.println(x);
}
}
>>> 2
说明:整数与整数相除的结果,永远是整数,小数部分被忽略!
示例2:
class OperatorDemo
{
public static void main(String[] args)
{
System.out.println(-5 % 2);
System.out.println(-5 % -2);
System.out.println(5 % 2);
System.out.println(5 % -2);
}
}
>>> -1
-1
1
1
说明:负整数与任意非0整数取余的结果是负整数;正整数与任意非0整数取余的结果是正整数!
示例3:
class OperatorDemo
{
public static void main(String[] args)
{
int a = 3;
int b = a++;
System.out.println("a = " + a + " b = " + b);
}
}
>>>> a = 4 b = 3
说明:计算机中的实际操作是:当执行
b = a ++
语句时,先把a的值放在一个临时内存空间中,然后将 a 自身加1,再将内存空间中的a赋值给b,因此b还是a原来的值,也就是3(注意:使用的是左运算
)
示例4:
class OperatorDemo
{
public static void main(String[] args)
{
int a = 3;
int b = ++a;
System.out.println("a = " + a + " b = " + b);
}
}
>>> a = 4 b = 4
说明:当执行语句
b = ++a
时,现将a的值加1,再将a赋值给b,也就是4 .
符号:=、+=、-=、*=、/=、%=
明确:a += b 的作用 相当于 a = a + b;(其它运算符 同理类比)
因为各种赋值运算符,具有相同性质,重点解析+=
示例1:比较 s = s + 4 和 s += 4 的区别
class OperatorDemo
{
public static void main(String[] args)
{
short s = 3;
s = s + 4;
System.out.println("s = " + s);
}
}
运行结果:“错误:不兼容的类型:从int转换成int可能会有损失”
说明:在执行s=s+4;语句时,编译器在编译的时候,默认并没有强制类型转换。所以,s是short类型,4是int类型,s会自动提升为int类型,相加的和也是int类型,赋值给short类型的变量必然造成损失精度
的错误。这时候就需要进行强制类型转换: s = (short)(s + 4);
* *。
那如果将 s = s + 4;
替换为 s += 4;
,结果又会是什么样子的呢?
运行结果:s = 7
;这是为什么呢?
说明:在执行s+=4;
语句时,编译器在编译的时候,默认进行了强制类型转换,也就是将int类型的数据转换成short类型的数据。
s+=4;
等价于s = (short)(s + 4);
而非s = s + 4;
P.S.
比较运算符结果是boolea类型值 也就是 true 或 false
注意比较==
和=
示例1
class OperatorDemo
{
public static void main(String[] args)
{
int a = 3;
int b = 2;
boolran c = true;
System.out.println(a > b);
System.out.println(a == b);
System.out.println( c = false);
System.out.println( c == false);
}
}
>>> true
false
false
false
说明:前面打印的两句很好理解,重点是后两句,虽然都是false但是完全不同,第三句打印的是c的新值false,第四句打印的是c和false等于比较的结果
。
// System.out.println( c = false);
// 实际上等价于:先赋值、再打印c的新值
c = false;
System.out.println(c);
逻辑运算符用于连接两个boolean类型的表达式
运算规律:
- &:同为true结果为true,否则false
- | :存在为true结果为true,否则false
- ^ :相同为false,不同为true
- ! :!(true)为false,!(false)为true,!!(true)=true
- &&:同为true结果为true,否则false
- ||:存在为true结果为true,否则false
重点在于比较
&&
和&
以及||
和|
的区别1、
&&
和&
运算结果一样
2、&&
具有短路的效果,当左边为false,右边的不参与运算,提高效率;&
不具有短路效果,无论左边的是否为false,右边依然参与运算
1、
||
和|
运算结果一样
2、||
具有短路的效果,当左边为true,右边的不参与运算,提高效率;|
不具有短路效果,无论左边的是否为true,右边依然参与运算
鉴于运行效率,使用中,多为 "&&" 和 "||"
示例:
class OperatorDemo
{
public static void main(String[] args)
{
int x = 3;
int y = 6;
System.out.println("x = " + x + " y = " + y);
if( y > 5 & (++x) == 5 )
{
System.out.println("Hehe");
}
System.out.println("x = " + x + " y = " + y);
}
}
>>> x = 3 y = 6
x = 4 y = 6
说明:结果显示 if 语句块并没有执行,但是x的值加1,因为
&
没有短路,换成&&
,结果又会怎样呢? x的值还是3
P.S.
位运算符是直接针对二进制位进行运算。
&
运算的例子: &
得到010,也就是十进制下的2用“与运算”可以很方便的获取某一个二进制数的其中其中几位数。
例如:获取17476二进制数的后四位
0100 0100 0100 0100
&0000 0000 0000 1111
—————————————
0000 0000 0000 0100
|
运算的例子:
6 | 3 = 7
110和011按位|
得到111,也就是十进制下的7
^
运算的例子:
6 ^ 3 = 5
110和011按位|
得到101,也就是十进制下的5
一个数异或 同一个数两次,结果还是这个数
技巧
:利用异或运算可以实现数据简单地进加解密,例如对一张图片的所有数据异或3加密,那么这幅画就无法查看了,解密只需要再对图片的数据执行异或3操作即可。
!
运算:取反操作就是对二进制数值的每一位0变1,1变0。
<<
运算的例子:
3 << 2 = 12 相当于 3 * 22 = 12
3 << 3 = 12 相当于 3 * 23 = 24
总结:
- 左移几位其实就是该数据乘以2的几次方。
- <<:可以完成2的次幂的运算
>>
运算的例子: 总结:右移几位其实就是该数据除以2的几次方。
>>
右移:高位出现的空位,原来是什麽就用什么来填补>>>
无符号位右移:高位出现的空缺永远用0
来填补
-24 >> 2 = -6
-24 >>> 2 = 1073741818PS:计算机中乘除法的原理:左移、右移
1、最有效率的方式算出2乘以8等于几?
// 计算机底层乘法实现原理,效率最高
System.out.println(2 >> 3);
2、对两个整数变量的值进行互换?
- 方式1:开发中常用的,使用中间变量
- 方式2:不使用中间变量的,“和”实现
- 方式3:面试中使用的,按位亦或 “^”
- 方式4:一句话实现交换
方式1:开发中常用的,使用中间变量
public class SwapDemo{
public static void main(String[] args) {
int i = 10;
int j = 20;
int temp;
temp = i; //i = 10; j = 20; temp = 10;
i = j; //i = 20; j = 20; temp = 10;
j = temp; //i = 20; j = 10; temp = 10;
System.out.println("i=" + i + ";j=" + j);
// "i=20;j=10"
}
}
方式2:不使用中间变量的,“和”实现
这种方式不要用,如果两个整数的数值过大,会超出 int 范围,会强制转换,数据会变化
。public class SwapDemo{
public static void main(String[] args) {
int i = 10;
int j = 20;
i = i + j; //i = 30; j = 20;
j = i - j; //i = 30; j = 10;
i = i - j; //i = 20; j = 10;
System.out.println("i=" + i + ";j=" + j);
// "i=20;j=10"
}
}
方式3:面试中使用的,按位亦或 “^”
public class SwapDemo{
public static void main(String[] args) {
int i = 10;
int j = 20;
i = i ^ j;
j = i ^ j;
i = i ^ j;
System.out.println("i=" + i + ";j=" + j);
// "i=20;j=10"
}
}
方式4:一句话实现交换
public class SwapDemo{
public static void main(String[] args) {
int i = 10;
int j = 20;
j = ( i + j ) - ( i = j );
System.out.println("i=" + i + ";j=" + j);
// "i=20;j=10"
}
}
格式:
(条件表达式) ? 表达式1 : 表达式2;
- 如果条件表达式为true,则执行表达式1
- 如果条件表达式为false,则执行表达式2
表达式:具有一定语法规则的语句。
示例1:获取两个整数中的较大值
max = (x > y) ? x : y;
示例2:获取三个整数中的最大值
max = (x > y) ? ((x > z) ? x : z) : ((y > z) ? y : z);
【最基础的结构:自上而下执行】
(1)、if语句
格式1:
if(条件表达式)
{
执行语句;
}
示例1:
class IfDemo
{
public static void main(String[] args)
{
int score = 70;
if(score >= 60)
{
System.out.println("you pass the exam");
}
}
}
如果if语句没写大括号,if 就只能控制离它最近的单条语句
建议永远不要省略{ }
,这样具有更好的阅读性
格式2:
if(条件表达式)
{
执行语句;
}
else
{
执行语句;
}
示例2:
class IfDemo
{
public static void main(String[] args)
{
int score = 70;
if(score >= 60)
{
System.out.println("you win");
}
else
{
System.out.println("you fail");
}
}
}
P.S.
三元运算符就是 if else 语句的简写格式
简写格式什么时候可以使用呢?
当 if else 运算之后,有一个具体的结果时,可以简写成三元运算符。但是,如果是 输出语句,就不可以使用三元运算符了
格式3:
if(条件表达式)
{
执行语句;
}
else if(条件表达式)
{
执行语句;
}
......
{
执行语句;
}
示例3:
class IfDemo
{
public static void main(String[] args)
{
int score = 70;
if(score >= 90)
{
System.out.println("A");
}
else if(score >= 80)
{
System.out.println("B");
}
else if(score >= 70)
{
System.out.println("C");
}
else if(score >= 60)
{
System.out.println("D");
}
else
{
System.out.println("E");
}
}
}
P.S.
if(条件表达式) 之后切记不可加分号”;
“,否则无论表达式真假,都不执行任何语句
if(条件表达式);
相当于if(条件表达式) {};
其后的{ System.out.println(" "); }
为局部代码块
局部代码块
可以定义局部变量的生命周期,主要用来控制资源的释放,在移动端的开发中比较常见,因为移动端的资源是很宝贵的。
示例:
class IfDemo
{
public static void main(String[] args)
{
if(true);
{
int m = 100;
System.out.println("inner : " + m);
}
System.out.println("outter : " + m);
}
}
运行结果:“错误: 找不到符号 m ”【outter 处的 m】
说明:变量m是局部变量,生命周期仅在局部代码块括号中,当代码执行到局部代码块右括号外,变量m便消失了。局部代码块外的代码当然也就访问不到变量m了。
if语句特点:
- 1、每一种格式都是单条语句。
- 2、第二种格式与三元运算符的区别:三元运算符运算完一定要有值出现。好处是:可以写在其他表达式中。
- 3、条件表达式无论写成什么样子,只看最终的结构是否是true或者false。
(2)、switch语句
格式:
switch(表达式)
{
case 取值1:
执行语句;
break;
case 取值2:
执行语句;
break;
... ...
default:
执行语句;
break;
}
switch语句特点
- 1、
switch语句选择的类型只有四种:byte short int char;JDK5.0之后支持 枚举,JDK7.0之后支持String【面试题】
- 2、case与default没有顺序,先尝试第一个case,一次往下执行,没有匹配的case,就执行default
- 3、结束switch语句的两种情况:①遇到break;②执行到switch语句结束
}
- 4、如果没有匹配的case或default,没有对应的break,那么程序会继续执行下去,运行所有可以执行的语句,直到switch结束
}
- 5、进入switch语句后,执行顺序:自上而下,先执行case,依次往下,没有符合的case,最后再执行default。即使 default 定义在所有case之前,执行顺序不变
- 6、
default可以没有
示例1:
class SwitchDemo
{
public static void main(String[] args)
{
int score = 70;
char grade = ' ';
switch(score / 10)
{
case 9:
grade = 'A';
break;
case 8:
grade = 'B';
break;
case 7:
grade = 'C';
break;
case 6:
grade = 'D';
break;
// case 0-5 时 执行同一条语句 grade='E';
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
grade = 'E';
break;
default:
break;
}
System.out.println(grade);
}
}
示例2:case贯穿现象
class SwitchDemo
{
public static void main(String[] args)
{
int a = 2;
int b = 3;
switch(a)
{
default:
b++;
case 3:
b++;
case 4:
b++;
}
System.out.println(b);
}
}
运行结果: 6
总结:if和switch语句的应用:
if:
- 1)、针对常量值的判断【多常量值时,使用
switch
】- 2)、针对一个范围判断
- 3)、针对运算结果是 boolean 类型表达式的判断【执行语句返回的是值时,使用
三目运算符
】switch:
- 1)、针对常量值的判断
- 2)、值的个数通常是固定的
PS:针对常量值的判断,建议使用switch语句,因为switch语句会将具体的答案都加载进内存,效率相对较高。
关键词:while、do…while、for
(1)、while语句
格式:
初始化语句;
while(判断条件表达式)
{
循环体语句;
控制条件语句;
//必须包含 控制条件语句,否则造成死循环
}
示例:
class WhileDemo
{
public static void main(String[] args)
{
int x = 1;
while(x < 3)
{
System.out.println("x = " + x);
// 控制条件语句
x++;
}
}
}
P.S.
一定要注意不要写while(x < 3);
相当于是while(x < 3) {};
,代表不执行任何语句遗失了控制条件语句
,这个循环就成了一个死循环。
(2)、do…while语句
格式:
初始化语句;
do
{
循环语句;
控制条件语句;
// 必须包含 控制条件语句,否则造成死循环
} while(判断条件语句);
示例:
class WhileDemo
{
public static void main(String[] args)
{
int x = 1;
do
{
System.out.println("x = " + x);
// 控制条件语句
x++;
}while(x < 3);
}
}
总结:对比while和do...while
- do…while语句的特点:无论条件是否满足,循环体至少执行一次
- while如果条件不满足,循环体一次都不会执行
(3)、for语句
格式:
for(初始化语句;判断条件语句;控制条件语句)
{
循环语句;
}
**说明:**for里面的三个表达式运行的顺序,
初始化语句只执行一次
,判断条件语句为真就执行循环语句,然后再执行控制条件语句,接着执行判断条件语句,重复整个过程,直到条件不满足为止。
示例:1~10之间的偶数
class FoDemo
{
public static void main(String[] args)
{
for(int i = 1; i <= 10; i++)
{
if(i % 2 == 0)
{
System.out.println(i);
}
}
/* 等价于:
* for(int i = 2; i <= 10; i += 2)
* {
* System.out.println(i);
* }
}
}
示例:统计100以内所有3的倍数的个数–统计思想
class CountDemo
{
public static void main(String[] args)
{
int count = 0;
for(int i = 0; i <= 100 ; i++)
{
if(i % 3 == 0)
{
count ++;
}
}
System.out.println(count);
}
}
>>> 33
『可以使用和求偶数一样的方式:for(int i = 3; i <= 100; i += 3){}』
示例:求N的阶乘N!–求积思想
import java.util.Scanner;
class MultiplyDemo
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int q = 1;
for(int i = 1; i <= n; i++)
{
q *= i;
}
System.out.println(q);
}
}
P.S.
Scanner
是键盘录入类,import java.util.Scanner;
将类所在的包导入;使用Scanner sc = new Scanner(System.in);
新建一个对象,sc.nextInt();
获取键盘录入的一个int类型值
示例:求1-N的总和–求和思想
import java.util.Scanner
class SumDemo
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int sum = 0;
for(int i = 1; i <= n; i++)
{
sum += i;
}
System.out.println(sum);
}
}
P.S.
for循环的初始化语句、控制条件语句可以有多个,之间使用,
隔开
总结:for和while对比
- 1、使用区别:如果初始化语句中的变量在循环之外还需使用的话,使用while;否则使用for,变量及早地从内存中消失,提高内存的利用率
『变量的作用域』
- 2、对于一个明确的范围,使用for;否则使用while
- 3、在不影响阅读性的基础上,建议使用for,而不使用while
注意:死循环
- 1、控制条件语句必须有,正确控制变量
- 2、最简单的两种死循环:while(true)
、for(;;)
(4)、for嵌套
示例:输出正三角形
/* 需求:打印一下图形
* *
* **
* ***
* ****
* 分析: 第1行,输出1个'*'
* 第2行,输出2个'*'
* ......
* 第n行,输出n个'*'
* 实现: 用一个 i 控制第几行
* 用一个 j 控制打印的数目
* j 的范围应该由 i 来控制
* 每行输出完成之后,执行换行 System.out.println();
* 编码:
*/
class StarDemo
{
public static void main(String[] args)
{
for(int i = 1; i <= 4; i++)
{
for(int j = 1; j <= i; j++)
{
System.out.print('*');
}
System.out.println();
}
}
}
示例:输出99乘法表
/* 需求:打印以下格式的99乘法表
* 1×1=1
* 1×2=2 2×2=4
* 1×3=3 2×3=6 3×3=9
* 1×4=4 2×4=8 3×4=12 4×4=16
* ......
* 分析: 第1行 1×1
* 第2行 1×2 2×2
* 第3行 1×3 2×3 3×3
* ......
* 第n行 1×n 2×n 3×n ... n×n
* 实现: 用 i 控制第几行
* 用 j 控制该行有多少列
* j 的范围应该由 i 来控制
* 每行输出完成之后,执行换行 System.out.println();
* 编码:
*/
class TableDemo
{
public static void main(String[] args)
{
for(int i = 1; i <= 9; i++)
{
for(int j = 1; j <= i; j++)
{
System.out.print(j + "×" + i + "=" + i*j + "\t");
}
System.out.println();
}
}
}
> 1×1=1
1×2=2 2×2=4
1×3=3 2×3=6 3×3=9
1×4=4 2×4=8 3×4=12 4×4=16
1×5=5 2×5=10 3×5=15 4×5=20 5×5=25
1×6=6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36
1×7=7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49
1×8=8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64
1×9=9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81
break(中断)、continue(继续)、return(返回)
goto作为保留字,不可使用
(1)、break(中断)
使用场景:switch结构中、循环语句中的 if 判断,离开上述场景毫无意义!
如何使用:
outer:for(int i = 0; i < 3; i++)
{
inner:for(int j = 0; j < 5; j++)
{
if(j == 2)
{
break outer;
// break inner;
}
}
}
(2)、continue(继续)
使用场景:循环语句中的 if 判断,离开此场景毫无意义!
如何使用:
break
跳出当前循环;continue
跳出本次循环(3)、return(返回)
使用场景:方法中,用于退出当前方法体,跳转到上层调用的方法;在main方法中的return用于结束程序
综合示例:写出程序的执行结果
class GotoDemo
{
public static void main(String[] args)
{
for(int i = 1; i < 10; i++)
{
if(i % 2 == 0)
{
System.out.println("Exit");
____①;____
}
System.out.println(i);
}
System.out.println("Over");
}
}
>>> 分别写出 ① 为break、continue、return的结果
① 为 break
>>> 1
Exit
Over
① 为 continue
>>> 1
Exit
3
Exit
5
Exit
7
Exit
9
Over
① 为 return
>>> 1
Exit
PS:
以上三种语句应该放在局部代码块的最后,因为放于其后的代码永不执行
。
定义:类中完成特定功能的代码块。也称为函数,Java称为方法。
修饰符 返回值类型 方法名(参数类型 形式参数1,参数类型 形式参数1,...)
{
方法体;
return 返回值;
}
>>> "参数类型 形式参数1,参数类型 形式参数1,..."也就是参数列表
同一个代码块在出现两次以上考虑定义方法。
P.S.
- 1、修饰符:目前只需要固定写成public static即可
- 2、返回值类型:返回值的数据类型『数值类型、引用类型』
- 3、方法名:标识符,方便调用
- 4、参数:实际参数:实际参与运算的变量,形式参数:方法上用于接收实际参数值的变量
- 5、参数类型:参数的数据类型
- 6、方法体:完成特定功能的代码块
- 7、return:结束方法,跳转到上层调用的方法
- 8、返回值:return返回给调用者
方法的定义:格式 + 两个明确『参数列表、返回值类型』
注意:
- 1、对于方法没有具体返回值的情况,返回值类型使用关键字void,该函数中的return语句可以省略不写,或者写上
return;
- 2、函数中只能调用函数,不可以在函数内部定义函数。否则,编译时期就会报错。
- 3、定义函数时,函数的结果应该返回给调用者,交由调用者处理。
对于第3点,请对比以下完成两个数值和的代码块:
public static void sum(int a,int b)
{
System.out.println(a+b);
}
public static int sum(int a,int b)
{
return a + b;
}
虽说两种都可以执行出正确的数据,下面的代码比较好,因为调用者只需要获取两数相加的结果,而不需要方法做打印的操作!
按照方法定义的要求:格式 + 两个明确,完成以下示例:
示例1:输出n列m行的”*”方法
/* 需求:输出n行m列的 *
* 例如:当n=3,m=4时
* ****
* ****
* ****
* 分析:n代表一共几行,m代表一行打印多少个
* 方法的需求中强调将其直接打印出来
* 可以明确返回值类型是void,
* 也就是说return可以省略不写或者使用return;
* n行m列,所以参数列表应该是(int n,int m)
*
* 综上,格式为:
* public static void PrintStar(int n,int m)
* {
* //return;
* }
*
* 编码实现
*/
import java.util.Scanner;
class StarDemo
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.println("Please input an integer(n):");
int n = sc.nextInt();
System.out.println("Please input an integer(m):");
int m = sc.nextInt();
PrintStar(n,m);
}
public static void PrintStar(int n,int m)
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
System.out.print("*");
}
System.out.println();
}
}
}
示例2:输出nn乘法表(1~9)
/* 需求:输出nn乘法表,且n在1-9之间
* 借鉴之前的99乘法表
* 1×1=1
* 1×2=2 2×2=4
* 1×3=3 2×3=6 3×3=9
* ... ...
* 分析:根据需求中的方法的功能是输出,明确返回值类型是void,
* 返回值是return; 或者省略
* 明确是nn乘法表。所以方法的参数是一个int类型的n
* 第一个n确认的是行数,第二个n确认改行打印的程式的个数
* 综上,格式是:
* public static void PrintTable(int n)
* {
* //return;
* }
* 编码实现:
*/
import java.util.Scanner;
class TableDemo
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.println("Please inoput an integer:");
int n = sc.nextInt();
PrintTable(n);
}
public static void PrintTable(int n)
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= i; j++)
{
System.out.print(j + "*" + i + "=" + j*i +"\t");
}
System.out.println();
}
}
}
示例3:获取两个整数中的最大数
/* 需求:获取两个整数中的最大数;
* 分析:明确参数列表是两个int类型的参数
* 返回值类型也是int类型
* 根据功能需求是获取,也就是需要把方法处理后结果返还给调用者
* 综上:格式为:
* public static int max(int a,int b)
* {
* return max;
* }
* 编码实现:
*/
class MaxDemo
{
public static void main(String[] args)
{
int a = 12;
int b = -1;
int max = max(a, b);
System.out.println(max);
}
public static int max(int a,int b)
{
return (a > b) ? a : b;
}
}
练习:判断两个整数是否相等
练习:获取两个整数的和
示例4:获取三个整数中的最大数
/*
* 需求分析参考上述示例3
*/
class MaxDemo
{
public static void main(String[] args)
{
int a = 12;
int b = -1;
int c = 23;
int max = max(a, b, c);
System.out.println(max);
}
public static int max(int a,int b,int c)
{
return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c);
}
}
对比示例3、4可以发现两个方法的功能相同,方法名相同,只是参数列表不同,具有类似功能的方法应该定义在相同的类中完成封装。这就引出了Java中的方法重载(OverLoad)。
方法重载(OverLoad):
- 同一类中,完成同样功能的方法,为了见名知意,允许具有相同的方法名,不同的参数列表,这种现象就叫做方法重载(OverLoad)。
- 不同的参数列表包含两种含义:参数的数据类型不同、参数的个数不同。
- 从定义中可以看到,重载只和参数列表有关,与方法的返回值无关。
调用时候,JVM(Java Virtual Machine)根据参数列表的不同来区分同名方法
示例:实现获取最大值的类
class MaxDemo
{
public static void main(String[] args)
{
int a = 12;
int b = -1;
int c = 23;
int max = max(a, b, c);
System.out.println(max);
}
public static int max(int a,int b,int c)
{
//return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c);
return max(max(a, b), c);
}
public static int max(int a,int b)
{
return (a > b) ? a : b;
}
public static float max(float a,float b)
{
return (a > b) ? a : b;
}
}
定义:数组是存储同一数据类型的多个元素的集合(容器)
数组初始化:为数组中的元素分配内存空间并为其赋值,Java中的数组必须先进行初始化才可以使用
动态初始化
:只指定数组的长度(内存空间),由系统为数组分配初始值(0\null)静态初始化
:只指定每个元素的值,由系统为其指定长度(内存空间)new 为数组申请内存空间
数组的下标是从 0 开始,、最大值 为:length-1
Java中的内存分配:
- Java中程序在运行时,需要在内存中为其分配空间,为了提高效率,将内存空间进行了不同的划分,让每块区域都有自己特定的数据处理方式和内存管理方法。
大致可以分为以下5种:
1、栈:存储局部变量,当变量所属的作用域一旦结束,所占空间会自动释放
2、堆:通常new出来的数组或对象都放置在堆内存中
3、方法区:class文件内容
- 4、本地方法区:与系统相关
- 5、寄存器:共CPU使用
局部变量:在方法声明中或方法定义上的变量。
示例代码1:
class ArrayDemo
{
public static void main(String[] args)
{
int[] arr = new int[3];
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
}
}
>>> [I@659e0bfd // 地址值:"[" 代表是一位数组;"I" 代表是int类型;
// "@"之后的是映射的十六进制地址值
0
0
0 // 打印的三个元素值,是由JVM系统给定的初始值
内存图解:
堆内存的特点:
- A:每一个new出来的对象都有地址值
- B:每一个变量都有默认值
- C:使用完成(栈中没有指向它的变量)就成了垃圾,但并没有马上回收。在垃圾回收器空闲时回收。
注意:C++内类型的析构函数就是为了释放空间,但在Java中是自动进行的基本数据类型默认值:
- byte、short、int、long默认是 0
- float、double默认是 0.0
- char 默认是 ‘、u0000’ - 空字符
- boolean 默认是 false
- 引用数据类型 默认是 null
栈内存的特点
数据用完就释放掉(超出作用域”}
“)
示例代码2:
{
int a = 10;
System.out.println(a) ;
} // 在这里 a 已经被释放了,之后再对 a 访问造成 未定义的错误
在示例代码2
的基础之上,进行以下的操作:
arr[0] = 100;
arr[1] = 100;
内存图解:
示例代码3:
class ArrayDemo
{
public static void main(String[] args)
{
int[] arr = new int[3];
int[] ar = arr;
arr[0] = 100;
arr[1] = 100;
ar[0] = 10;
ar[1] = 20;
ar[2] = 30;
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
}
}
>>> 10
20
30
内存图解:
静态初始化:指定元素的值,由系统分配内存长度
格式:数据类型[] 数组名 = new 数据类型[]{元素1,元素2…};
简写格式是:数据类型[] 数组名 = {元素1, 元素2…};
int[] arr = new int[]{1, 2, 3};
// int[] arr = {1, 2, 3};
内存图解:
切记:不可同时对数组进行动态和静态初始化,即:int[] arr = new int[3]{1, 2, 3}; 是不合法的。
Exception:异常
- 1、识别
现象
- 2、分析
原因
- 3、如何
改进
[0,length-1]
之间
int[] arr = null;
(1)、遍历
for(int i = 0; i < array.length; i++)
{
// 操作
}
>>> 数组名.length 是获取数组的长度 int类型值
(2)、获取最值
int max = array[0];
// 获取数组中的第一个元素值,作为参照
// 不可以使用非数组中元素作为参照,比如说:0
// 遍历之后的 [1,length-1] 元素,与参照对比
// 如果大于参照,就把他的值赋给参照
// 如果小于参照,则继续下一个元素的比较
for(int i = 1; i < array.length; i++)
{
if(array[i] > max)
{
max = array[i];
}
}
// 通过遍历全部元素之后,获得最大值
System.out.println(max);
>>> 数组名.length 是获取数组的长度 int类型值
PS:最小值的问题与此类似,请自行分析!
(3)、逆序(Reverse)
所谓的数组逆序,就是倒序;譬如{1, 2, 3}逆序为{3, 2, 1}
第1种实现:定义新的数组
// 定义新的同类型数组(使用元数组的长度动态初始化定义)
int[] rArray = new int[array.length];
// 遍历数组所有元素,实现倒序
for(int i = 0; i < array.length; i++)
{
rArray[array.length-1-i] = array[i];
}
// 实现比较简单:但是耗费了额外的内存空间。好处是没有改变原来数组
第2种实现:使用原数组
// 以中间元素为基准,将数组元素进行交换
// 第一个和倒数第一个,第二个和倒数第二个,以此类推
for(int i = 0; i < (array.length-1) / 2; i++)
{
// 实现两个正整数的交换-四种方式
// 第一种方式:使用中间变量
int t = array[i];
array[i] = array[array.length-1-i];
array[array.length-1-i] = t;
}
// 使用while实现:从两头向中间靠近,到达中间之后就停止
int start = 0;
int end = array.length-1;
while(start != end)
{
int t = array[start];
array[start] = array[end];
array[end] = t;
// 两头向中间靠近
start++;
end--;
}
(4)、数组查表法:以索引获取指定元素
方法实现:明确参数列表是(int[] arr,int index)
;返回值类型 int
类型
public static int getValue(int[] arr, int index)
{
if(index >= 0 && index < arr.length)
{
return arr[index];
}
else
{
// 暂时使用 -1 代表ArrayIndexOutOfBoundsException异常
return -1;
}
}
(5)、基本查找:查找指定元素在数组中第一次出现的位置
方法实现:明确参数列表是(int[] arr,int value)
;返回值类型 int
类型
public static int getIndex(int[] arr, int value)
{
for(int i = 0; i < arr.length; i++)
{
if(arr[i] == value)
{
return i;
}
}
// -1 表示数组中不存在该元素
return -1;
}
上述两个部分代码看似实现了功能,但是不具有很好的阅读性:
public static int getIndex(int[] arr, int value)
{
// -1 表示数组中不存在该元素
int index = -1;
for(int i = 0; i < arr.length; i++)
{
if(arr[i] == value)
{
index = i;
// 找到第一个元素之后,应该结束当前的循环
break;
}
}
return index;
}
参照getIndex,请自行修改方法getValue,使其具有更好的阅读性。
定义:元素是一维数组的数组
示例1:分析以下的代码片段:
int[] x, y[]; // x是一维数组,y是二维数组:拆开定义就显而易见了
// x是一维数组,y是二维数组:拆开定义就显而易见了
int[] x;
int[] y[];
class ArrayDemo
{
public static void main(String[] args)
{
int[][] arr = new int[3][2];
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[1][0]);
System.out.println(arr[1][2]);
}
}
>>> [[I@659e0bfd // "[[" 代表是二维数组,"I" 代表是int类型,
// "@"之后的是映射的内存地址
[I@2a139a55 // "[" 代表的是一维数组,其他的同上
[I@15db9742
[I@6d06d69c
0 // 堆内存中,int类型的默认值是 0
0
内存图解:
示例2:分析以下的代码片段:
class ArrayDemo
{
public static void main(String[] args)
{
int[][] arr = new int[3][];
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[1];
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[1][0]);
System.out.println(arr[1][2]);
arr[1][0] = 100;
arr[1][2] = 200;
System.out.println(arr[1][0]);
System.out.println(arr[1][2]);
}
}
>>> [[I@659e0bfd // "[[" 代表是二维数组,"I" 代表是int类型,
// "@"之后的是映射的内存地址
null // 堆内存中,一维数组是引用类型,默认值是 null
null
null
0 // 堆内存中,int类型的默认值是 0
0
[I@2a139a55 // "[" 代表的是一维数组,其他的同上
[I@15db9742
[I@6d06d69c
100 // 完成了数组元素的赋值
200
内存图解
数据类型[][] 数组名 = {{,..},{,..}...}
示例3:分析以下代码片段:
class ArrayDemo
{
public static void main(String[] args)
{
int[][] arr = {{1, 2, 3},{4, 5},{6}};
System.out.println(arr);
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[0][1]);
System.out.println(arr[2][0]);
}
}
>>> [[I@659e0bfd
[I@2a139a55
[I@15db9742
[I@6d06d69c
2
6
内存图解
动态初始化:『只指定数组的长度,具体的值由JVM虚拟机默认初始化』格式1、格式2
动态初始化:『只给出所有元素的值,数组的长度由JVM虚拟机给出』格式3
(1)、遍历
class ArrayDemo
{
public static void main(String[] args)
{
int[][] arr = {{1, 2, 3}, {4, 5}, {6}};
for(int m = 0; m < arr.length; m++)
{
for(int n = 0; n < arr[m].length; n++)
{
System.out.print(arr[m][n] + "\t");
}
System.out.println();
}
}
}
>>> 1 2 3
4 5
6
(2)、求和(求和思想+遍历)
class ArrayDemo
{
public static void main(String[] args)
{
int[][] arr = {{1, 2, 3}, {4, 5}, {6}};
int sum = 0;
for(int m = 0; m < arr.length; m++)
{
for(int n = 0; n < arr[m].length; n++)
{
sum += arr[m][n];
}
}
System.out.println(sum);
}
}
>>> 21
(3)、杨辉三角性
-综合案例
/*
* 需求:根据用户输入的行号,输出杨辉三角性
* 譬如:输入行号为 5
* 输出: 1
* 1 1
* 1 2 1
* 1 3 3 1
* 1 4 6 4 1
* 1 5 10 10 5 1
*
* 分析:使用二维数组作为数据结构
* 输出的行数是输入的行号+1
* 每行的列数和该行行号相同
* 第一列的数字均为1,对角线的数字均为1
* 从第三行开始,除掉第一数字1、最后一个数字1;
* 从第二个数字开始,该数字的值等于上一行的
* 该列数字和它前一列的数字之和
*
* 实现:
* 定义一个二维数组:int[][] arr = new int[n+1][]
* 初始化二维数组中的每一个一维数组的值
* 1、定义一个直角三角形的二维数组,其中每个一维数组的长度
* 等于二维数组下标+1,同时将一维数组的第一列和
* 对角线上的数字初始化为 1
* for(int i = 0; i < arr.length; i++)
* {
* arr[i] = new int[i + 1];
* arr[i][0] = 1;
* arr[i][i] = 1;
* }
*
* 2、从第三行开始每行的第二个元素到对角线之前的那个元素,
* 都等于上一行同列的元素以及前列的元素之和
* for(int i = 2; i < arr.length; i++)
* {
* for(int j = 1; j < arr[i].length-1; j++)
* {
* arr[i][j] = arr[i-1][j] + arr[i-1][j-2];
* }
* }
*
* 3、遍历打印二维数组
* for(int i = 0; i < arr.length; i++)
* {
* for(int j = 0; j < arr[i].length; j++)
* {
* System.out.print(arr[i][j] + " ");
* }
* System.out.println();
* }
*/
import java.util.Scanner;
/**
* 这是一个实现打印杨辉三角性的类
* @author JoianSun
*/
class TriangleDemo
{
public static void main(String[] args)
{
// 定义键盘录入对象,接收用户录入的行数
Scanner sc = new Scanner(System.in);
System.out.println("Please input a number(n > 0):");
// 接收用户输入的行数
int line = sc.nextInt();
// 判断用户输入的行数是否合法,如果不合法,立即结束程序
if(line < 0)
{
System.out.println("Please input a postive integer!");
return;
}
// 用户输入的line合法的话,继续实现
// 1、实现数据结构的初始化
int[][] arr = new int[line + 1][];
/* 2、定义二维数组中每个一维数组的长度
* (一维数组的长度等于该一维数组在二维数组中的下标+1)
* 并对每个一维数组第一个元素和对角线上
* (也就是最后一个元素)的元素进行 1 赋值
*/
for(int i = 0; i < arr.length; i++)
{
// 定义一维数组的长度
arr[i] = new int[i + 1];
// 首尾元素赋值为 1
arr[i][0] = 1;
arr[i][i] = 1;
}
// 3、将一维数组中的非首尾元素按规律赋值
for(int i = 2; i < arr.length; i++)
{
for(int j = 1; j < arr[i].length-1; j++)
{
arr[i][j] = arr[i-1][j] + arr[i-1][j-1];
}
}
// 4、遍历打印二维数组
for(int i = 0; i < arr.length; i++)
{
for(int j = 0; j < arr[i].length; j++)
{
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
class Demo
{
public static void main(String[] args)
{
int a = 10;
int b = 20;
System.out.println("a=" + a + ",b=" + b);
change(a, b);
System.out.println("a=" + a + ",b=" + b);
int[] arr = {1, 2, 3, 4, 5};
change(arr);
System.out.println(arr[1]);
}
public static void change(int a, int b)
{
System.out.println("a=" + a + ",b=" + b);
a = b;
b = a + b;
System.out.println("a=" + a + ",b=" + b);
}
public static void change(int[] arr)
{
for(int i = 0; i < arr.length; i++)
{
if(arr[i] % 2 == 0)
{
arr[i] *= 2;
}
}
}
}
>>> a=10,b=20 // main方法中,打印a、b的值
a=10,b=20 // change方法中,打印a、b的值
a=20,b=40 // change方法中,在将a=b; b=a+b;执行完毕后的打印
a=10,b=20
/* main方法中,打印a、b的值,值没变的原因是:change方法上形式参数
接受了a、b值,只是把main方法中a、b的值传给了change方法
中的a、b,并在change方法内部做了操作,但是在main方法中
并没有对a、b做任何的操作,所以并没有改变main方法中的a、b值 */
4
/* main方法中的数组下标为1的元素的值是2,将数组的地址值传递到change
方法中,实际上相当于两个不同方法中的arr指向了同一块堆内存区域,
所以在change中改变了的数组元素的值,会被main方法中的数组
同样引用到,所以arr[1]的值被改变 */
P.S.
Java中只有一种参数传递的方式:值传递
-基本数据类型:传递的是数值的大小『形式参数和实际参数互不影响』
-引用数据类型:传递的是 地址值 『形式参数改变直接作用到实际参数』
/*
* 1、问题描述:
* 某个公司采用公用电话传递数据信息,数据是小于8位的整数,为了确保安全,
* 在传递过程中需要加密。
* 加密规则如下:首先将数据倒序,然后将每位数字都加上5,再用和
* 除以10的余数代替该数字,最后将第一位和最后一位数字交换。
* 请任意给定一个小于8位的整数,然后,把加密后的结果在控制台打印出来。
*
* 2、获取需求:
* 实现将用户输入的小于8位正整数字,按照给定的规则加密,并打印出来
*
* 3、分析:
* (1)获取给定的不小于8位的整数
*
* (2)分析主要规定的规则:
* a、原始数据倒序
* b、将每一个数字加上5
* c、和与10取余代替当前数字
* d、首尾数字交换
*
* (3)将所得加密后的数字打印
*
* 4、实现:
* 数据结构:采用一维数组,长度为8
*
* 规则实现:
* a、原始数据倒序
* 拆数:获取各个位置上的数字
* 拆数过程中从个位数字开始获取,存储从数组的0索引开始,
* 已经实现了数组的逆置
* 逆置数组(reverse函数)
*
* b、将每一个数字加上5
* 一维数组的遍历:for循环
* num += 5;
*
* c、和与10取余代替当前数字
* num %= 10;
*
* d、首尾数字交换
* 实现正整数交换的四种方式
* (1)中间变量temp
* (2)不借助中间变量(+)
* (3)使用按位异或的特点:
* 某一数据和同一数据异或两次,数据本身不变
* (4)一句话实现:
* b = (a+b) -(a=b); 可读性很差且代码不规范
*
* 5、编码
*/
import java.util.Scanner;
public class JiaMiDemo
{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入原始数据:");
// 1、获取原始数据
int data = sc.nextInt();
/*
// 2、定义数据结构:一维数组
int[] dataArray = new int[8];
int count = 0; // 记录索引位置(数组的实际长度)
// 3、原始数据倒序
// 拆数:获取各个位置上的数字
// 拆数过程中从个位数字开始获取,存储从数组的0索引开始,
// 已经实现了数组的逆置
// 逆置数组(reverse函数)
while(data!=0)
{
dataArray[count] = data % 10;
count ++;
data /= 10;
}
*/
// 拆数函数实现2、3
int[] dataArray = chaiShu(data);
// 获取数组的实际长度
int count = dataArray[8];
/* 4、将每一个数字加上5
* 一维数组的遍历:for循环
* 5、和与10取余代替当前数字
*/
for(int i=0;i5;
dataArray[i] %= 10;
}
// 6、首尾数字交换
int temp = dataArray[0];
dataArray[0] = dataArray[count-1];
dataArray[count-1] = temp;
// 7、实现加密数据的输出
String jiami="";
for (int i=0;i"加密后的数据是:\n"+ jiami);
}
/* 拆数函数:获取各个位置上的数字
* 拆数过程中从个位数字开始获取,存储从数组的0索引开始,
* 已经实现了数组的逆置
*/
public static int[] chaiShu(int num)
{
int[] arr = new int[9];
int index = 0;
while(num!=0)
{
arr[index++]=num%10;
num/=10;
}
// 最后一位存储数组的实际长度
arr[8] = index;
return arr;
}
}