赞
踩
软件,即一系列按照特定顺序组织的计算机数据和指令的集合。有系统软件和应用软件之分。
图形化界面(Graphical User Interface GUI):
- 这种方式简单直观,使用者易于接受,容易上手操作。
命令行方式(Command Line Interface CLI):- 需要有一个控制台,输入特定的指令,让计算机完成一些操作。较为麻烦,需要记录住一些命令。
(1)常用命令:
- md :创建目录
- rd: 删除目录
- cd : 进入指定目录
- cd… : 退回到上一级目录
- cd \: 退回到根目录
- del : 删除文件
- exit: 退出 dos 命令行
- 补充:echo javase>1.doc
(2)常用快捷键:
- ← → :移动光标
- ↑ ↓:调阅历史操作命令
- Delete和Backspace:删除字符
(1)第一代语言:
机器语言:
- 指令以二进制代码形式存在;
(2)第二代语言
汇编语言:
- 使用助记符表示一条机器指令;
(3)第三代语言:
高级语言:
- C、Pascal、Fortran面向过程的语言
- C++面向过程/面向对象
- Java跨平台的纯面向对象的语言
- .NET跨语言的平台
- Python、Scala…
- 企业级应用
- Android平台应用
- 大数据平台开发
- Java语言是易学的
- Java语言是强制面向对象的
- Java语言是分布式的
- Java语言是健壮的
- Java语言是安全的
- Java语言是体系结构中立的
- Java语言是编译型的
- Java是性能略高的
- Java语言是原生支持多线程的
(1)特点一:面向对象
两个基本概念:类、对象
三大特性:封装、继承、多态
(2)特点二:健壮性
程序在遇到意外错误或异常时能够正常运行而不崩溃的能力。换句话说,一个健壮的Java程序能够处理意外情况或错误,保持正常运行。
(3)特点三:跨平台性
- write once,run anywhere;
- 原理:JVM(Java虚拟机);
- 理解:Java的源码可以在不同的操作系统(Windows、Linux、OS…)上运行;
(1)Java虚拟机 (Java Virtal Machine):
JVM(Java虚拟机)是一个虚拟的计算机,具有指令集并使用不同的存储区域。负责执行指令,管理数据、内存、寄存器;
(1)垃圾收集机制 (Garbage Collection):
- 它是自动释放程序不再使用的内存的机制。它可以防止内存泄漏,并确保程序的高效运行。垃圾收集器定期检查程序的内存,识别不再使用的对象,然后释放它们占用的内存。这个过程是自动的,不需要程序员进行显式的操作。
- 但是在C语言中需要自己手动的释放内存,容易方法内存泄漏;
(1)JDK(Java Development Kit Java开发工具包):
JDK是提供给Java开发人员使用的,其中包含了java的开发工具,也包括了 JRE。 所以安装了JDK,就不用在单独安装JRE了。
(2)JRE(Java Runtime Environment Java运行环境):
包括Java虚拟机(JVM :Java Virtual Machine)和Java程序所需的核心类库等,如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可。
(3)jdk、JRE、JVM之间关系:
JDK=JRE+开发工具集(例如javac/Javac编译工具等)
JRE= JVM+Java SE标准类库
①官网:Oracle.com
②进入products(进入后拉到底部)——>java(进入后拉到底部)——>oracleJDK:
建议:安装路径不要有中文或者空格等特殊符号
注意:一台电脑上可以安转多个不同版本的JDK
注意:
- 环境配置决定jdk使用版本
- path :windows系统执行命令时要搜寻的路径
①步骤一:
- 打开【此电脑】的属性页面,在【系统】窗口中选择【高级系统配置】在【高级】窗口中选择【环境变量】进行配置:
②步骤二:
在系统变量(s)创建(W)-----> (输入变量名、和设置变量值)-----> 确定
③步骤三:
将新建的变量JAVA_HOME 添加到path路径下:
- path :windows系统执行命令时要搜寻的路径;
④环境配置补充:
(1)编写:
public class HelloWorld{ //注意:当修饰符为public时,文件名必须与类型相同
public static void main(String [] args){
System.out.println("hello world!");
}
}
(2)编译和运行:
将 Java 代码编写到扩展名为 .java 的文件中。
通过 javac 命令对该 java 文件进行编译。
- 代码:
javac XxxYyy.java
(此时文件不区分大小写,因为在Windows下不区分大小写)
通过 java 命令对生成的 class 文件进行运行。代码:java XxxYyy
(XxxYyy:类名)
(1)总结:
学习编程最容易犯的错是语法错误。Java要求你必须按照语法规则编写代码。
如果你的程序违反了语法规则,例如:忘记了分号、大括号、引号,或者拼错了单词,
java编译器都会报语法错误。尝试着去看懂编译器会报告的错误信息。
分类:单行注释、多行注释、文档注释
(1)单行注释:
//这是一个int类型的变量
int m;
(2)多行注释格式:
/*
这是一句多行注释
*/
(3)作用:
对所写程序进行解释说明,增强可读性。方便自己和他人;
调试所写的代码;
(4)特点:
单行注释和多行注释,注释了的内容不参与编译;
换言之,编译以后生成的,class结尾的字节码文件中不包含注释掉的信息;
(5)注意:
多行注释不能嵌套使用;
(1)文档注释格式: /** */
/**
@author 指定java程序的作者
@version 指定源文件的版本
*/
(2)特点:
注释内容可以被JDK提供的工具 javadoc 所解析,生成一套以网页文件形式体现的该程序的说明文档;
前提:在源文件(.java文件)中使用了文档注释
//举例代码
public class Test{
public static void main(String[] args) {
System.out.println("Hello World!");
}
/**
这是一个我说的方法....
*/
public static void say(String language){
System.out.println("我正在用"+language+"交谈....");
}
}
点击打开产生的day01目录 ------> 双击(源文件名).html文件
API (Application Programming Interface,应用程序编程接口)是 Java 提供的基本编程接口。
Java语言提供了大量的基础类,因此 Oracle 也为这些基础类提供了相应的 API文档,用于告诉开发者如何使用这些类,以及这些类里包含的方法。
网址:http://www.oracle.com/technetwork/java/javase/downloads/index.html
Additional Resources-Java SE 8 Documentation下载
(1)API文档:
API文档打开之后,点击显示 ------> 索引 -----> 查找自己想查找的结构
例如:Scanner类
- 在API文章中,会存在属性、构造器和方法三部分-----> 找到这些类成员可以点击查看(方法)内部结构
(1)正确注释和注释风格:
使用文档注释来注释整个类或整个方法。
如果注释方法中的某一个步骤,使用单行或多行注释。
(2)正确的缩进和空白:
使用一次tab操作,实现缩进。
运算符两边习惯性各加一个空格。比如:2 + 4 * 5。
(3)书写代码块的风格:
Java API 源代码选择了行尾风格
(1)文本编辑工具:
记事本;
UltraEdit;
EditPlus;(开始将会使用一段时间)
TextPad;
NotePad;
(2)Java集成开发环境:
ntegrated Development Environment:IDE
- JBuilder
- NetBeans
- Eclipse (会使用一段时间)
- MyEclipse
- IntelliJ IDEA(以后将会常使用)
(1)定义:
被Java语言赋予了特殊含义,用做专门用途的字符串(单词);
(2)特点: 官方地址
关键字中所有字母都为小写;
Java保留字:现有Java版本尚未使用,但以后版本可能会作为关键字使 用。自己命名标识符时要避免使用这些保留字 goto 、const;
Java 对各种变量、方法和类等要素命名时使用的字符序列称为标识符;
- 技巧:凡是自己可以起名字的地方都叫标识符。
(1)定义标识符的规则:
- 由26个英文字母大小写,0-9 ,_或 $ 组成 ;
- 数字不可以开头。
- 不可以使用关键字和保留字,但能包含关键字和保留字。
- Java中严格区分大小写,长度无限制。
- 标识符不能包含空格。
(2)定义标识符的规范:
**包名:**多单词组成时所有字母都小写:xxxyyyzzz
**类名、接口名:**多单词组成时,所有单词的首字母大写:XxxYyyZzz
**变量名、方法名:**多单词组成时;第一个单词首字母小写,第二个单词开始每个单词首字母大 :xxxYyyZzz
**常量名:**所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ
(3)注意:
在起名字时,为了提高阅读性,要尽量有意义,“见名知意”。
java采用unicode字符集,因此标识符也可以使用汉字声明,但是不建议使用。
(1)变量概念:
内存中的一个存储区域 ;
该区域的数据可以在同一类型范围内不断变化;
变量是程序中最基本的存储单元。包含变量类型、变量名和存储的值;
(2)变量作用:
用于在内存中保存数据;
(3)变量使用注意:
Java中每个变量必须先声明,后使用。
使用变量名来访问这块区域的数据 ;
变量的作用域:其定义所在的一对**{ }**内 ’
变量只有在其作用域内才有效 ;
同一个作用域内,不能定义重名的变量;
(4)变量声明:
语法:<数据类型> <变量名称>
例如:int var;
(5)变量赋值:
语法:<变量名称> = <值>
例如:var = 10;
(6)变量声明与赋值:
语法: <数据类型> <变量名> = <初始化值>
例如:int var = 10;
①基本数据类型(primitive type):
整数类型:byte、short、int、long
浮点类型:float、double
②应用数据类型 (reference type):
类:class
接口:interface
数组:[ ]
在方法体外,类体内声明的变量称为成员变量。 在方法体内部声明的变量称为局部变量。
①成员变量:
实例变量(不以static修饰)
类变量(以static修饰)
②局部变量:
形参(方法、构造器中定义的变量)
方法局部变量(在方法内定义)
代码块局部变量(在代码块内定义)
③注意:二者在初始化值方面的异同:
同:都有生命周期(作用域),都需要先声明后使用。
异:局部变量除形参外,需显式初始化,才能进行运算,成员变量会有默认值。
(bit: 计算机中的最小存储单位。byte:计算机中基本存储单元。)
- byte:1字节=8bit (-128-127)
byte b1=-128; //声明byte变量并赋值
byte b2=127;
//byte b3=128; //编译不通过,超出byte变量的容量大小;
- short:2字节=16bit (-215—215-1)
short s1=332; //声明short变量并赋值
short s2=333;
- int:4字节=32bit(-231—231-1)
//声明并赋值
int i1=334; //声明int变量并赋值
//先声明,后赋值
int i2; //声明int变量
i2=44; //int变量赋值;
- long:8字节=64bit(-263—263-1)
注意:定义long变量时,其赋于值必须以“L”或“l”结尾;
//声明long类型数据,赋值时,必须使用L或者l后缀
long l1=333L; //声明long变量并赋值;
long l2=847L;
总结:java中整型默认常量是int,声明long常量其后需要加“L”或“l”
- float:单精度[4字节= 32bit(-3.403E38 ~ 3.403E38)]
注意:定义float变量时,其赋于值必须以“f”或“F”结尾;
float f1=23.23f; //声明float变量并赋值;
//float f2=23.23; //类型不匹配,编译不通过(浮点型变量的默认类型为double类型)
-double:双精度(8字节 = 64bit)
//注意:初始化过程中不能超出其类型的最大存储范围
double d1=88.34;
总结:java中浮点型默认常量是double,声明float常量其后需要加“f”或“F”
- char: 一个字符=2字节
使用:①一个字符、②一个转义字符、③直接使用Unicode值表示字符常量
//普通字符
char c1='a';
char c2='中';
char c3='3';
//转义字符
char c4='\t'; //\t是制表符
char c5='\n'; //\n:换行符
//使用Unicode码
char c6='\u0094'; //Unicode值(Unicode码包含ASCII码)
char c7=97; //表示字符a;
注意:
- Unicode:一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一 无二的编码,使用 Unicode 没有乱码的问题。
- UTF-8 是在互联网上使用最广的一种 Unicode 的实现方式。
boolean:boolean类型数据只允许取值true和false,无null;
boolean 类型用来判断逻辑条件,一般用于程序流程控制:
- if条件控制语句;
- 三目运算符:(表达式1>表达式2)? 取值1:取值2;
- while循环控制语句;
- do-while循环控制语句;
- for循环控制语句;
//注意:boolean类型变量初始化,只能时true或者false
//boolean类型变量的默认值是false(属性,数组元素)
boolean b1 = true;
boolean b2 = false;
字符串数据类型:String
- 使用方式与基本数据类型一致。例如:String str = “abcd”( 或String str = new String(“abcd”); );
- 一个字符串可以串接另一个字符串,也可以直接串接其他类型的数据;其连接得到的结果都为字符串类型。
//其他数据类型变量与字符串类型变量进行连接时,其结果都为字符串;
String s1="str";
String s2="ing";
String s3=s1+s2;
System.out.println(s3); //string
int i1=33;
String s4=s1+i1;
System.out.println(s4); //str33
注意:String类型变量与其它八种基本数据类型进行“+”操作,表示连接;
//接口的定义方式
public interface Test{ }
//接口需要其他类来实现(略)
//一维数组的声明方式:
int [] arr = new int[3]; //动态赋值
//.......
容量小的类型自动转换为容量大的数据类型。数据类型按容量大小排序为:
- 注意:此时容量大小指:表示可数的范围大小;
- byte,short,char之间不会相互转换,他们三者在计算时首先转换为int类型。
- boolean类型不能与其它数据类型运算。
- 当把任何基本数据类型的值和字符串(String)进行连接运算时(+),基本数据类型的值将自动转化为字符串(String)类型。
byte b1=22; byte b2=21; short s1=33; char c1='a'; //byte、short、char之间不会相互转换 int i4=b1+b2; int i3=c1+s1; int i2=b1+s1; int i1=23; long l1=44l; float f1=32.3f; double d1=23.3; //自动类型提升:容量小的->容量大的 i1=b1; i1=s1; i1=c1; long l2=i1; float f2=i1; double d2=f1;
- 自动类型提升逆过程,表示容量大到容量小的;(此时容量大小指:表示可数的范围大小)
- 使用时要加上强制转换符:(),但可能造成精度降低或溢出,格外要注意;
- 数据类型 变量名 = (数据类型)变量值;
int i1=33;
char c1=22;
long l1=33l;
float f1=44.3f;
char c2=(char)i1;
int i2=(int)l1;
int i3=(int)f1;
- boolean类型不可以转换为其它的数据类型。
- 字符串不能直接转换为基本类型,但通过基本类型对应的包装类则可 以实现把字符串转换成基本类型。
String s="233";
int i1=Integer.parseInt(s); //调用包装类中的parseInt()方法
- 所有数字在计算机底层都以二进制形式存在;
(1)对于整数,有四种表示方式:
- 二进制(binary):0,1 ,满2进1.以0b或0B开头。
- 十进制(decimal):0-9 ,满10进1。
- 八进制(octal):0-7 ,满8进1. 以数字0开头表示。
- 十六进制(hex):0-9及A-F,满16进1. 以0x或0X开头表示。此处的A-F不区分大小写。 如:0x21AF +1= 0X21B0
原码:直接将一个数值换成二进制数。最高位是符号位 ;
负数的反码:是对原码按位取反,只是最高位(符号位)确定为1。
负数的补码:其反码加1。
计算机以二进制补码的形式保存所有的整数。
正数的原码、反码、补码都相同 。
负数的补码是其反码+1注意:补码—->原码(过程相反:补码—[除符号位其他位取反]—-> 反码—[+1]——>原码)
二进制——>八进制或十六进制:
- 将二进制的三位或四位转换为八进制或十六进制的一位,逆转换只需逆过程
- 运算符的种类:算术、赋值、比较(关系)、逻辑、位、三元运算符
- 运算符号:+(负号)、-(正号)、+、-、/、%、++、–、+(字符串连接)
(1)算术运算符需要注意:
- 取模时,模数的正负号取决于被模数。
- %:如果对负数取模,可以把模数负号忽略不记,如:5%-2=1。 但被模数是负数则不可忽略。此外,取模运算的结果不一定总是整数;
- (前)++:先自增一,后再运算;
- (后)++:先运算,后自增一;
- (前)–:先自减一,后再运算;
- (后)–:先运算,后再自减一;
int num1=22;
int num2=num1++;
System.out.println(num2); //22
int num3=++num1;
System.out.println(num3); //23
运算符号:=、-=、+=、*=、/=、%=
(1)注意:
- 当“=”两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理。支持连续赋值;
- +=、-=、+=、*=、/=、%=运算时,并不会改变其原来的数据类型;
int num1=10;
num1+=2; //int型的12
byte b1=12;
// b1=b1+2; //类型不匹配,编译不通过(由式子的右边为int类型)
b1+=2; //编译通过,值为byte型14;
int num2=15;
num2%=2; //int型的1;
运算符号:== 、!=、>、<、>=、<=、interface
- 运算结果:都是boolean型,也就是要么是true,要么是false。
- >、<、>=、<=:只能使用在数值类型数据之间。
- ==、!=:既可以使用在数值类型数据之间,也可以使用在引用数据类型之间;
(1)代码演示:
//创建两个对象:account1 和 account2
Account account1= new Account(100);
Account account2= new Account(200);
boolean result= (account1==account2); //false:地址值不同
int num1=23;
boolean b1=true;
if(b1==true){
System.out.println(“结果为真”);
}else{
System.out.println(“结果为假”);
}
if(num1>10){
System.out.println(“结果为真”);
}else{
System.out.println(“结果为假”);
}
运算符号:& 、&&、|、||、!、^
(1)注意:
- 两者运算结果一致;
- 若左边结果为true,&和&&都会执行右边;
- 若左边运算结果为false,&会继续执行右边,而&&不会继续执行右边运算;
int num1=12; boolean b1=true;//b1=false if(b1==true & ++num1>11){ }else{ } System.out.println(num1); //13(b1为true) 13(b1为false) int num2=12; boolean b2=true;//b2=false if(b2==true && ++num2>11){ }else{ } System.out.println(num2); //13(b2为true时) 12(b2为false时)
- 两者运算结果一致;
- 若左边结果为false,| 和 || 都会执行右边;
- 若左边结果为true,| 会继续执行右边,而 || 不会继续执行右边运算;
int num3=10; boolean b3=true; if(b3==true | ++num3>9){ }else{ } System.out.println(num3); //11 int num4=10; boolean b4=true; if(b4==true || ++num4>9){ }else{ } System.out.println(num4); //10
- 注意:异或( ^ )与或( | )的不同之处是:当左右都为true时,结果为false。
运算符号:<<、>>、>>>、&、|、^、~:位运算是直接对整数的二进制进行的运算。
(1)位运算符操作的对象都是整型的数据:
- 在一定范围内,左移多少为,就是乘于2的多少次方;
- 8<<2 ——> 8*22
- 在一定范围内,右移多少为,就是除以2的多少次方;
- 8>>2 ——> 8/22
^(异或运算):
注意:
- num3=num1^num2;
- mum1=num3^num2;
(1)格式:
(条件表达式)?表达式1:表达式2;
- 条件表达式为true时,则执行表达式1;否则执行表达式2;
(2)注意:
- 三元运算符可简化if-else语句 。
- 三元运算符要求必须返回一个结果。
- if后的代码块可有多个语句。
- 程序从上到下逐行地执行,中间没有任何判断和跳转。
- 根据条件,选择性地执行某段代码。有if…else和switch-case两种分支语句。
if(条件表达式){
//执行语句;
}
if(条件表达式){
//执行语句1;
}else{
//执行语句2;
}
if(条件表达式1){
//执行语句1;
}else if(条件表达式2){
//执行语句2;
}else if(条件表达式3){
//执行语句3;
}else if(条件表达式4){
//.............
}else{
//执行语句n;
}
- 条件表达式必须是布尔表达式(关系表达式或逻辑表达式)、布尔变量;
- 语句块只有一条执行语句时,一对{ }可以省略,但建议保留;
- if-else语句结构,根据需要可以嵌套使用;
- 当if-else结构是“多分支”时,最后的else是可选的,根据需要可以省略;
- 当多个条件是“互斥”关系时,条件判断语句及执行语句间顺序无所谓 ,当多个条件是“包含”关系时,“小上大下 / 子上父下”;
- 导包:import java.util.Scanner;
- Scanner类的实例化:Scanner scanner = new Scanner(System.in);
- 调用Scanner类的方法:**scanner.nextXxxx( ); ** ,来获取某一类型的值;
- 获取byte、short、int、long、float、double值,只需Scanner对象调用Scanner类的方法;格式:对象名.nextXxx( );
- 获取String类型的值,只需对象名.next( ); 即可,注意,在键盘中我们不能直接获取char类型的值,而需要先获取String类型的值,在调用String类中的方法来获取char类型的值;格式:String对象名.charAt( 索引号);
- Math.random( ); ——> 所得double型变量数值的范围:[ 0.0 , 1.0)
- 若需得到int型变量[a , b]范围的数:需要,(int)(Math.random( )*(b-a+1)+a)
Random ran = new Random();
int num=ran.nexInt(number); //此时生成的随机数为0~number-1
switch(表达式){
case 常量1:
语句1;
//break;
case 常量2:
语句2;
//break;
case 常量3:
语句3;
//break;
.......
default :
//break;
}
- switch(表达式)中表达式的值必须是下述几种类型之一:byte,short,char,int,枚举 (jdk 5.0),String (jdk 7.0);
- case子句中的值必须是常量,不能是变量名或不确定的表达式值;
- 同一个switch语句,所有case子句中的常量值互不相同;
- break语句用来在执行完一个case分支后使程序跳出switch语句块;如果没有break,程序会顺序执行到switch结尾 ;
- default子句是可任选的。同时,位置也是灵活的。当没有匹配的case时, 执行default;
- 如果判断的具体数值不多,而且符合byte、short 、char、int、String、枚举等几 种类型。虽然两个语句都可以使用,建议使用swtich语句。因为效率稍高。
- 其他情况:对区间判断,对结果为boolean类型判断,使用if,if的使用范围更广。 也就是说,使用switch-case的,都可以改写为if-else。反之不成立。
- 主要结构:while、do…while、for
- 根据循环条件,重复性的执行某段代码。
循环四个组成部分:
- ①初始化条件;
- ②循环条件;——boolean型
- ③循环体;
- ④迭代条件;
for(①初始化条件; ②循环条件 ; ④迭代条件){
③循环体;
}
执行过程:
①——②——③——④——②——③——④——②——③——④…——②——③——④
说明:(以下序号为循环组成部分代号)
- ②循环条件部分为boolean类型表达式,当值为false时,退出循环 ;
- ①初始化部分可以声明多个变量,但必须是同一个类型,用逗号分隔;
- ④可以有多个变量更新,用逗号分隔;
- 在循环中一旦执行到break关键字就跳出循环;
①初始化条件;
while(②循环条件){
③循环体;
④迭代条件;
}
执行过程:
①——②——③——④——②——③——④——②——③——④……——②——③——④
说明:
- 注意不要忘记声明④迭代部分。否则,循环将不能结束,变成死循环。
- for循环和while循环可以相互转换。
①初始换条件;
do{
③循环体;
④迭代条件;
}while(②循环条件);
执行过程:
①——③——④——②——③——④——②……——③——④——②
说明:
- do-while循环结构中的循环体至少执行一次;
- 将一个循环放在另一个循环体内,就形成了嵌套循环。其中, for ,while ,do…while均可以作为外层循环或内层循环。
- 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的 循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开 始下一次的循环。
- 设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次。
- 外层循环表示行,内层循环表示列;
break语句用于终止某个语句块的执行
{
……
break;
……
}
break语句出现在多层嵌套的语句块中时,可以通过标签指明要终止的是哪一层语句块:
label1: { ……
label2: { ……
label3: { ……
break label2;
……
}
}
}
- continue只能使用在循环结构中;
- continue语句用于跳过其所在循环语句块的一次执行,继续下一次循环;
- continue语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环;
public class ContinueTest {
public static void main(String args[]){
for (int i = 0; i < 10; i++) {
if (i%2==0){
continue; //跳出当次循环
}
System.out.print(i+" ") ; // 1 3 5 7 9
}
}
}
- break只能用于switch语句和循环语句中。
- continue 只能用于循环语句中。
- 二者功能类似,但continue是终止本次循环,break是终止本层循环。
- break、continue之后不能有其他的语句,因为程序永远不会执行其后的语句。
- 标号语句必须紧接在循环的头部。标号语句不能用在非循环语句的前面。
- 很多语言都有goto语句,goto语句可以随意将控制转移到程序中的任意一条语句上,然后执行它。但使程序容易出错。Java中的break和continue是不同于goto的。
- return: 并非专门用于结束循环的,它的功能是结束一个方法。 当一个方法执行到一个return语句时,这个方法将被结束。
- 与break和continue不同的是,return直接结束整个方法,不管这个return处于多少层循环之内;
(1) 数组(Array):
- 是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
(2) 数组的常见概念:
- 数组名;
- 下标(或索引);
- 元素;
- 数组长度;
(3) 数组介绍:
- 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
- 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
- 数组的长度一旦确定,就不能修改。
- 我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。
- **按照维度:**一维数组、二维数组、三维数组、…。
- **按照元素的数据类型分:**基本数据类型元素的数组、引用数据类型元素的数组(即对象数组)。
int arr [];
int []arr1;
char []arr2;
double []b;
String []arr3; //字符串类型变量数组(引用类型变量数组)
- 数组声明且为数组元素分配空间与赋值的操作分开进行:
//例如:
int []arr=new int[4];
int [0]=1;
int [1]=2;
int [2]=3;
int [3]=4;
String [] names;
names= new String[3];
names[0]="于敏";
names[1]="钱学森";
names[2]="程开甲";
- 在定义数组的同时就为数组元素分配空间并赋值。
//例如:
int [] arrs= new int[]{1,2,3,4};
//int []arrs={1,2,3,4}
String []names= new String[]{"于敏","钱学森","程开甲"};
//String []names={"于敏","钱学森","程开甲"};
(1)定义并用运算符new为之分配空间后,才可以引用数组中的每个元素;
(2)数组元素的引用方式:数组名[数组元素下标]
- 数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6*i];
- 数组元素下标从0开始;长度为n的数组合法下标取值范围: 0 —>n-1;如int a[]=new int[3]; 可引用的数组元素为a[0]、a[1]、a[2]。
(3)每个数组都有一个属性length指明它的长度,例如:a.length 指明数组a的长度(元素个数)。
- 数组一旦初始化,其长度是不可变的;
- 数组是引用类型,它的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化。
public class Array{
public static void main(String [] args){
int [] arr= new int[3];
System.out.println(arr[2]); //arr[2]默认值为0
}
}
- 对于基本数据类型而言,默认初始化值各有不同;
- 对于引用数据类型而言,默认初始化值为null(注意与0不同!)
栈(stack)和堆(heap)结构:
- 栈: (stack):局部变量;
- 堆:(heap):new出来的结构:对象、数组;
(1)Java 语言里提供了支持多维数组的语法。
(2)如果说可以把一维数组当成几何中的线性图形, 那么二维数组就相当于是一个表格,像右图Excel 中的表格一样。
(3)对于二维数组的理解,我们可以看成是一维数组 array1又作为另一个一维数组array2的元素而存在。其实,从数组底层的运行机制来看,其实没有多维数组。
(4)数组的length属性;(获取数组的长度,即一维数组的个数和一维数组中元素的个数)
(5) 二维数组值中数组元素的初始化值和一维数组类似;
- byte、short、int、long——>0;
- float、double——>0.0;
- char——> 0 (ascll码中的’\u0000’);
- boolean——> false;
- 引用数据类型——> null或者地址;
(1)动态初始化:
int [][]arr= new int[3][2];
//代码说明:
//定义了名称为arr的二维数组
//二维数组中有3个一维数组
//每一个一维数组中有2个元素
//一维数组的名称分别为arr[0], arr[1], arr[2]
//给第一个一维数组1脚标位赋值为78写法是:arr[0][1] = 78;
int [][]arr= new int [3][];
//代码说明:
// 二维数组中有3个一维数组。
//每个一维数组都是默认初始化值null (注意:区别于格式1)
//可以对这个三个一维数组分别进行初始化
arr[0] = new int[3];
arr[1] = new int[1];
arr[2] = new int[2];
// 注意:
// int[][]arr = new int[][3]; //非法
(2)静态初始化:
int [][]arr= new int[][]{{3,8,2},{2,7},{9,0,1,6}};
//代码说明:
//定义一个名称为arr的二维数组,二维数组中有三个一维数组
//每一个一维数组中具体元素也都已初始化
//第一个一维数组 arr[0] = {3,8,2};
//第二个一维数组 arr[1] = {2,7};
//第三个一维数组 arr[2] = {9,0,1,6};
//第三个一维数组的长度表示方式:arr[2].length;
//注意特殊写法情况:
//int[] x,y[]; x是一维数组,y是二维数组。
//Java中多维数组不必都是规则矩阵形式
- 栈(stack):存放局部变量;
- 堆(heap):存放new出来的结构(数组、对象);
- 方法区:静态域+常量池;
(1)举例一:
//举例代码:
int[][] arr1 = new int[4][];
arr1[1] = new int[]{1,2,3};
arr1[2] = new int[4];
arr1[2][1] = 30;
(2)举例二:
//举例代码:
int[][] arr1 = new int[4][];
arr1[0] = new int[3];
arr1[1] = new int[]{1,2,3};
arr1[0][2] = 5;
arr1 = new int[2][];
- 数组元素的赋值(杨辉三角、回形数等) ;
- 求数值型数组中元素的最大值、最小值、平均数、总和等;
- 数组的复制、反转、查找(线性查找、二分法查找) ;
- 数组元素的排序算法;
(1)杨辉三角、回形数(略)等
//代码实现: int [][]yanghui= new int[10][]; //2.给数组元素赋值: for(int i=0;i<yanghui.length;i++) { // yanghui[i]= new int[i+1]; //方式一: //2.1:给首末尾元素赋值: yanghui[i][0]=yanghui[i][i]=1; //2.2:给非首末元素赋值: for(int j=1;j<yanghui[i].length-1;j++) { yanghui[i][j]=yanghui[i-1][j-1]+yanghui[i-1][j]; } //方式二: /* for(int j=0;j<yanghui[i].length;j++){ if(j==0 || i==j){ yanghui[i][j] = 1; //给首末尾元素赋值; }else{ yanghui[i][j]=yanghui[i-1][j-1]+yanghui[i-1][j]; //给非首末元素赋值 } } */ //3.遍历数组: for(int j=0;j<yanghui[i].length;j++) { System.out.print(yanghui[i][j]+" "); } System.out.println(); }
注意:
- 是将数组元素依次遍历下去,再查找是否有符合的元素;对于数值类型的变量而言,这样的查找效率非常低,而应该考虑二分查找的方式;
//代码演示:
int []array=new int []{1,2,3,5,4};
int dest=1; //需要查找的元素
boolean isFlag=true; //记录元素最终是否被查到的标签
for(int i=0;i<array.length;i++){ //遍历数组
if(dest==array[i]){
isFlag=false;
System.out.println("找到了,索引为:"+i);
break;
}
}
if(isFlag){
System.out.println("抱歉未找到");
}
- 前提: 数组元素排好序;
- 说明:是通过比较数组元素的中间值来进行查找元素的,这样大大的提高查找的效率;
- 局限:只适用于数值数据类型;
代码演示:
int []arr= new int []{1,2,3,4,5,6,7}; boolean isFlag=true; int dest=6; //目的值 int head=0; //初始首索引 int end=arr.length-1; //初始尾索引; while(head<=end){ int middle=(head+end)/2; //if条件分支中,进行数组元素的中间值和目的值进行比较 if(dest=arr[middle]){ System.out.println("找到了,索引位置为:"+middle); isFlag=false; break; }else if(dest>arr[middle]){ head=middle+1; }else{ end=middle-1; } } if(isFlag){ System.out.println("未找到"); }
① 排序解释:
- 假设含有n个记录的序列为{R1,R2,…,Rn},其相应的关键字序列为 {K1,K2,…,Kn}。将这些记录重新排序为{Ri1,Ri2,…,Rin},使得相应的关键 字值满足条Ki1<=Ki2<=…<=Kin,这样的一种操作称为排序。
- 通常来说,排序的目的是快速查找。
② 衡量排序算法的优劣:
- 时间复杂度:分析关键字的比较次数和记录的移动次数;
- 空间复杂度:分析排序算法中需要多少辅助内存;
- 稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的。
③ 排序算法分类:内部排序和外部排序:
- 内部排序:整个排序过程不需要借助于外部存储器(如磁盘等),所有排序操作都在内存中完成。
- 外部排序:参与排序的数据非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助于外部存储器(如磁盘)。外部排序最常见的是多路归并排序。可以认为外部排序是由多次内部排序组成。
④ 十大内部排序算法:
i. 选择排序:
直接选择排序、堆排序
ii. 交换排序:
冒泡排序、快速排序
iii. 插入排序 :
直接插入排序、折半插入排序、Shell排序
iv. 归并排序
v. 桶式排序
vi. 基数排序
⑤ 算法介绍:
算法的五大特征:
- 说明:满足确定性的算法也称为:确定性算法。现在人们也关注更广泛的概念,例如考虑各种非确定性的算法,如并行算法、概率算法等。另外,人们也关注并不要求终止的计算描述,这种描述有时被称为过程(procedure)。
①冒泡排序:
- 冒泡排序的原理非常简单,它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。
- 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较为止。
//冒泡排序:
for(int i=0;i<array.length-1;i++) { //1.需要比较的轮数:
for(int j=0;j<array.length-1-i;j++) {//2.每一轮中需要比较的次数:
if(array[j]>array[j+1]) {
int temp=array[j];
array[j]=array[j+1];
array[j+1]=temp;
}
}
}
② 快速排序:
- 快速排序(Quick Sort)由图灵奖获得者Tony Hoare发明,被列为20世纪十 大算法之一,是迄今为止所有内排序算法中速度最快的一种。冒泡排序的升 级版,交换排序的一种。快速排序的时间复杂度为O(nlog(n))。
- 从数列中挑出一个元素,称为基准(pivot)
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准 值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后, 该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
- 递归的最底部情形,是数列的大小是0或1,也就是永远都已经被排序好 了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代 (iteration)中,它至少会把一个元素摆到它最后的位置去。
//交换数组元素的值 private static void swap(int[] data, int i, int j) { int temp = data[i]; data[i] = data[j]; data[j] = temp; } private static void subSort(int[] data, int start, int end) { if (start < end) { int base = data[start]; int low = start; int high = end + 1; while (true) { while (low < end && data[++low] - base <= 0); while (high > start && data[--high] - base >= 0); if (low < high) { swap(data, low, high); } else { break; } } swap(data, start, high); subSort(data, start, high - 1);//递归调用 subSort(data, high + 1, end); } } public static void quickSort(int[] data){ subSort(data,0,data.length-1); }
① 直接插入排序:
- 把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。
//直接插入排序
for(int i=0;i<array.length-1;i++) { //1.需要比较的轮数:
for(int j=i+1;j > 0;j--) {//2.每一轮中需要比较的次数:
if(array[j]< array[j-1]) { //需要插入的元素是否小于有序元素
int temp=array[j];
array[j]=array[j-1];
array[j-1]=temp;
}else{
break; //当无序中的元素大于有序元素的元素时,直接介绍比较
}
}
}
② 希尔排序:
- 希尔排序的基本思想:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上有较大提高。
① 简单选择排序:
- 在一组元素R[i]到R[n]中选择具有最小关键码的元素若它不是这组元素中的第一个元素,则将它与这组元素中的第一个元素对调。除去具有最小关键字的元素,在剩下的元素中重复第(1)、(2)步,直到剩余元素只有一个为止。
//假定第一元素为最小;则将第一个元素依次和其后的元素进行比较,选出最小的元素,方法第一个元素处;以此循环,选出第二小的元素放于第二个元素处。
//注意:将该嵌套循环封装在方法中
for(int i=0;i<arr.length-1;i++){ //需要比较的轮数
for(int j=i+1;j<arr.length;j++){ //每轮需要比较的次数
if(arr[i]>arr[j]){ //该处元素依次和其后的元素进行比较
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
② 堆排序:
建立初始堆:
- 将排序码k1,k2k3,…,kn,表示成一棵完全二叉树,然后从第[n/2]个排序码(即树的最后一个非终端结点)开始筛选,使由该结点作根结点组成的子二叉树符合堆的定义,然后从第(n/2) -1个排序码重复刚才操作,直到第一个排序码止。这时候,该二叉树符合堆的定义,初始堆已经建立。
堆排序:
- 将堆中第一个结点(二叉树根结点)和最后一个结点的数据进行交换(k1与kn),再将k1~ kn-1重新建堆,然后k1和kn-1交换,再将k1~kn-2 重新建堆,然后k1,和kn-2交换,如此重复下去,每次重新建堆的元素个数不断减1,直到重新建堆的元素个数仅剩一个为止。这时堆排序已经完成,则排序码k1,k2,k3,…,kn已排成一个有序序列。
是多次将了两个或两个以上的有序表合并成一个新的有序表。最简单的归并是直接将两个有序的子表合并成一个有序的表,即二路归并。
- 是将R[0……n-1]看成是n长度为1的有序序列,然后进行两两归并,得到[n/2]个长度为2(最后一个有序序列的长度可能为2)的有序序列,再进行两两归并,得到[n/4]个长度为4(最后一个有序序列的长度可能为4)的有序序列,……,直到得到长度为n的有序序列。
- 从平均时间而言:快速排序最佳。但在最坏情况下时间性能不如堆排序和归 并排序。
- 从算法简单性看:由于直接选择排序、直接插入排序和冒泡排序的算法比较 简单,将其认为是简单算法。对于Shell排序、堆排序、快速排序和归并排序 算法,其算法比较复杂,认为是复杂排序。
- 从稳定性看:直接插入排序、冒泡排序和归并排序时稳定的;而直接选择排 序、快速排序、 Shell排序和堆排序是不稳定排序。
- 从待排序的记录数n的大小看:n较小时,宜采用简单排序;而n较大时宜采用改进排序。
- 若n较小(如n≤50),可采用直接插入或直接选择排序。 当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插入,应选直接选择排序为宜。
- 若文件初始状态基本有序(指正序),则应选用直接插入、冒泡或随机的快速排序为宜;
- 若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或 归并排序。
- java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。
(1)代码演示:
import java.util.Arrays; //工具类Arrays中方法的使用: int []arr=new int[] {1,23,3,4,5,5,8}; int []arr1=new int[] {-12,23,-88,3,78,98,4,-34,-13}; //1. boolean equals(int[] a,int[] b):判断两个数组是否相等。 System.out.println(Arrays.equals(arr, arr1)); //2. String toString(int[] a):输出数组信息。 System.out.println(Arrays.toString(arr1)); System.out.println(Arrays.toString(arr)); //3. void fill(int[] a,int val) :将指定值填充到数组之中。 Arrays.fill(arr, 8); System.out.println(Arrays.toString(arr)); //4. void sort(int[] a):对数组进行排序。 Arrays.sort(arr1); System.out.println(Arrays.toString(arr1)); //[-88, -34, -13, -12, 3, 4, 23, 78, 98] //5. int binarySearch(int[] a,int key):对排序后的数组进行二分法检索指定的值。 int number=Arrays.binarySearch(arr1, -88); //值返回为负数,表示未找到; System.out.println(number);
(1)数组脚标越界异常(ArrayIndexOutOfBoundsException):
int[] arr = new int[2];
//System.out.println(arr[2]); //运行不通过,数组角标越界
//System.out.println(arr[-1]); //运行不通过,数组角标越界
//访问到了数组中的不存在的脚标时发生。
(2)空指针异常(NullPointerException):
//举例说明:
int[] arr = null;
//System.out.println(arr[0]);
int [] [] arr2 = new int [3][4];
arr[2] = null;
//arr[2].length; //报异常
//arr引用没有指向实体,却在操作实体中的元素时。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。