Java语言的前身是Oak语言,美国Sun公司于1991(1995)年推出。2009年Sun公司被Oracle公司收购。
Java SE (java standard edition):标准版 – Java技术的核心和基础
Java EE (Java enterprise edition):企业版 – 企业经应用开发的一套解决方案
Java ME (Java micro edition):小型版 – 针对移动设备应用的解决方案
Java语言的特点:
Java开发环境:
安装JDK:(Java SE Development Kit,Java语言软件开发工具包)包含编写和运行Java程序的所有工具,包括组成Java环境的基本构件。
配置环境变量
补充知识:
自动类型转换:类型范围小的变量可以直接赋值给类型范围大的变量。
byte a = 10;
int b = a;
//格式1
if (条件表达式) {
语句体;
}
//格式2
if (条件表达式) {
语句体1;
} else {
语句体2;
}
//格式3
if (条件表达式1) {
语句体1;
} else if (条件表达式2) {
语句体2;
}
...
else {
语句体n+1;
}
//格式
switch (表达式) {
case 值1:
执行代码...;
break;//不写break会出现穿透现象,不跳出,不再判断条件直接往下执行。
case 值2:
执行代码...;
break;
...
case 值n:
执行代码...;
break;
default:
执行代码...;
}
2.循环结构
//格式
for (初始化语句 ; 循环条件 ; 迭代语句) {
循环体;
}
//格式
while (循环条件) {
循环体;
迭代语句;
}
初始化语句;
do {
循环体语句;
迭代语句;
} while (循环条件);
//特点:一定会先执行一次循环体。
3.循环控制语句
面向对象三大特征:封装、继承、多态
美 /ɪn,kæpsə’leʃən/
指隐藏对象的属性和实现细节,仅对外提供访问方式。
封装原则:
将不需要对外提供的内容都隐藏起来。
把属性都隐藏,提供公共方法对其访问。
好处:
匿名对象:
//当对对象的方法只调用一次时,可以使用匿名对象来完成。
//匿名对象示例
new 类名().方法名();
构造函数:
特点:
函数名与类名相同;不用定义返回值;不可以些return语句。
对象一建立就会调用与之对应的构造函数;
系统默认给没有自定义构造函数的类中结了一个空参数的构造函数。
作用:
给对象进行初始化。
构造代码块:
作用:给对象进行初始化。
与构造函数之间的区别:对象一建立就运行且由于构造函数执行;构造代码块是给所有的对象进行统一初始化,而构造函数是给对应的对象初始化。
//构造代码块简单示例
class Person
{
{ cry(); }
}
final关键字:
最终修饰符
示例:
//共有静态常量
public static final double PI = 3.14;
特点:
访问控制符/权限修饰符:
| 同一个类中 | 同一个包中 | 子类 | 所有类 | |
|---|---|---|---|---|
| private | OK | |||
| default | OK | OK | ||
| protected | OK | OK | OK | |
| public | OK | OK | OK | OK |
- 一个Java源文件中最多只能有一个public类,当有一个public类时,源文件名必须与之一致,否则无法编译,如果源文件中没有一个public类,则文件名与类中没有一致性要求。
至于main()不是必须要放在public类中才能运行程序。
static关键字
在Java中,用关键字extends表示派生/继承。
Object类是Java程序中所有类的直接或间接父类,处在类层次的最高层。
继承的特点:
继承后构造器的特点:
this和super关键字:
this(…)访问本类构造器 / super(…) 访问父类构造器
重写(覆盖)和重载:
重载:子类父类方法名相同,但是参数刘表不同。调用重载方法时,编译器将根据参数的个数和类型,选择对应的方法执行。
重写(覆盖):字父类方法名以及参数都一样,
概述:
同一个对象,在不同时刻表现出来的不同形态
多态分为编译时多态和运行时多态:
多态存在的三个必要条件:
成员访问特点
成员变量:编译看父类,运行看父类
成员方法:编译看父类,运行看子类
代码演示
//动物类
public class Animal {
public int age = 40;
public void eat() {
System.out.println("动物吃东西");
}
}
//猫类
public class Cat extends Animal {
public int age = 20;
public int weight = 10;
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫捉迷藏");
}
}
//测试类
public class AnimalDemo {
public static void main(String[] args) {
//有父类引用指向子类对象
Animal a = new Cat();
System.out.println(a.age);
a.eat();
}
}
//40
//猫吃鱼
多态的好处和弊端
好处:提高程序的扩展性。定义方法时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作
弊端:不能使用子类的特有成员
多态中的转型
向上转型:父类引用指向子类对象就是向上转型
向下转型:格式:子类型 对象名 = (子类型)父类引用;
代码演示
//动物类
public class Animal {
public void eat() {
System.out.println("动物吃东西");
}
}
//猫类
public class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void playGame() {
System.out.println("猫捉迷藏");
}
}
//测试类
public class AnimalDemo {
public static void main(String[] args) {
//多态
//向上转型
Animal a = new Cat();
a.eat();
//向下转型
Cat c = (Cat)a;
c.eat();
c.playGame();
}
}
abstract 抽象
美 /'æbstrækt/
抽象方法中只有方法名,没有方法体。
示例代码:
abstract class Student{
abstract void study();
}
class MidStudent extends Student{
void study(){
System.out.println("MidStudent study");
}
}
为什么要定义抽象类?
是一种模板模式,抽象类为所有子类提供一个通用模板,子类可以在这个模板基础上进行扩展。通过抽象类可以避免子类设计的随意性,使子类之间更加通用。
抽象的特点:
注意事项:
接口 interface
格式示例:
public interface MyInterface {
String NAME = "xiaoming";
public void test01();
public int test02(int a , int b);
}
接口中只有常量 和 抽象方法,修饰符是固定的:
特点:
子类名 implements 接口名
一个类只能继承一个父类,但可以同时实现多个接口。
class 子类名 extends 父类名 implements 接口1,接口2,接口3...
接口与接口之间也可以继承,且可以多继承(一对多的情况下,接口中同名抽象方法的返回值类型应当相同)。
数组是相同数据类型的元素按一定顺序排列的集合。
数组的定义格式:
数据类型[] 数组名 = new 数据类型[]{元素1,元素2...};
//简化写法
数据类型[] 数组名 ={元素1,元素2...};
数据类型[] 数组名 = new 数据类型[长度];
数组的遍历
//for循环遍历
for(int i = 0; i < 数组名.length; i++) {
数组名[i];
}
//foreach增强for循环JDK5开始
for (数组数据类型 i : 数组名) {
i;
}
String对象是不可变的,String类中修改String值的方法实际上都是创建了一个全新的String对象,以包含修改后的字符串内容。而最初的String对象则丝毫未动。
public class Immutable {
public static String upcase(String s) {
return s.toUpperCase();
}
public static void main(String[] args) {
String q = "xiangbian";
System.out.println(q);
String qq = upcase(q);
System.out.println(qq);
System.out.println(q);
}
}
/*
xiangbian
XIANGBIAN
xiangbian
*/
用于String的“+”与“+=‘是Java中仅有的两个重载过的操作符,而Java并不允许程序员重载任何操作符。
public class WhitherStringBuilder {
public static String implicit(String[] fields) {
String result = "";
for (int i = 0; i < fields.length; i++) {
result+=fields[i];
}
return result;
}
public static String explicit(String[] fields) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < fields.length; i++) {
result.append(fields[i]);
}
return result.toString();
}
public static void main(String[] args) {
String[] s = {"1","adfdf","fdf","123131"};
System.out.println(implicit(s));
System.out.println(explicit(s));
}
}
/*
1adfdffdf123131
1adfdffdf123131
*/
以上两种方法结果一样,实则内部实现不一样。
implicit(String[] fields) 会创建多个StringBuilder对象,而explicit(String[] fields)方法只会生成一个StringBuilder对象。
| 方法 | 参数 | 应用 |
|---|---|---|
| 构造器 | 重载版本:默认版本,String,StringBuilder,StringBuffer,char数组,byte数组 | 创建String对象 |
| length() | String中字符的个数 | |
| charAt() | Int索引 | 取得String中该索引位置上的char |
| getChars(),getBytes() | 要复制部分的起点和终点的索引,复制的目标数组,目标数组的起始索引 | 复制char或byte到目标数组中 |
| toCharArray() | 生成一个char[],包含String的所有字符 | |
| equals(),equalsIgnoreCase() | 与之进行比较的String | 比较两个String的内容是否相同 |
| compareTo() | 与之进行比较的String | 按词典顺序比较String的内容,比较结果为负数、零、或正数。注意,大小写并不等价。 |
| contains() | 要搜索的CharSequence | 如果该String对象包含参数的内容,则返回true |
| contentEquals() | 与之进行比较的CharSequence或StringBuffer | 如果该String对象与参数的内容完全一致,则返回true |
| equalsIgnoreCase() | 与之进行比较的String | 忽略大小写,如果两个String的内容相同,则返回true |
| regionMatcher() | 该String的索引偏移量,另一个String及其索引偏移量,要比较的长度。重载版本增加了”忽略大小写“功能 | 返回boolean结果,以表明所比较区域是否相等 |
| startsWith() | 可能的起始String。重载版本在参数中增加了偏移量 | 返回boolean结果,以表明该String是否以此参数起始 |
| endsWith() | 该String可能的后缀String | 返回boolean结果,以表明此参数是否该字符串的后缀 |
| indexOf(),lastIndexOf() | 重载版本包括:char,char与起始索引,String,String与起始索引 | 如果该String并不包含此参数,就返回-1,否则返回此参数在String中的起始索引。lastIndexOf()是从后向前搜索 |
| substring() (subSequence()) | 重载版本:起始索引;起始索引+终点坐标 | 返回一个新的String,以包含参数指定的字符串 |
| concat() | 要连接的String | 返回一个新的String对象,内容为原始String连上参数String |
| replace() | 要替换的字符,用来进行替换的新字符。也可以用一个CharSequence来替换另一个CharSequence | 返回替换字符后的新String对象。如果没有替换发生,则返回原始的String对象 |
| toLowerCase(),toUpperCase() | 将字符的大小写改变后,返回一个新String对象。如果没有发生改变,则返回原始的String对象 | |
| trim() | 将String两端的空白字符删除后,返回一个新的String对象。如果没有改变发生,则返回原始的String对象 | |
| valueOf() | 重载版本:Object;char[];char[],偏移量,与字符个数;boolean;char;int;long;float;double | 返回一个表示参数内容的String |
| intern() | 为每个唯一的字符序列生成一个且仅生成一个String引用 | |
从表中可以看出,当需要改变字符串的内容时,String类的方法都会返回一个新的String对象。、
同时,如果内容没有发生改变,String的方法只是返回指向原对象的引用,以节约存储空间和避免额外的开销。
public class SimpleFormat {
public static void main(String[] args) {
int x = 5;
double y = 3.1415926;
System.out.println("ROW 1:[" + x +" "+y+"]");
System.out.format("Row 1:[%d %f]\n", x,y);
//or
System.out.printf("Row 1:[%d %f]\n", x,y);
}
}
/*
ROW 1:[5 3.1415926]
Row 1:[5 3.141593] 精度丢失
Row 1:[5 3.141593]
*/
format()与printf()是等价的,它们只需要一个简单的格式化字符串,加上一串参数即可,每个参数对应一个格式修饰符。
在插入数据时,如果想要控制空格与对齐,你需要更精细复杂的格式修饰符。
抽象语法:
%[argument_index$][flags][width][.precision]conversion
用格式修饰符来打印一个购物收据:
import java.util.*;
public class Receipt {
private double total = 0;
private Formatter f = new Formatter(System.out);
public void printTitle() {
f.format("%-15s %5s %10s\n", "Item","Qty","Price");
f.format("%-15s %5s %10s\n", "-------","---","-----");
}
public void print(String name,int qty,double price) {
f.format("%-15.15s %5d %10.2f\n", name,qty,price);
total+=price;
}
public void printTotal() {
f.format("%-15s %5s %10.2f\n", "Tax"," ",total*0.06);
f.format("%-15s %5s %10s\n", " "," ","-----");
f.format("%-15s %5s %10.2f\n", "Total","",total*1.06);
}
public static void main(String[] args) {
Receipt receipt = new Receipt();
receipt.printTitle();
receipt.print("Jack's Magic Beans", 4, 4.25);
receipt.print("Princess Peas", 3, 5.1);
receipt.print("Three Bears Porridge", 1, 14.29);
receipt.printTotal();
}
}
/*
Item Qty Price
------- --- -----
Jack's Magic Be 4 4.25
Princess Peas 3 5.10
Three Bears Por 1 14.29
Tax 1.42
-----
Total 25.06
*/
常用类型转换字符:(占位符)
| %d | 整数型 |
| %c | Unicode字符 |
| %b | Boolean值 |
| %s | String |
| %f | 浮点数(十进制) |
| %e | 浮点数(科学计数) |
| %x | 整数(十六进制) |
| %h | 散列码(十六进制) |
| %% | 字符% |
代码示例:
import java.util.*;
public class Conversion {
public static void main(String[] args) {
Formatter f = new Formatter(System.out);
char c = 'a';
System.out.println("c = 'a'");
f.format("%%c: %c\n", c);
f.format("%%s: %s\n", c);
f.format("%%b: %b\n", c);
f.format("%%h: %h\n", c);
//f.format("%%d: %d\n", c);
f.close();
}
}
/*
c = 'a'
%c: a
%s: a
%b: true
%h: 61
*/
注意:对于b转换而言,boolean基本类型或Boolean对象以外的其他类型的参数,只要该参数不为null,那转换结果就永远都是true。
正则表达式是一种强大而灵活的文本处理工具,它提供了一种完全通用的方式,能够解决各种字符串处理相关的问题:匹配、选择、编辑以及验证。
字符:
| B | 指定字符B |
| \xhh | 十六进制值为oxhh的字符 |
| \uhhh | 十六进制表示为oxhhhh的Unicode字符 |
| \t | 制表符tab |
| \n | 换行符 |
| \r | 回车 |
| \f | 换页 |
| \e | 转义(Escape) |
字符类:
| . | 任意字符 |
| [abc] | 包含了a、b和c的任何字符(和a|b|c作用相同) |
| [^abc] | 除了a、b和c之外的任何字符(否定) |
| [a-zA-z] | 从a到z或从A到Z的任何字符(范围) |
| [abc[hij]] | 任意a、b、c、h、i、和j字符(与a|b|c|h|i|j作用相同)(合并) |
| a-z&&[hij] | 任意h、i或j(交) |
| \s | 空白符(空格、tab、换行、换页和回车) |
| \S | 非空白符([^\s]) |
| \d | 数字[0-9] |
| \D | 非数字[0-9] |
| \w | 词字符[a-zA-Z0-9] |
| \W | 非词字符 |

