此笔记学习于慕课网:Java入门第一季-第三季,想学的可以点击链接进行学习,笔记仅为私人收藏
建议学习时间:2-3天(极速版)
数据类型
基本数据类型存的是数据本身
引用类型变量(class、interface、数组)存的是数据的空间地址
自动类型转换
- 目标类型能与源类型兼容
- 目标类型大于源类型
强制类型转换
- 丢失数据(不 四舍五入)
常量
- 语法:final 常量名 = 值;
- 一般大写
注释
/**
* 这是文档注释
* @author laorenyang
* @version v1.0
*/
/*
* 这是多行注释
* aaa
* bbb
*/
//这是单行注释
怎么生成API文档
- 我们可以通过javadoc命令从文档注释中提取内容,生成程序的API帮助文档
- 使用javadoc标记
运算符
- 比较运算符:比较后的值是布尔值
- 逻辑运算符
- 条件运算符 ?:
String str = (8>5) ? "8>5" : "8 <= 5"
Scanner类 java.util
数组
- 声明数组
int[] scores;
int height[];
- (不规则数组)
int[][] num=new int[3][];
num[0] = new int[3];
num[1] = new int[2];
num[2] = new int[1];
- 分配空间
scores = new int[5];
int[] scores = new int[5]
int[] scores = {1, 2};
int[] scores = new int[]{1, 2};
- 长度
数组名.length
Arrays类 java.util 操作数组
- Arrays.sort();
- Arrays.toString();
foreach :for的简版
for(int num:nums) {
System.out.println(num);
}
方法(method)
- 使用类中的方法
- 方法的重载 一个类中有多个方法名相同的方法
- 判断方法重载的依据:
- 必须是在同一个类中
- 方法名相同
- 方法参数的个数、顺序或类型不同
- 与方法的修饰符或返回值没有关系
随机数 Math.random()
0-1浮点数
类
- 模板 抽象信息 描述
- 类 对象的类型,一个模子
- 一个类可以对应多个对象
对象
具体的信息
- 对象的属性:对象有什么 特征
- 对象的方法:对象执行的操作
类
定义类
- 类的组成:属性和方法
- 定义一个类
- 属性(有什么)
- 方法(干什么)
对象
- 创建一个对象 : 对一个类进行实例化 new Telphone() (new + 构造方法())
- 使用对象: 引用对象的属性:对象名.属性;引用对象的方法:对象名.方法名()
属性(实例变量)
- float型变量赋值时需加f,否则默认浮点数是double型
成员变量和局部变量
成员变量
- 在类中定义
- 被本类的方法,及其他跟本类相关的类中的方法使用
局部变量
在方法中定义
区别
- 初始值不同:成员变量有默认的初始值,局部变量没有
- 两类变量同名时,局部变量具有更高的优先级(就近原则)
构造方法
无返回类型 (不写)
- 构造方法的重载
- 构造方法不但可以给对象的属性赋值,还可以保证给对象的属性赋一个合理的值
static 静态
静态变量
- 该类所有对象所共享,属于整个类(所以在系统第一次使用该类时,就会为其分配内存空间直至该类被卸载,才进行资源回收)
- 可用类名来进行访问(或者对象名,推荐前者)
- 修饰变量、方法、代码块
静态方法
- 静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员
- 可以通过在方法里面 创建类的对象,然后通过对象来访问非静态变量,形式:hello.name
- 在普通方法中两者皆可直接调用
- 同理,静态方法中不能直接调用非静态方法,可以通过对象来访问非静态方法,形式:hello.show()
静态内部类
- 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
- 如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员
- 创建静态内部类的对象时,不需要外部类的对象,可以直接创建内部类 对象名= new 内部类();
静态初始化块
- 静态初始化块只在类加载时执行一次,且只能给静态变量赋值
初始化执行顺序
- 静态初始化块 -> 初始化块 -> 构造方法
面向对象
三大特性
- 封装 继承 多态
封装
- 修改属性的可见性:设为private
- 创建getter/setter方法:用于属性的读写
- 在getter/setter方法中加入属性控制语句:对属性值的合法性进行判断
包
- 全小写
- protected 子类也可以用
this关键字
- 代表当前对象
- 当前对象的属性、方法
- 封装对象属性时可用
内部类
- 内部类( Inner Class )就是定义在另外一个类里面的类。与之对应,包含内部类的类被称为外部类。
- 内部类的主要作用如下:
- 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,[不允许同一个包中的其他类访问该类???(那怎么可以用public修饰)]
- 内部类的方法可以直接访问外部类的所有数据,包括私有的数据
- 内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便
成员内部类
- 使用外部类对象创建内部类对象
Inner i = o.new Inner();
- 成员内部类的 .class 文件总是这样:外部类名$内部类名.class
- 外部类是不能直接使用内部类的成员和方法滴
- 可先创建内部类的对象,然后通过内部类的对象来访问其成员变量和方法。
- 如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,可以使用 this 关键字。这个外部类的对象的成员变量 Outer.this.name (静态内部类不用写this)
静态内部类
- static修饰
方法内部类
- 内部类定义在外部类的方法中
- 由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。
- 调用方法内部类的办法是:在所在的外部类方法里调用,在其他类调用该内部类方法时调用所在外部类方法即可
继承
- 类与类的一种关系 is a 的关系
- 一个类只有一个父类
- 子类不能继承父类中private属性的东西
方法的重写
- 返回值类型、方法名、参数类型及个数要一致
继承的初始化顺序
- 初始化父类再初始化子类(构造方法)
- 先执行初始化对象中属性,再执行构造方法的初始化
final
- 最终的
- 修饰类、方法、属性和变量
- 修饰类,该类不允许被继承
- 修饰方法,该方法不允许被覆盖(重写)
- 修饰属性,该属性不会默认进行初始化,属性值被赋一次后不能变化,只能在一开始或者构造函数里进行人工的初始化。
- 修饰变量,变量的值只能赋一次值,即声明的时候赋值,常量
属性与变量的区别?
super
在对象的内部使用,可以代表父类对象
调用父类的属性:super.age
调用父类的方法:super.eat()
子类的构造的过程当中必须调用其父类的构造方法,会有隐式的写有
如果子类的构造方法没有显示调用父类的构造方法,则系统默认调用父类无参的构造方法
如果显示的调用构造方法,必须在子类的构造方法的第一行
如果子类构造方法中既没有显式的调用父类的构造方法,而父类又没有无参的构造方法,则编译出错!
Object类
- 所有类的父类
toString()方法
- 返回对象的哈希code码(对象地址字符串)
- 可重写
equals()方法
- 比较的是对象的引用是够指向同一块内存地址 Dog dog = new Dog()
- 一般我们想比较的是两个对象的值是否一致,可重写
- == 判断数据值是否相同,若判断引用值是否相同则也是比较地址值
- 类对象obj.getClass()与类的对象obj,前者关注例如姓名年龄,后者关注阿宝20岁
多态
- 对象具有多种形态
- 继承是多态的实现基础
引用多态
- 引用的指向:可以是本类,也可以是子类
- 父类的引用可以指向本类或子类的对象
方法多态
- 调用的方法:可以是本类,也可以是本类重写父类的方法或者是继承的方法
引用类型转换
- 小类型到大类型的转换(自动类型)
- 大类型到小类型的转换(强制类型)
强制类型转换
- instanceof运算符:避免类型转换的安全性问题
抽象类
用abstract修饰
限制规定子类实现某些方法,但不关注里面的内容
abstract定义抽象类 或 抽象方法
包含抽象方法的类必须是抽象类
抽象类中可以有或者没有抽象方法
抽象类不能直接创建,可以定义引用变量??
抽象方法没有{},直接以;结束
接口
- 特殊的类,由全局常量(public static final)和公共的抽象方法(public avstract)所组成
- 定义了类所需要遵守的规范
- 定义接口:使用interface关键字(不是class)
- 接口的修饰符推荐是public
- 接口可继承多个父接口
使用接口
implements
一个类可以实现多个接口
继承父类要在实现接口之前,即:extends 父类 implements 接口1,接口2...
接口名 I打头
接口的引用可以使用实现接口功能的类
可以与匿名内部类配合使用
使用匿名内部类来实现接口
- 没有名字的内部类
Interface i = new Interface(){
public void method(){
System.out.println("匿名内部类实现接口的方式");
}
};
UML简介
- Unified Modeling Language 统一建模语言
- 模型化软件开发的图形语言
常用UML图
用例图
- 描述系统中出现的角色需要什么功能 角色与系统的功能联系起来
序列图(the seque diagram)
角色和计算机内存中对象的关系,及顺序怎样
类图(The Class Diagram)
业务逻辑和结构性的信息
类和类的关系,及里面的属性
- 私有 + 共有
数据模型分析
业务模型分析
显示和流程分析
异常与异常处理
- 图
处理异常
- try-catch
- try-catch-finally
try {
//代码
}catch(InputMismatchException e){
//处理
}catch(ArithmeticException e){
//处理
}
}finally{
//最终将要执行的一些代码,在catch块return之后执行
}
多重catch块注意事项
- 顺序问题:从小到大, 子类到父类
- 就近匹配
异常抛出及自定义异常
- throw 将产生的异常抛出(方法体内,动作)
- throws 方法名和参数之后,声明要抛出何种类型的异常(声明)
自定义异常
class 自定义异常类 extends 异常类型{
}
异常链
例:一个异常包装另一个抛出的异常后再抛出
经验总结
- 在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
- 处理潜在的异常
- 尽量去处理异常,而不是仅仅打印异常(printStackTrace())
- 尽量添加finally语句块去释放占用的资源,尤其是有网络连接,和连接数据库的情况下
字符串
一旦一个字符串在内存中创建,则这个字符串将不可改变。如果需要一个可以改变的字符串,我们可以使用StringBuffer或者StringBuilder(后面章节中会讲到)
每次 new 一个字符串就是产生一个新的对象,即便两个字符串的内容相同,使用 ”==” 比较时也为 ”false”
String s1 = new String("imooc");
String s2 = new String("imooc");
- imooc为常量字符串,多次出现时会被编译器优化,只创建一个对象
String s1 = "imooc";
String s2 = "imooc";
- s1是变量,s4在运行时才知道具体值,所以s3和s4是不同的对象
public class HelloWorld {
public static void main(String[] args) {
String s1 = "imooc";
String s2 = "imooc";
//定义字符串s3,保存“I love”和s1拼接后的内容
String s3 = "I love" + s1;
// 比较字符串s1和s2
// imooc为常量字符串,多次出现时会被编译器优化,只创建一个对象
System.out.println("s1和s2内存地址相同吗?" + (s1 == s2));
//比较字符串s1和s3
System.out.println("s1和s3内存地址相同吗?" + (s1 == s3));
String s4 = "I love" + s1;
//比较字符串s4和s3
// s1是变量,s4在运行时才知道具体值,所以s3和s4是不同的对象
System.out.println("s3和s4内存地址相同吗?" + (s4 == s3));
}
}
String类 - 常用方法
- length()
- indexof("") indexof('')
- substring(3, 7)
- split(" ")
- 使用 substring(beginIndex , endIndex) 进行字符串截取时,包括 beginIndex 位置的字符,不包括 endIndex 位置的字符
StringBuffer 与 StringBuilder(值可变的字符串存储)
- StringBuffer 是线程安全的,而 StringBuilder 则没有实现线程安全功能,所以性能略高。因此一般情况下,如果需要创建一个内容可变的字符串对象,应优先考虑使用 StringBuilder 类。
- append
- insert
- toString
常用类
包装类
- 让基本类型也具备对象的特性
- 包装类主要提供了两大类方法:
- 将本类型和其他基本类型进行转换的方法
- 将字符串和本类型及包装类互相转换的方法
转换
- 装箱与拆箱
- parseInteger intValue
- 字符串与其他
- String.valueOf、toString、parseXXX、XXX.valueOf()、+ ""
时间
表示时间 Date 和 SimpleDateFormat 类
Date
- java.util 包中的 Date 类:获取当前时间
- 使用 Date 类的默认无参构造方法创建出的对象就代表当前时间
SimpleDateFormat
- java.text 包中的 SimpleDateFormat类 :对日期时间进行格式化,如可以将日期转换为指定格式的文本,也可将文本转换为日期。
- 相当于在Date对象外包装一层格式
- 代码中的 “yyyy-MM-dd HH:mm:ss” 为预定义字符串, yyyy 表示四位年, MM 表示两位月份, dd 表示两位日期, HH 表示小时(使用24小时制), mm 表示分钟, ss 表示秒
- 使用 format() 方法将日期转换为指定格式的文本
- 使用 parse() 方法将文本转换为日期:
Date date = sdf.parse(day);
- df.format()成字符串 df.parse()成Date
注意事项
- 调用 SimpleDateFormat 对象的 parse() 方法时可能会出现转换异常,即 ParseException ,因此需要进行异常处理
- 使用 Date 类时需要导入 java.util 包,使用 SimpleDateFormat 时需要导入 java.text 包
处理时间 - Calendar 类
- java.util.Calendar 类 抽象类
- 可以通过调用 getInstance() 静态方法获取一个 Calendar 对象,此对象已由当前日期时间初始化,即默认代表当前时间,如
Calendar c = Calendar.getInstance();
- 通过调用get() 方法获取日期时间信息,参数为需要获得的字段的值, Calendar.Year 等为 Calendar 类中定义的静态常量。
- Calendar 类提供了getTime() 方法,用来获取 Date 对象,完成 Calendar 和 Date 的转换,还可通过 getTimeInMillis() 方法,获取此 Calendar 的时间值,以毫秒为单位。
使用 Math 类操作数据
- java.lang 包
- Math 类的所有方法都是静态方法
- round() random() floor() ceil()
集合框架
Collection
- 是List、Set和Queue接口的父接口
List接口及其实现类 - ArrayList
- 有序可重复 序列
- 数组序列:ArrayList 底层由数组实现
- 对象存入集合都变成Object类型,取出需要类型转换
增删改查
- add addAll get set remove removeAll
- Arrays.asList()
迭代器接口
Iterator it = coursesToSelect.iterator();
- 依赖于某个集合存在
泛型
- 规定了某个集合只可以存放特点类型的对象,会在编译期间进行类型检查
public List<Course> courses;
public TestGneric(){
this.courses = new ArrayList<Course>();
}
- 泛型集合:泛型类型 泛型子类型
- 泛型集合中的限定类型不能使用基本数据类型
Set接口及其实现类——HashSet
- 元素无序且不重复(重复也会变为第一个),被称为集
- 没有set()方法,因为它是无序的,找不到索引
- 遍历Set中的元素只能用foreach或iterator方法,用不了get()方法
- 可以add(null)
Map和HashMap
- 映射关系,元素以键值对(key-value)的形式存储
- 键值对以Entry类型的对象实例形式存在
- key值不可重复,value值可以
- 支持泛型 Map<K, V>
增删
- put putAll
- remove
返回
- keySet() 返回key值的集合
- values() 返回value值的集合
- entrySet() 返回映射关系的集合
HashMap
- 基于哈希表实现
- 其中的Entry对象是无序排列的
- Key值和value值都可以为null,但是一个HashMap只能有一个key值为null的映射(key值不可重复)
Collection List Set
contains(需要重写equals方法)
containsAll
set:hashCode + equals()
索引位置:indexOf lastIndexOf
Map
- containsKey() containsValue()
Collections 工具类
- sort() 排序
Comparable 与 Comparator
- Comparable 默认比较规则
- Comparator 临时比较规则
Comparable接口 可比较的
- 实现该接口的类:实例可比较大小,可进行自然排序(默认的比较规则)
- 需实现compare To()方法 + - ==
Comparator接口 比较工具接口
- 定义临时比较规则
- 其实现类需要实现compare()方法
- 可将其传递给Collection sort方法
Java集合框架
- Collection接口 | Collections工具箱
- Map接口 | Comparator接口
- Comparable接口
字符串的比较与整数的比较不同 如 1000 与 233
综合练习- 洗牌发牌小程序
功能描述
1. 创建一副扑克牌:
- 包括四种花色(黑桃、红桃、梅花、方片)
- 十三种点数:2-10,J、Q、K、A,不考虑大小王
2. 创建两名玩家
- 玩家至少要有ID、姓名、手牌等属性,手牌为扑克牌的集合
3. 洗牌
- 将之前创建的“一副扑克牌”打乱顺序
4. 发牌
- 将洗牌之后的扑克牌集合,从第一张开始,发给两名玩家,按照一人一张的方式,每人发两张
5. 游戏
- 比较两名玩家手中的扑克牌,规则为:取两人各自手中点数最大的牌进行比较,点数大的赢;若两人各自的点数最大的牌相等,
初步设想
- 创建一个player类设置玩家信息,其中手牌套用ArrayList类,手牌间比大小的方法重写Comprable接口中的compare to()方法
- 创建一个poker类设置单张扑克牌信息,其中含有属性:String类的花色和String类的数值
- 一副扑克牌用Set定义(HashSet)
- 打乱顺序:直接利用Set是无序的这个特点来做,每次取出的元素都是不定的