逻辑操作符:
| XY | Y跟在X后面 |
| x|y | X或Y |
| (X) | 捕获组(capturing group)。可以在表达式中用\i引用第i个捕获组 |
边界匹配符:
| ^ | 一行的起始 |
| $ | 一行的结束 |
| \b | 词的边界 |
| \B | 非词的边界 |
| \G | 前一个匹配的结束 |
量词:
| 贪婪型 | 勉强型 | 占有型 | 如何匹配 |
|---|---|---|---|
| X? | X?? | X?+ | 一个或零个X |
| X* | X*? | X*+ | 零个或多个X |
| X+ | X+? | X++ | 一个或多个X |
| X{n} | X{n}? | X{n}+ | 恰好n次X |
| X{n,} | X{n,}? | X{n,}+ | 至少n次X |
| X{n,m} | X{n,m}? | X{n,m}+ | X至少n次,且不超过m次 |
表达式X通常必须要用圆括号括起来,以便它可以按照我们期望的效果去执行。
例如:
abc+ //这个表达式表示:匹配ab,后面跟随1个或多个c。
要表明匹配一个或多个完整的abc字符串,必须这要表示:
(abc)+ //匹配一个或多个完整的abc字符串
定义泛型方法语法格式:

调用泛型方法语法格式

容器,就是可以容纳其他Java对象的对象。
*Java Collections Framework(JCF)*为Java开发者提供了通用的容器,其始于JDK 1.2,
优点是:
Java容器里只能放对象,对于基本类型(int, long, float, double等),需要将其包装成对象类型后(Integer, Long, Float, Double等)才能放到容器里。很多时候拆包装和解包装能够自动完成。这虽然会导致额外的性能和空间开销,但简化了设计和编程。

LinkedList
可以用它来实现双向队列。
PriorityQueue
基于堆结构实现,可以用它来实现优先队列。


模式定义了数据如何存储、存储什么样的数据以及数据如何分解等信息,数据库和表都有模式。 主键的值不允许修改,也不允许复用(不能使用已经删除的主键值赋给新数据行的主键)。
SQL(Structured Query Language),标准 SQL 由 ANSI 标准委员会管理,从而称为 ANSI SQL。各个 DBMS 都有自己的实现,如 PL/SQL、Transact-SQL 等。
SQL 语句不区分大小写,但是数据库表名、列名和值是否区分依赖于具体的 DBMS 以及配置。
CREATE TABLE mytable (
id INT NOT NULL AUTO_INCREMENT,
col1 INT NOT NULL DEFAULT 1,
col2 VARCHAR(45) NULL,
col3 DATE NULL,
PRIMARY KEY (`id`));
ALTER TABLE mytable
ADD col CHAR(20);
---ALTER TABLE 表名 CHANGE 原字段名 新字段名 字段类型 约束条件
ALTER TABLE mytable
CHANGE col col1 CHAR(32) NOT NULL DEFAULT '123';
ALTER TABLE mytable
DROP COLUMN col;
DROP TABLE mytable;
INSERT INTO mytable(col1, col2)
VALUES(val1, val2);
INSERT INTO mytable1(col1, col2)
SELECT col1, col2
FROM mytable2;
CREATE TABLE newtable AS
SELECT * FROM mytable;
UPDATE mytable
SET col = val
WHERE id = 1;
使用更新和删除操作时一定要用 WHERE 子句,不然会把整张表的数据都破坏。可以先用 SELECT 语句进行测试,防止错误删除。
DELETE FROM mytable
WHERE id = 1;
TRUNCATE TABLE mytable;
SELECT DISTINCT col1, col2
FROM mytable;
返回前5行:
SELECT *
FROM mytable
LIMIT 5;
SELECT *
FROM mytable
LIMIT 0, 5;
返回3~5行:
SELECT *
FROM mytable
LIMIT 2, 3;
可以按多个列进行排序,并且为每个列指定不同的排序方式:
SELECT *
FROM mytable
ORDER BY col1 DESC, col2 ASC;
不进行过滤的数据非常大,导致通过网络传输了多余的数据,从而浪费了网络带宽。因此尽量使用 SQL 语句来过滤不必要的数据,而不是传输所有的数据到客户端中然后由客户端进行过滤。
SELECT *
FROM mytable
WHERE col IS NULL;
WHERE 子句可用的操作符:
| 操作符 | 说明 |
|---|---|
| = | 等于 |
| < | 小于 |
| > | 大于 |
| <> != | 不等于 |
| <= !> | 小于等于 |
| >= !< | 大于等于 |
| BETWEEN | 在两个值之间 |
| IS NULL | 为 NULL 值 |
应该注意到,NULL 与 0、空字符串都不同。
AND 和 OR 用于连接多个过滤条件。优先处理 AND,当一个过滤表达式涉及到多个 AND 和 OR 时,可以使用 () 来决定优先级,使得优先级关系更清晰。
IN 操作符用于匹配一组值,其后也可以接一个 SELECT 子句,从而匹配子查询得到的一组值。
NOT 操作符用于否定一个条件。
通配符也是用在过滤语句中,但它只能用于文本字段。
使用 Like 来进行通配符匹配:
SELECT *
FROM mytable
WHERE col LIKE '[^AB]%'; -- 不以 A 和 B 开头的任意文本
不要滥用通配符,通配符位于开头处匹配会非常慢。
计算字段通常需要使用 AS 来取别名,否则输出的时候字段名为计算表达式。
SELECT col1 * col2 AS alias
FROM mytable;
CONCAT() 用于连接两个字段。许多数据库会使用空格把一个值填充为列宽,因此连接的结果会出现一些不必要的空格,使用 TRIM() 可以去除首尾空格。
SELECT CONCAT(TRIM(col1), '(', TRIM(col2), ')') AS concat_col
FROM mytable;
各个 DBMS 的函数都是不相同的,因此不可移植,以下主要是 MySQL 的函数。
| 函 数 | 说 明 |
|---|---|
| AVG() | 返回某列的平均值 |
| COUNT() | 返回某列的行数 |
| MAX() | 返回某列的最大值 |
| MIN() | 返回某列的最小值 |
| SUM() | 返回某列值之和 |
AVG() 会忽略 NULL 行。
使用 DISTINCT 可以让汇总函数值汇总不同的值。
SELECT AVG(DISTINCT col1) AS avg_col
FROM mytable;
| 函数 | 说明 |
|---|---|
| LEFT() | 左边的字符 |
| RIGHT() | 右边的字符 |
| LOWER() | 转换为小写字符 |
| UPPER() | 转换为大写字符 |
| LTRIM() | 去除左边的空格 |
| RTRIM() | 去除右边的空格 |
| LENGTH() | 长度 |
| SOUNDEX() | 转换为语音值 |
其中, SOUNDEX() 可以将一个字符串转换为描述其语音表示的字母数字模式。
SELECT *
FROM mytable
WHERE SOUNDEX(col1) = SOUNDEX('apple')