day1
1、class Demo
{
public static void main(String[] args){
System.out.println("Hello World!");
}
}
三点:main为程序入口,被虚拟机所调用,有main函数,一个类就可以独立运行。
2、类文件在各个路径下都可以找到
使用classpath环境变量
set classpath=c:\my class
set classpath=c:\my class;
存在加分号和不加分号的区别,加上分号如果在指定目录下找不到会在当前目录下进行查找,一般不要加
set classpath=.;c:\my class;
设置当前路径和设置路径,要显式地设置出来
3、class类名前添加public关键字强制保证类名和文件名相同,否则编译不通过。
day2
1、java中特有的注释
该种注释,可以使用jdk中的javadoc.exe程序来提取源码和说明。
2、大括号即作用域
public static void main(String[] args){
{
int z = 9;
System.out.println(z);
}
System.out.println(z);
}
上述代码段编译时会报错,因为z的作用域的原因。
3、运算两端同类型才能运算,不同数值型可以运算,但会有类型提升。
public class Test {
public static void main(String[] args){
byte b = 4;
byte b1 = 3;
byte b2 = 7;
b = b1 + b2;
int x;
x = b1 + b2;
}
}
4、自动类型转换(隐式)和强制类型转换(显式)
5、任何数值和字符串(用双引号)单引号为字符,计算时取ASCII值)做加法都是相连接。
System.out.println(3 + "2");
System.out.println(3 + ‘2’);
6、short s = 3;
s += 4;
s = (short)(s + 4);
day3
1、异或 ^两边如果相同,则结果为false。
2、按位操作符 & |
3、逻辑操作符(短路) && ||
4、取反和反码不一样
a. 原码、反码、补码:
(1)在Java中,所有数据的表示方式都是以补码形式来表示
(2)正数:原码、反码、补码相同
(3)负数:符号位为1,其余各位是对原码取反,然后整个数加1
(4)~按位取反(反码加1称为补码。)步骤就是先求出这个数(因为java存的数是补码)的原码,
然后对原码取反得到X,这个X就是我们要求的那个数的补码
b. 取反(~)运算
(1)n=37 ,二进制数就是 100101
因为在Java中,所有数据的表示方式都是以补码形式来表示,如果没有特别的说明,Java 中的数据类型默认为int,int数据类型的长度为8位,就是32字节,32bit的意思,
因此,n=100101的原码=补码(因为是正数,所以原=补=反)运算过程就是:
原码:00000000 00000000 00000000 00100101 =37
~n(对n的原码) 取反运算得: 11111111 11111111 11111111 11011010 很明显,最高位是1,意思是原码为负数,负数的补码是其绝对值的原码取反,末尾再加1,
因此,我们可将这个二进制数的补码进行还原:
首先,末尾减1得反码:11111111 11111111 11111111 11011001
其次,将各位取反得原码:00000000 00000000 00000000 00100110 这个就是~n的绝对值形式,|~n|=38,
所以,~n= -38,这个就是Java虚拟机的运算结果
(2)n= - 4, 取反 (~-4)
-4补码:10000000 00000000 00000000 00000100
-4反码:10000000 00000000 00000000 00000011
-4原码:11111111 11111111 11111111 11111100
对原码取反:00000000 00000000 00000000 00000011
因为是正数,所以补码等于原码等于反码= 3,所以~-4 = 3
5、左移、右移(高位是什么,移位后高位补什么)、无符号右移 << >> >>>
6、对两个数值变量进行互换(不使用第三个变量)
public class Test {
public static void main(String[] args){
int a = 3;
int b = 4;
a = a + b;
b = a - b;
a = a - b;
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
}
7、局部代码块与变量作用域
使用局部代码块可以节省内存(虚拟机内存不大),性能优化
public class Test {
public static void main(String[] args){
int a = 3;
int b = 4;
{
int m = 89;
System.out.println("Hello" + m);
}
System.out.println("Hello" + m);
}
}
8、if...else if...效率比 if...if...要高。
9、if和switch的应用
if:1、对具体的值进行判断
2、对区间进行判断
3、对运算结果是boolean类型的表达式进行判断
switch:1、对具体值进行判断 2、值的个数通常是固定的
day4
1、九九乘法表
public class Test {
public static void main(String[] args){
for(int x = 1; x <= 9; x++){
for(int y = 1; y <= x; y++){
System.out.print(y+"*"+x+"="+y*x+"\t");
}
System.out.println();
}
}
}
2、转义字符
\n : 回车
\t : 制表符
\b : 退格
\r : 按下回车键
Windows系统中回车符其实是由两个符号组成的\r\n. linux中回车符是\n.
3、break和continue
break:跳出当前循环 选择结构和循环结构
continue: 结束本次循环,继续下次循环 循环结构中使用
break想要跳出指定循环,需要用到标号;continue想要继续指定循环也可以用标号
a、
public class Test {
public static void main(String[] args){
for(int x = 0; x < 3; x++){
for(int y = 0; y < 4; y++){
System.out.println("x="+x);
break;
}
}
}
}
output:
x=0
x=1
x=2
b、
public class Test {
public static void main(String[] args){
for(int x = 0; x < 3; x++){
for(int y = 0; y < 4; y++){
System.out.println("x="+x);
}
break;
}
}
}
output:
x=0
x=0
x=0
x=0
c、
package cn.itcast.io;
public class Test {
public static void main(String[] args){
firstloc:for(int x = 0; x < 3; x++){
secondloc:for(int y = 0; y < 4; y++){
System.out.println("x="+x);
break firstloc;
}
}
}
} output:x=0
continue打印10以内的奇数(continue: 结束本次循环,继续下次循环 循环结构中使用)
package cn.itcast.io;
public class Test {
public static void main(String[] args){
for(int x = 0; x < 11; x++){
if(x%2 == 0)
continue;
System.out.print("x="+x+" ");
}
}
} output:x=1 x=3 x=5 x=7 x=9
4、函数
函数的定义、特点、应用和重载
5、内存加载过程(栈)
/>javac FunctionDemo.java --> FunctionDemo.class
/>java FunctionDemo
6、重载(overload)
重载的概念:在同一个类中,允许一个以上的同名函数,只要他们的参数个数或参数类型不同即可。
重载的特点:与返回值类型无关,只看参数列表。
重载的好处:方便阅读,优化程序设计。
重载的示例:
public static int add(int a, int b) {return a+b;}
public static int add(int a, int b, int c) {return a+b+c;}
public static double add(double a, double b) {return a+b;}
public static double add(int a, int b) {return a+b;}
7、乘法表(体现函数的重载和复用)
package cn.itcast.io;
public class Test {
public static void main(String[] args){
printCFB(6);
printCFB();
}
public static void printCFB(int num){
for(int x = 1; x <= num; x++){
for(int y = 1; y <= x; y++){
System.out.print(y+"*"+x+"="+y*x+"\t");
}
System.out.println();
}
}
public static void printCFB(){
printCFB(9);
}
}
8、数组
格式1、元素类型[] 数组名 = new 元素类型[元素个数或数组长度]
示例:int[] arr = new int[5];
格式2、元素类型[] 数组名 = new 元素类型[] {元素, 元素, ......};
示例:int[] arr = new int[]{3, 5, 1, 7};
int[] arr = {3, 5, 1, 7};
9、内存的划分
寄存器、本地方法区、方法区、栈内存、堆内存
栈内存:存储的都是局部变量,而且变量所属的作用域一旦结束,该变量就自动释放
堆内存:存储的是数组和对象(其实数组就是对象),凡是new建立的都在堆中
day5
1、选择排序、冒泡排序
2、有序的数组可以使用二分查找,无序的只能顺序查找
java提供了二分查找法,如果存在返回的具体的角标位置,不存在返回的是(-插入点-1)
3、进制转换(查表法)
day6
1、二维数组
格式1、int[][] arr = new int[3][2];
定义一个名称为arr的二维数组,有三个一维数组,每一个一维数组中有两个元素
格式2、int[][] arr = new int[3][];
arr[0] = new int[3];
arr[1] = new int[1];
arr[2] = new int[2];定义一个名称为arr的二维数组,有三个一维数组,每一个一维数组默认初始化值为null,分别进行初始化
2、面向对象 封装、继承、多态
3、用java语言对现实生活中的事物进行描述,通过类的形式来体现。
4、对事物的描述通常只关注两个方面,一个是属性,一个是行为。
5、默认初始化 int num; 显示初始化 int num = 4;
public class Car {
int num;
String color;
void run(){
System.out.println(num+"..."+color);
}
public static void main(String[] args){
Car c = new Car();
c.num = 4;
c.run();
}
} output:4...null
6、成员变量和局部变量的区别
a、成员变量定义在类中,整个类都可以访问;局部变量定义在局部代码块,只在所属区域有效。
b、成员变量存在于堆内存的对象中;局部变量存在于栈内存的方法中。
c、成员变量随着对象的创建而存在,随着对象的消失而消失;
局部变量随着所属区域的存在而存在,随着所属区域的结束而释放。
d、成员变量都有默认初始化值,局部变量没有默认初始化值。
7、类类型参数 public static void show(Car c)
8、匿名对象 其实就是定义对象的简写格式
Car c = new Car(); c.run(); new Car().run()
a、当对象对方法仅进行一次调用的时候,就可以简化成匿名对象。
b、匿名对象可以作为实际参数进行传递。
9、基本数据类型参数传递和引用数据类型参数传递
public class Car {
public static void main(String[] args){
int x = 3;
show(x);
System.out.println("x = "+x);
}
public static void show(int x){
x = 4;
}
}
public class Car {
int x = 3;
public static void main(String[] args){
Car c = new Car();
c.x = 9;
show(c);
System.out.println("x = "+c.x);
}
public static void show(Car c){
c.x = 4;
}
}
10、封装:隐藏对象的属性和内部实现细节,仅对外提供公共访问方式。
day7
1、构造函数
特点:函数名和类名相同 不用定义返回值类型,没有具体的返回值
作用:给对象进行初始化
2、默认构造函数的特点 无参
3、多个构造函数是以重载的形式存在的(第3和4是不同的)
public class Person {
private String name;
private int age;
Person()
{
name = "baby";
age = 1;
System.out.print("person run ");
}
Person(String n)
{
name = n;
}
Person(String n, int a)
{
name = n;
age = a;
}
Person(int a, String n)
{
name = n;
age = a;
}
public void speak(){
System.out.print(name+":"+age+" ");
}
public static void main(String[] args){
Person p1 = new Person();
p1.speak();
Person p2 = new Person("tom");
p2.speak();
Person p3 = new Person("jack", 12);
p3.speak();
Person p4 = new Person(10, "lily");
p4.speak();
}
}
4、构造函数有return语句
5、this关键字
this代表其所在函数所属对象的引用,this代表本类对象的引用,当在函数内
需要调用到函数的对象时,就用this。
this也可以在构造函数中调用其他的构造函数。只能定义在构造函数的第一行。
public class Person {
private String name;
private int age;
Person()
{
name = "baby";
age = 1;
System.out.print("person run ");
}
Person(String name)
{
this.name = name;
}
Person(String name, int age)
{
this(name);
this.age = age;
}
public void speak(){
System.out.print(name+":"+age+" ");
}
}
6、static关键字
用于修饰成员:成员变量和成员函数
特点:随着类的加载而加载 优先于对象存在 被所有对象所共享 可以直接被类名调用
注意:静态方法只能访问静态成员 静态方法中不能有this、super关键字 主函数是静态的
7、成员变量和静态变量区别
a、生命周期不同:成员变量随着对象的创建而存在,随着对象的被回收而释放,
静态变量随着类的加载而存在,随着类的消失而消失。
b、调用方式:成员变量只能被对象调用,静态变量可以被对象调用,还可以被类名调用。
c、别名不同:成员变量也称为实例变量,静态变量称为类变量。
d、数据存储位置:成员变量存储在堆内存的对象中,静态变量数据存储在方法区。
8、内存图解
9、静态变量和静态函数
10、静态代码块(随着类的加载而执行,而且只执行一次)
作用:用于给类进行初始化(构造函数用于给对象进行初始化)
原因:有的类不需要创建对象,比如类中的方法都是静态的方法。
class StaticCode {
static
{
System.out.print("this is static code! ");
}
void show(){
System.out.println("show run!");
}
}
public class StaticCodeDemo{
public static void main(String[] args){
new StaticCode().show();
}
}
class StaticCode {
static
{
System.out.print("this is static code! ");
}
static void show(){
System.out.println("show run!");
}
}
public class StaticCodeDemo{
public static void main(String[] args){
StaticCode.show();
}
}
11、构造代码块对所有对象进行初始化,构造函数对对应对象进行针对性的初始化。
day8
1、继承
提高代码复用性,让类和类之间产生了关系,为多态创造前提
2、java中支持单继承,不直接支持多继承,但对c++中的多继承机制进行改良。
单继承:一个子类只有一个直接父类。
多继承:一个子类可以有多个直接父类(java中不允许,进行改良)
不直接支持,因为多个父类中有相同成员,会产生调用不确定性。
如下:
class A{
void show(){
System.out.println("a");
}
}
class B{
void show(){
System.out.println("b");
}
}
class C extends A,B{
}
当调用new C().show()时,会产生调用的不确定性。
3、java支持多层(多重)继承。 c继承b,b继承a
当要使用一个继承体系时,查看该体系中的顶层类,了解该体系基本功能,
查看最子类队象,完成功能使用。
4、本类中的成员和局部变量同名用this区分,子父类中的成员变量同名用super区分交换。
this和super的用法很相似,this代表本类对象的一个引用,super代表一个父类空间。
class Fu{
int num = 4;
}
public class ZiLei extends Fu{
int num = 5;
void show(){
System.out.println(this.num + "......" + super.num);
}
public static void main(String[] args){
ZiLei z = new ZiLei();
z.show();
}
}
5、子类不能直接访问父类中的私有成员变量,通过public修饰的接口间接访问。
6、当子父类中出现成员函数一模一样的情况,会运行子类的函数,称为覆盖(重写)。
重写注意事项:
a、子类方法覆盖父类方法时,子类权限必须要大于等于父类的权限。
b、静态只能覆盖静态,或被静态覆盖。
7、何时使用重写?升级,要添加新功能,但不更改原来的类中的内容,提高程序的扩展性。
8、强制一个类不能创建对象,可以将该类的构造函数私有化。
class ArrayTool{ private ArrayTool(){} }
9、D:\Program Files(x86)\Java\jdk1.8.0_131\bin\javadoc.exe 提取文档注释
10、设计模式
单例模式(Singleton Pattern):Ensure a class has only one instance,and provided a
global point of access to it.
单例设计模式,解决的问题:可以保证一个类在内存中的对象唯一性。
如何保证唯一性:
a、不允许其他程序用new创建该类对象。
b、在该类创建一个本类实例。
c、对外提供一个方法让其他程序可以获取该对象。
public class Emperor{
private static final Emperor emperor = new Emperor();
private Emperor(){
}
public static Emperor getInstance(){
return emperor;
}
public static void say(){
System.out.println("我是...");
}
}
public class Emperor{
private static Emperor emperor = null;
private Emperor(){
}
public static Emperor getInstance(){
if(emperor == null)
{
emperor = new Emperor();
}
return emperor;
}
public static void say(){
System.out.println("我是...");
}
}
day9
1、子父类中的构造函数
在子类构造对象时,发现,访问子类构造函数时,父类也运行了。原因是在子类的构造
函数中第一行有一个默认的隐式语句:super();,调用的就是父类中的空参数的构造函数。
子类的实例化过程,子类中所有的构造函数默认都会访问父类中的空参数的构造函数(但可以
自行指定带参构造函数)。
2、为什么子类实例化的时候要访问父类中的构造函数?
子类会使用父类的属性等,父类的构造函数中可能对某些属性进行了一些操作。
3、子类构造函数中如果使用this调用了本类构造函数时,那么super就没有了,因为super和this都只能定义在第一行。
4、class Fu
{
Fu()
{
super();
show();
return;
}
void show()
{
System.out.println("fu show");
}
}
class Zi extends Fu
{
int num = 8;
Zi()
{
super();
System.out.println("zi cons run...."+num);
return;
}
void show()
{
System.out.println("zi show..."+num);
}
}
class ExtendsDemo5
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
}
}
5、final关键字
final可以修饰类(不可被继承);方法(不可被覆盖);变量(是一个常量,只能被赋值一次)
6、内部类只能访问被final修饰的局部变量(内部类在局部位置上只能访问局部中被final修饰的局部变量。)
7、抽象类特点:
a、含abstract修饰符的class即为抽象类,abstract类不能创建实例。
b、含有abstract方法的类必须定义为abstract class。
c、abstract 类中定义的抽象方法必须在具体子类中实现,所以不能有抽象构造方法或抽象静态方法(可以有静态方法)。
d、abstract 类中的方法不是必须是抽象的。
e、子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。
8、抽象类中有构造函数,用于给子类对象进行初始化
9、抽象类中可以不定义抽象方法,但很少见,目的是不让该类创建对象。
awt的适配器对象就是这种类。通常这个类中的方法有方法体,但没有内容。
10、抽象关键字不可以和private、static、final共存
11、接口定义:interface()
a、接口中的所有方法都必须是抽象的。
b、接口中的方法定义默认为public abstract类型。
c、接口中的变量默认为public static final
12、接口实现:implements class DemoImpl implements Demo
13、java中的类不支持多继承,所以java将多继承进行改良,在java中变成多实现。一个类可以实现多个接口。
如下:
interface A{
public void show();
}
interface B{
public void show();
}
class C implements A,B{
public void show()
{
}
}
14、一个类在继承另一个类的同时,还可以实现多个接口
interface A{
public void show();
}
interface B{
public void show();
}
class Q{
public void method(){
}
}
class C extends Q implements A,BAD_CONTEXT{
}
所以,接口的出现,避免了单继承的局限性。
15、接口与接口之间是继承关系,接口可以多继承。
interface A{
public void show();
}
interface B{
public void method();
}
interface QQ extends A,B{
public void function();
}
class WW implements QQ{
public void show(){};
public void method(){};
public void function(){};
}
day10
1、接口示例
interface USB
{
public void open();
public void close();
}
class BookPC
{
public static void main(String[] args)
{
useUSB(new UPan());
useUSB(new UsbMouse());
}
public static void useUSB(USB u)
{
if(u!=null)
{
u.open();
u.close();
}
}
}
class UPan implements USB
{
public void open()
{
System.out.println("upan open");
}
public void close()
{
System.out.println("upan close");
}
}
class UsbMouse implements USB
{
public void open()
{
System.out.println("UsbMouse open");
}
public void close()
{
System.out.println("UsbMouse close");
}
}
2、多态 某一事物的多种存在形态,在代码中的体现是父类或者接口的引用指向子类的对象。
3、多态提高了代码的扩展性,前期定义的代码可以使用后期的内容,但不能使用后期子类的特有内容。
4、转型,向上转型和向下转型
abstract class Animal
{
abstract void eat();
}
class Cat extends Animal
{
void eat()
{
System.out.println("吃鱼");
}
void catchMouse()
{
System.out.println("抓老鼠");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
Animal a = new Cat();
a.eat();
Cat c = (Cat)a;
c.eat();
c.catchMouse();
Animal a1 = new Dog();
Cat c1 = (Cat)a1;
}
}
5、类型(类或接口)判断 instanceof
public class ListTest {
public static void main(String[] args) {
List<String> arr = new ArrayList<String>();
arr.add("a");
arr.add("b");
arr.add("a");
arr.add("d");
arr.add("d");
arr.add("e");
for (int i = 0; i < arr.size(); i++) {
boolean result = arr.get(i) instanceof String;
System.out.print(result+" ");
}
System.out.print("删除前:"+arr.toString()+" ");
for (int i = 0; i < arr.size() - 1; i++) {
for (int j = arr.size() - 1; j > i; j--) {
if(arr.get(j).toString().equals(arr.get(i).toString())){
arr.remove(j);
}
}
}
System.out.println("删除后:"+arr.toString());
}
}
6、在向下转型时,先使用instanceof来判断类型
public static void method(Animal a)
{
a.eat();
if(a instanceof Cat)
{
Cat c = (Cat)a;
c.catchMouse();
}
}
7、多态时,成员的特点:
a、成员变量
编译时:参考引用型变量所属的类中的是否有调用的成员变量,有,编译通过,没有,编译失败。
运行时:参考引用型变量所属的类中的是否有调用的成员变量,并运行该所属类中的成员变量。
简单说:编译和运行都参考等号的左边。
b、成员函数(非静态)
编译时:参考引用型变量所属的类中的是否有调用的函数。有,编译通过,没有,编译失败。
运行时:参考的是对象所属的类中是否有调用的函数。
简单说:编译看左边,运行看右边。因为成员函数存在覆盖特性。
c、静态函数
编译时:参考引用型变量所属的类中的是否有调用的静态方法。
运行时:参考引用型变量所属的类中的是否有调用的静态方法。
简单说,编译和运行都看左边。其实对于静态方法,是不需要对象的(所以和非静态不同,不会覆盖)。
8、内部类
将一个类定义在另一个类的里面,里面那个类就称为内部类。
访问特点:内部类可以直接访问外部类中的成员,包括私有成员。而外部类要访问内部类中的成员必须要建立内部类的对象。
9、内部类可以使用访问权限修饰符
class Outer
{
private static int num = 31;
class Inner
{
void show()
{
System.out.println("show run..."+num);
}
}
public void method()
{
Inner in = new Inner();
in.show();
}
}
class InnerClassDemo
{
public static void main(String[] args)
{
Outer.Inner in = new Outer().new Inner();
in.show();
}
}
10、为什么内部类可以直接访问外部类的成员? 因为内部类持有了外部类的引用,外部类.this
class Outer
{
int num = 3;
class Inner
{
int num = 4;
void show()
{
int num = 5;
System.out.println(num);
System.out.println(this.num);
System.out.println(Inner.this.num);
System.out.println(Outer.this.num);
}
}
void method()
{
new Inner().show();
}
}
class InnerClassDemo2
{
public static void main(String[] args)
{
new Outer().method();
}
}
11、局部内部类(内部类可以放在局部位置上)(day9 6)
内部类在局部位置上只能访问局部中被final修饰的局部变量。
class Outer
{
int num = 3;
Object method()
{
final int x = 9;
class Inner
{
public String toString()
{
return "show ..."+x;
}
}
Object in = new Inner();
return in;
}
}
class InnerClassDemo3
{
public static void main(String[] args)
{
Outer out = new Outer();
Object obj = out.method();
System.out.println(obj);
}
}
12、匿名内部类。就是内部类的简写格式,前提:内部类必须继承或者实现一个外部类或者接口。
匿名内部类其实就是一个匿名子类对象,格式:new 父类or接口() {子类内容}
13、当函数参数是接口类型时,而且接口中的方法不超过3个,可以用匿名内部类作为实际参数进行传递。
14、静态方法中不允许有this
day11
1、Object-equals方法
class Per extends Object
{
private int age;
Per(int age){
this.age = age;
}
}
public class ObjectTest {
public static void main(String[] args)
{
Per p1 = new Per(20);
Per p2 = new Per(20);
Per p3 = p1;
System.out.print((p1 == p2) + " ");
System.out.print((p1 == p3) + " ");
System.out.print((p1.equals(p2)) + " ");
System.out.println(p1.equals(p3));
}
}
2、Object-equals方法覆盖
class Per extends Object
{
private int age;
Per(int age){
this.age = age;
}
public boolean equals(Person obj){
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
{
throw new ClassCastException("类型错误");
}
Person p = (Person)obj;
return this.age == p.age;
}
}
3、Object-hashCode方法
当重写equals方法时,一般重写该方法,以维护hashCode的常规协定
4、Object-getClass方法 返回Object的运行时类
5、Object-toString方法 返回该对象的字符串表现形式getClass.getName()+"@"+Integer.toHexString(hashCode())
6、异常
描述不正常情况的类称为异常类,以前将正常流程代码和问题处理代码相结合,
现在将正常流程代码和问题代码分离,提高阅读性。
7、异常分为两大类Throwable a、一般不可处理的。Error b、可以处理的 Exception
Throwable:无论是error,还是异常,问题发生就应该可以抛出,让调用者知道并处理。
8、可抛性通过两个关键字来体现:throws、throw
凡是可以被这两个关键字所操作的类和对象都具备可抛性。
9、java虚拟机将传送过来的异常打印到控制台(真实开发时打印到日志)
10、异常信息可以自定义
class Demo
{
public int method(int[] arr,int index)
{
if(arr==null)
throw new NullPointerException("数组的引用不能为空!");
if(index>=arr.length)
{
throw new ArrayIndexOutOfBoundsException("数组的角标越界:"+index);
}
if(index<0)
{
throw new ArrayIndexOutOfBoundsException("数组的角标不能为负:"+index);
}
return arr[index];
}
}
10、异常可以自定义,定义异常类需要继承异常体系,只有成为异常体系的子类才能具有可抛性。
11、异常的分类
a、编译时被检测异常:只要是Exception和其子类都是,除了特殊子类RuntimeException体系。
b、编译时不检测异常(运行时异常):就是Exception中的RuntimeException和其子类。
所以,当自定义的异常继承自Exception时,函数不throws出异常,编译时会报错;若
继承自RuntimeException,则编译时不会报错。
12、throw和throws的区别
throws使用在函数上,throw使用在函数内;throws抛出的是异常类,可以抛出多个,throw抛出的
是异常对象。
13、try(){需要被检测异常的代码} catch(异常类 变量){处理异常的代码} finally{一定会被执行的代码}
14、finally代码块作用:try{} finally{} 也比较常见,异常无法直接catch处理,但资源需要关闭
例如连接数据库、查询、关闭连接。查询时出异常了,则需要靠finally代码块执行关闭动作、释放资源
15、异常转换
16、异常的注意事项
a、子类在覆盖父类方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常或者该异常的子类。
b、如果父类抛出多个异常,那么子类只能抛出父类异常的子集。
day12
1、包 对类文件进行分类管理,给类提供多层命名空间,写在程序文件的第一行
类名的全称是包名.类名 包也是一种封装形式
2、包在文件系统中的体现是文件夹。
3、包与包之间的类进行访问,被访问的包中的类必须是public的,被访问的包中的类的方法也必须是public的。
4、protected不同包中只有子类可以
5、 public protected default private
同一类中 √ √ √ √
同一包中 √ √ √
子类中 √ √
不同包中 √
6、import关键字可以导入其他包中的类,这样可以在使用其他包中的类时,不再需要添加包名。
7、多线程的两种线程创建方式
a、以定义Thread类子类的方式创建线程 b、以创建Runnable接口实例的方式创建线程
8、调用thread.run不能开启线程,需要用thread.start才开启线程。
9、Thread.currentThread().getName()
线程在创建时即确定了编号从Thread-0开始,也可以自行定义,通过重写带参构造函数
class Demo extends Thread
{
private String name;
Demo(String name)
{
super(name);
}
public void run()
{
for(int x=0; x<10; x++)
{
System.out.println(name+"....x="+x+".....name="+Thread.currentThread().getName());
}
}
}
class ThreadDemo2
{
public static void main(String[] args)
{
Demo d1 = new Demo("旺财");
Demo d2 = new Demo("xiaoqiang");
d1.start();
d2.start();
System.out.println("over...."+Thread.currentThread().getName());
}
}
day13
1、线程的四种状态
start() ------------------------->
被创建---------------->运行 sleep() wait() 冻结
| | <------------------------- |
| run() | sleep() notify() |
| stop()| |
| stop() | |
------------------> 消亡 <----------------------------
sleep方法需要指定睡眠时间,单位是毫秒。
一个特殊的状态:就绪。 具备了执行资格,但是还没有获取资源。
2、CPU的执行资格:可以被CPU处理,在处理队列中排队
CPU的执行权:正在被CPU处理的
运行:具备执行资格和执行权 冻结:释放执行权的同时释放执行资格
临时阻塞状态:具备执行资格,但不具备执行权,在等待其他线程释放执行权。
3、创建线程方式一:继承Thread类。
步骤:
a、定义一个类继承Thread类。
b、覆盖Thread类中的run方法。
c、直接创建Thread的子类对象创建线程。
d、调用start方法开启线程并调用线程的任务run方法执行。
4、创建线程的第二种方式:实现Runnable接口。
a、定义类实现Runnable接口
b、覆盖接口中的run方法,将线程的任务代码封装到run方法中。
c、通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递。
为什么?因为线程的任务都封装在Runnable接口子类对象的run方法中。
所以要在线程对象创建时就必须明确要运行的任务。
d、调用线程对象的start方法开启线程。
5、实现Runnable接口的好处:
a、将线程的任务从线程的子类中分离,进行单独封装。按照面向对象的思想将任务的封装成对象。
b、避免了java单继承的局限性。
所以,创建线程的第二种方式较为常用。
6、多次启动一个线程是非法的。
7、卖票实例 使用第二种创建线程的方法,可以只创建一个线程(有安全性问题),与static效果相同。
8、线程的安全性问题产生原因
a、多个线程在操作共享的数据
b、操作共享数据的线程代码有多条
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会出现问题。
9、同步代码块
线程的安全性问题解决思路;
就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程时不可以参与运算的。
必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。
在java中,用同步代码块就可以解决这个问题。
同步代码块的格式:
synchronized(对象)
{
需要被同步的代码 ;
}
class Ticket implements Runnable
{
private int num = 100;
Object obj = new Object();
public void run()
{
while(true)
{
synchronized(obj)
{
if(num>0)
{
try{Thread.sleep(10);}catch (InterruptedException e){}
System.out.println(Thread.currentThread().getName()+".....sale...."+num--);
}
}
}
}
}
class TicketDemo
{
public static void main(String[] args)
{
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
10、同步的好处:解决了线程的安全问题。
同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁。
同步的前提:同步中必须有多个线程并使用同一个锁。
11、同步函数
class Bank
{
private int sum;
public synchronized void add(int num)
{
sum = sum + num;
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println("sum="+sum);
}
}
class Cus implements Runnable
{
private Bank b = new Bank();
public void run()
{
for(int x=0; x<3; x++)
{
b.add(100);
}
}
}
12、同步函数用的锁是线程对象实例(this)的锁
同步函数和同步代码块的区别:
同步函数的锁是固定的this。同步代码块的锁是任意的对象。建议使用同步代码块。
class Ticket implements Runnable
{
private int num = 100;
boolean flag = true;
public void run()
{
if(flag)
while(true)
{
synchronized(this)
{
if(num>0)
{
try{Thread.sleep(10);}catch (InterruptedException e){}
System.out.println(Thread.currentThread().getName()+".....obj...."+num--);
}
}
}
else
while(true)
this.show();
}
public synchronized void show()
{
if(num>0)
{
try{Thread.sleep(10);}catch (InterruptedException e){}
System.out.println(Thread.currentThread().getName()+".....function...."+num--);
}
}
}
class SynFunctionLockDemo
{
public static void main(String[] args)
{
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
try{Thread.sleep(10);}catch(InterruptedException e){}
t.flag = false;
t2.start();
}
}
13、静态同步函数的锁是该函数所属字节码文件对象,可以用getClass方法或当前类名.class表示。
14、懒汉式单例模式的同步和效率问题
class Single
{
private static Single s = null;
private Single(){}
public static Single getInstance()
{
if(s==null)
{
synchronized(Single.class)
{
if(s==null)
s = new Single();
}
}
return s;
}
}
class SingleDemo
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
day14
1、线程间通讯
多个线程在处理同一资源,但任务却不同。
2、下面程序解决多线程访问同一资源的问题,但存在长时间执行一个线程,切换慢的问题
class Resource
{
String name;
String sex;
}
class Input implements Runnable
{
Resource r ;
Input(Resource r)
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
synchronized(r)
{
if(x==0)
{
r.name = "mike";
r.sex = "nan";
}
else
{
r.name = "丽丽";
r.sex = "女女女女女女";
}
}
x = (x+1)%2;
}
}
}
class Output implements Runnable
{
Resource r;
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
synchronized(r)
{
System.out.println(r.name+"....."+r.sex);
}
}
}
}
class ResourceDemo
{
public static void main(String[] args)
{
Resource r = new Resource();
Input in = new Input(r);
Output out = new Output(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
3、等待、唤醒机制
a、wait() 让线程处于冻结状态,被wait的线程会被存储到线程池中。
b、notify() 唤醒线程池中的一个线程(任意)。
c、notifyAll() 唤醒线程池中的所有线程。
这些方法都必须用于同步中,因为这些方法都是用于操作线程状态的方法,
必须要明确操作的哪个锁上的线程。
class Resource
{
String name;
String sex;
boolean flag = false;
}
class Input implements Runnable
{
Resource r ;
Input(Resource r)
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
synchronized(r)
{
if(r.flag)
try{r.wait();}catch(InterruptedException e){}
if(x==0)
{
r.name = "mike";
r.sex = "nan";
}
else
{
r.name = "丽丽";
r.sex = "女女女女女女";
}
r.flag = true;
r.notify();
}
x = (x+1)%2;
}
}
}
class Output implements Runnable
{
Resource r;
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
synchronized(r)
{
if(!r.flag)
try{r.wait();}catch(InterruptedException e){}
System.out.println(r.name+"....."+r.sex);
r.flag = false;
r.notify();
}
}
}
}
class ResourceDemo2
{
public static void main(String[] args)
{
Resource r = new Resource();
Input in = new Input(r);
Output out = new Output(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
4、为什么操作线程的方法wait、notify、notifyAll定义在了Object类中?
因为这些方法是监视器的方法。监视器其实就是锁。
锁可以是任意的对象,任意的对象调用的方式一定定义在Object类中。
5、将同步放在资源类中,进行优化
class Resource
{
private String name;
private String sex;
private boolean flag = false;
public synchronized void set(String name,String sex)
{
if(flag)
try{this.wait();}catch(InterruptedException e){}
this.name = name;
this.sex = sex;
flag = true;
this.notify();
}
public synchronized void out()
{
if(!flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(name+"...+...."+sex);
flag = false;
notify();
}
}
class Input implements Runnable
{
Resource r ;
Input(Resource r)
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
if(x==0)
{
r.set("mike","nan");
}
else
{
r.set("丽丽","女女女女女女");
}
x = (x+1)%2;
}
}
}
class Output implements Runnable
{
Resource r;
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class ResourceDemo3
{
public static void main(String[] args)
{
Resource r = new Resource();
Input in = new Input(r);
Output out = new Output(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
6、生产者和消费者
多生产者和多消费者(while(flag)\notifyAll)
if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。
while判断标记,解决了线程获取执行权后,是否要运行!
notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。
notifyAll解决了本方线程一定会唤醒对方线程的问题。
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
public synchronized void set(String name)
{
while(flag)
try{this.wait();}catch(InterruptedException e){}
this.name = name + count;
count++;
System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
flag = true;
notifyAll();
}
public synchronized void out()
{
while(!flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"...消费者........"+this.name);
flag = false;
notifyAll();
}
}
class Producer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.set("烤鸭");
}
}
}
class Consumer implements Runnable
{
private Resource r;
Consumer(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class ProducerConsumerDemo
{
public static void main(String[] args)
{
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t0 = new Thread(pro);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
Thread t3 = new Thread(con);
t0.start();
t1.start();
t2.start();
t3.start();
}
}
7、jdk1.5新特性lock(锁)和condition(监视器)
一把锁获取两组监视器,一组监视生产者,一组监视消费者
import java.util.concurrent.locks.*;
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
Lock lock = new ReentrantLock();
Condition producer_con = lock.newCondition();
Condition consumer_con = lock.newCondition();
public void set(String name)
{
lock.lock();
try
{
while(flag)
try{producer_con.await();}catch(InterruptedException e){}
this.name = name + count;
count++;
System.out.println(Thread.currentThread().getName()+"...生产者5.0..."+this.name);
flag = true;
consumer_con.signal();
}
finally
{
lock.unlock();
}
}
public void out()
{
lock.lock();
try
{
while(!flag)
try{cousumer_con.await();}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"...消费者.5.0......."+this.name);
flag = false;
producer_con.signal();
}
finally
{
lock.unlock();
}
}
}
class Producer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.set("烤鸭");
}
}
}
class Consumer implements Runnable
{
private Resource r;
Consumer(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class ProducerConsumerDemo2
{
public static void main(String[] args)
{
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t0 = new Thread(pro);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
Thread t3 = new Thread(con);
t0.start();
t1.start();
t2.start();
t3.start();
}
}
8、a、wait可以指定时间也可以不指定。
sleep必须指定时间。
b、在同步中时,对cpu的执行权和锁的处理不同。
wait:释放执行权,释放锁。
sleep:释放执行权,不释放锁。
9、停止线程方式 定义标记和interrupt(将线程从冻结态强制转换到运行态,会抛出异常)
10、setDaemon将线程标记为守护(后台)线程或用户线程。当运行的线程都是守护线程时,Java虚拟机退出。
11、join等待该线程运行完成。setPriority设置优先级。
day15
1、字符串对象一旦被创建就不会再改变,存储在字符串常量区中。
2、String类中的equals覆写了Object中的equals,建立了string类的判断字符串是否相同的依据。
public class StringDemo {
public static void main(String[] args) {
stringDemo1();
stringDemo2();
}
public static void stringDemo2() {
String s = "abc";
String s1 = new String("abc");
System.out.println(s==s1);
System.out.println(s.equals(s1));
System.out.println("s="+s);
System.out.println("s1="+s1);
}
private static void stringDemo1() {
String s = "abc";
String s1 = "abc";
System.out.println(s==s1);
s = "nba";
System.out.println(s==s1);
}
}
4、String的构造函数
public class StringConstructorDemo {
public static void main(String[] args) {
stringConstructorDemo();
stringConstructorDemo2();
}
private static void stringConstructorDemo2() {
char[] arr = {'w','a','p','q','x'};
String s = new String(arr,1,3);
System.out.println("s="+s);
}
public static void stringConstructorDemo() {
String s = new String();
byte[] arr = {97,66,67,68};
String s1 = new String(arr);
System.out.println("s1="+s1);
}
}
3、字符串的相关操作
按照面向对象的思想对字符串进行功能分类。
a、获取
1.1 获取字符串中字符的个数(长度).
int length();
1.2 根据位置获取字符。
char charAt(int index);
1.3 根据字符获取在字符串中的第一次出现的位置.
int indexOf(int ch)
int indexOf(int ch,int fromIndex):从指定位置进行ch的查找第一次出现位置
int indexOf(String str);
int indexOf(String str,int fromIndex);
根据字符串获取在字符串中的第一次出现的位置.
int lastIndexOf(int ch)
int lastIndexOf(int ch,int fromIndex):从指定位置进行ch的查找第一次出现位置
int lastIndexOf(String str);
int lastIndexOf(String str,int fromIndex);
1.4 获取字符串中一部分字符串。也叫子串.
String substring(int beginIndex, int endIndex)
String substring(int beginIndex);
b、转换
2.1 将字符串变成字符串数组(字符串的切割)
String[] split(String regex):涉及到正则表达式.
2.2 将字符串变成字符数组。
char[] toCharArray();
2.3 将字符串变成字节数组。
byte[] getBytes();
2.4 将字符串中的字母转成大小写。
String toUpperCase():大写
String toLowerCase():小写
2.5 将字符串中的内容进行替换
String replace(char oldch,char newch);
String replace(String s1,String s2);
2.6 将字符串两端的空格去除。
String trim();
2.7 将字符串进行连接 。
String concat(string);
c、判断
3.1 两个字符串内容是否相同啊?
boolean equals(Object obj);
boolean equalsIgnoreCase(string str);忽略大写比较字符串内容。
3.2 字符串中是否包含指定字符串?
boolean contains(string str);
3.3 字符串是否以指定字符串开头。是否以指定字符串结尾。
boolean startsWith(string);
boolean endsWith(string);
d、比较 compareTo();
5、intern():对字符串池进行操作的
6、StringBuffer
StringBuffer:就是字符串缓冲区。用于存储数据的容器。
特点:
a、长度的可变的。
b、可以存储不同类型数据。
c、最终要转成字符串进行使用。
d、可以对字符串进行修改。
7、既然是一个容器对象。应该具备功能
a、添加:
StringBuffer append(data);
StringBuffer insert(index,data);
b、删除:
StringBuffer delete(start,end):包含头,不包含尾。
StringBuffer deleteCharAt(int index):删除指定位置的元素
c、查找:
char charAt(index);
int indexOf(string);
int lastIndexOf(string);
d、修改:
StringBuffer replace(start,end,string);
void setCharAt(index,char);
8、jdk1.5以后出现了功能和StringBuffer一模一样的对象。就是StringBuilder
不同的是:
StringBuffer是线程同步的。通常用于多线程。
StringBuilder是线程不同步的。通常用于单线程。 它的出现提高效率。
jdk升级:简化书写。提高效率。增加安全性。
day16
1、基本数据类型对象包装类
好处:可以在对象中定义更多的功能方法操作该数据。
2、基本数据类型对应的封装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
3、该包装对象主要用于基本类型和字符串之间的转换
基本类型--->字符串
a,基本类型数值+""
b,用String类中的静态方法valueOf(基本类型数值);
c,用Integer的静态方法valueOf(基本类型数值);
字符串--->基本类型
a,使用包装类中的静态方法 xxx parseXxx("xxx类型的字符串");*****
int parseInt("intstring");
long parseLong("longstring");
boolean parseBoolean("booleanstring");
只有Character没有parse方法
b,如果字符串被Integer进行对象的封装。
可使用另一个非静态的方法,intValue();
将一个Integer对象转成基本数据类型值。
4、进制转换
整数具备不同的进制体现
十进制-->其他进制
toBinaryString
toOctalString
toHexString
System.out.println(Integer.toBinaryString(60));
System.out.println(Integer.toOctalString(60));
System.out.println(Integer.toHexString(60));
其他进制-->十进制
parseInt("string",radix)
System.out.println(Integer.parseInt("3c",16));
5、自动装箱 Integer i = new Integer(4); Integer i = 4;(jdk1.5之后新特性,自动装箱)
Integer a = new Integer(128);
Integer b = new Integer(128);
System.out.print((a == b) + " ");
System.out.print(a.equals(b) + " ");
Integer a1 = new Integer(129);
Integer b1 = new Integer(129);
System.out.print((a1 == b1) + " ");
System.out.print(a1.equals(b1) + " ");
Integer x = 127;
Integer y = 127;
System.out.print((x == y) + " ");
System.out.print(x.equals(y) + " ");
Integer x1 = 128;
Integer y1 = 128;
System.out.print((x1 == y1) + " ");
System.out.print(x1.equals(y1) + " ");
6、集合框架
为什么会出现集合类?
用于存放对象的容器。数组是固定长度,集合长度可变。集合中不可以存储基本数据类型值。
7、体系与共性功能
集合容器因为内部的数据结构不同,有多种具体容器。不断向上抽取,就形成了集合框架。
框架的顶层就是Collection接口,其常见方法如下:
a、添加:
boolean add(E e);
boolean addAll(Collection<?> coll);
b、删除:
boolean remove(object obj);
boolean removeAll(Collection<?> coll);
void clear();
c、判断:
boolean contains(object obj);
boolean containsAll(Collection coll);
boolean isEmpty();
d、获取:
int size();
Iterator<E> iterator();
e、其他:
boolean retainAll(Collection coll);
Object[] toArray();
8、迭代器的使用
public class IteratorDemo {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add("abc1");
coll.add("abc2");
coll.add("abc3");
coll.add("abc4");
for(Iterator it = coll.iterator(); it.hasNext(); ){
System.out.println(it.next());
}
}
}
9、List和Set的区别
List:有序(存入和取出的顺序一致),元素都有索引,可以重复。
Set: 元素不能重复,无序。
10、List的常用方法:共性特点是可以操作角标。
a、增加:
void add(index, element);
void add(index,collection);
b、删除:
Object remove(index);
c、修改:
Object set(index,element);
d、获取:
Object get(index);
int indexOf(object);
int lastIndexOf(object);
List subList(from, to);
11、ListIterator接口 迭代过程中修改集合
public class ListDemo2 {
public static void main(String[] args) {
List list = new ArrayList();
list.add("abc1");
list.add("abc2");
list.add("abc3");
System.out.println("list:"+list);
ListIterator it = list.listIterator();
while(it.hasNext()){
Object obj = it.next();
if(obj.equals("abc2")){
it.set("abc9");
}
}
while(it.hasPrevious()){
System.out.println("previous:"+it.previous());
}
System.out.println("list:"+list);
}
public static void show(List list) {
list.add("abc1");
list.add("abc2");
list.add("abc3");
list.add("abc4");
Iterator it = list.iterator();
while(it.hasNext()){
System.out.println("next:"+it.next());
}
for(int x=0; x<list.size(); x++){
System.out.println("get:"+list.get(x));
}
}
}
12、List子类
Vector:内部是数组数据结构,是同步的,线程安全。
ArrayList:内部是数组数据结构,是不同步的。替代Vector。查询速度快。
LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。
day17
1、LinkedList
addFist(E e); addLast(E e);
offerFirst(); offerLast(); jdk1.6
getFirst(); getLast();
peekFirst(); peekLast(); jdk1.6 当链表为空时,不抛出异常,返回空
removeFirst(); removeLast();
pollFirst(); pollLast(); jdk1.6 当链表为空时,不抛出异常,返回空
2、用LinkedList模拟一个堆栈或者数据结构
import java.util.LinkedList;
public class DuiLie {
private LinkedList link;
public DuiLie() {
link = new LinkedList();
}
public void myAdd(Object obj) {
link.addLast(obj);
}
public Object myGet() {
return link.removeFirst();
}
public boolean isNull() {
return link.isEmpty();
}
}
3、ArrayList存储自定义对象
import java.util.ArrayList;
import java.util.Iterator;
import cn.itcast.p.bean.Person;
public class ArrayListTest {
public static void main(String[] args) {
Person p1 = new Person("lisi1",21);
ArrayList al = new ArrayList();
al.add(p1);
al.add(new Person("lisi2",22));
al.add(new Person("lisi3",23));
al.add(new Person("lisi4",24));
Iterator it = al.iterator();
while(it.hasNext()){
Person p = (Person) it.next();
System.out.println(p.getName()+"--"+p.getAge());
}
}
}
4、HashSet元素不能重复,无序。Set中的方法和Collection中一样。
5、HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。
不保证迭代顺序,也不保证该顺序恒久不变,此类允许使用null元素。
6、哈希表确定元素是否相同
a、判断两个元素的哈希值是否相同,如果相同,判断两个对象内容是否相同。
b、判断哈希值是否相同,其实判断的是hashCode的方法。判断内容用的equals方法。
7、HashSet存储自定义对象
public class Person implements Comparable {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
return name.hashCode()+age*27;
}
@Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(!(obj instanceof Person))
throw new ClassCastException("类型错误");
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return name+":"+age;
}
@Override
public int compareTo(Object o) {
Person p = (Person)o;
int temp = this.age-p.age;
return temp==0?this.name.compareTo(p.name):temp;
}
}
public class HashSetTest {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Person("lisi4",24));
hs.add(new Person("lisi7",27));
hs.add(new Person("lisi1",21));
hs.add(new Person("lisi9",29));
hs.add(new Person("lisi7",27));
Iterator it = hs.iterator();
while(it.hasNext()){
Person p = (Person)it.next();
System.out.println(p);
}
}
}
8、LinkedHashSet具有可预知迭代顺序的Set接口的哈希表和链接列表实现。
9、TreeSet 使用元素的自然顺序对数据进行排序,是不同步的。
判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,是0,就是相同元素,不存。
TreeSet排序自定义的对象,需要重写compareTo方法。
10、Treeset如果不要按照对象中具备的自然排序进行排序,或不具备自然排序,使用第二种方法:
让集合自身具备比较功能,利用创建集合时的构造函数
Treeset(Comparator<? super E> comparator) 构造一个新的空TreeSet,它根据指定比较器进行排序。
package cn.itcast.p5.comparator;
import java.util.Comparator;
import cn.itcast.p.bean.Person;
public class ComparatorByName implements Comparator {
@Override
public int compare(Object o1, Object o2) {
Person p1 = (Person)o1;
Person p2 = (Person)o2;
int temp = p1.getName().compareTo(p2.getName());
return temp==0?p1.getAge()-p2.getAge(): temp;
}
}
package cn.itcast.p5.treeset.demo;
import java.util.Iterator;
import java.util.TreeSet;
import cn.itcast.p.bean.Person;
import cn.itcast.p5.comparator.ComparatorByName;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet(new ComparatorByName());
ts.add(new Person("zhangsan",28));
ts.add(new Person("lisi",21));
ts.add(new Person("zhouqi",29));
ts.add(new Person("zhaoliu",25));
ts.add(new Person("wangu",24));
Iterator it = ts.iterator();
while(it.hasNext()){
Person p = (Person)it.next();
System.out.println(p.getName()+":"+p.getAge());
}
}
}
11、TreeSet集合--二叉树 怎么存怎么取,实现让比较器返回1
day18
1、Map接口:一次添加一对元素,也称为双列集合。map集合必须保证键的唯一性。
2、常用方法:
a、添加
V put(K key, V value);
b、删除
void clear();
V remove(K key);
c、判断
boolean containsKey(K key);
boolean containsValue(V value);
boolean isEmpty();
d、获取
V get(K key);
int size();
3、keySet方法
Set<E> keySet();
4、entrySet方法
public Set<Map,Entry<K, V>> entrySet();
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class MapDemo {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer,String>();
method_2(map);
}
public static void method_2(Map<Integer,String> map){
map.put(8,"zhaoliu");
map.put(2,"zhaoliu");
map.put(7,"xiaoqiang");
map.put(6,"wangcai");
Collection<String> values = map.values();
Iterator<String> it2 = values.iterator();
while(it2.hasNext()){
System.out.println(it2.next());
}
Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
Iterator<Map.Entry<Integer, String>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<Integer, String> me = it.next();
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+"::::"+value);
}
}
}
5、Collection<V> values();
6、Map常用子类:
Hashtable:内部结构是哈希表,是同步的。不允许null作为键和值。
Properties:表示一个持久的属性集,可以保存在流中或从中加载。属性列表中每个
键及对应值都是一个字符串。
HashMap:内部结构是哈希表,不是同步的。允许null作为键和值。
TreeMap:内部结构是二叉树,不是同步的。可以对Map集合中的键值进行排序。
7、泛型(JDK1.5以后出现的机制)ArrayList<String> a1 = new ArrayList<String>();
泛型出现的原因:提高集合的安全性。
反省出现的好处:将运行时期的问题暴露在编译时期。避免了强制转换的麻烦。
泛型的书写格式:<>就是一个用于接收具体引用数据类型的参数范围。在程序中,只要用到
了带有<>的类或者接口,就要明确传入的具体引用数据类型。
自定义泛型类:
public class Tool<QQ>{
private QQ q;
public QQ getObject() {
return q;
}
public void setObject(QQ object) {
this.q = object;
}
}
8、擦除与补偿
泛型技术是给编译器使用的技术,用于编译时期,确保类型安全。
运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除,
目的为了兼容运行的类加载器。
在运行时,通过获取元素的类型进行转换动作,不用使用者进行强制转换,称为泛型的补偿。
9、泛型方法(泛型定义在类型的前面,修饰符的后面)
public class Tool<QQ>{
private QQ q;
public QQ getObject() {
return q;
}
public void setObject(QQ object) {
this.q = object;
}
public <W> void show(W str){
System.out.println("show : "+str.toString());
}
public void print(QQ str){
System.out.println("print : "+str);
}
public static <Y> void method(Y obj){
System.out.println("method:"+obj);
}
}
10、泛型接口
public class GenericDefineDemo5 {
public static void main(String[] args) {
InterImpl in = new InterImpl();
in.show("abc");
InterImpl2<Integer> in2 = new InterImpl2<Integer>();
in2.show(5);
}
}
interface Inter<T>{
public void show(T t);
}
class InterImpl2<Q> implements Inter<Q>{
public void show(Q q){
System.out.println("show :"+q);
}
}
class InterImpl implements Inter<String>{
public void show(String str){
System.out.println("show :"+str);
}
}
11、泛型的限定
? extends E:接收E类型或者E的子类型对象,上限
? super E:接收E类型或者E的父类型,下限
public class GenericAdvanceDemo2 {
public static void main(String[] args) {
ArrayList<Person> al = new ArrayList<Person>();
al.add(new Person("abc",30));
al.add(new Person("abc4",34));
ArrayList<Student> al2 = new ArrayList<Student>();
al2.add(new Student("stu1",11));
al2.add(new Student("stu2",22));
ArrayList<String> al3 = new ArrayList<String>();
al3.add("stu3331");
al3.add("stu33332");
printCollection(al2);
printCollection(al);
}
public static void printCollection(Collection<? super Student> al){
Iterator<? super Student> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
12、上限应用
public static void main(String[] args) {
ArrayList<Person> al1 = new ArrayList<Person>();
al1.add(new Person("abc",30));
al1.add(new Person("abc4",34));
ArrayList<Student> al2 = new ArrayList<Student>();
al2.add(new Student("stu1",11));
al2.add(new Student("stu2",22));
ArrayList<Worker> al3 = new ArrayList<Worker>();
al3.add(new Worker("stu1",11));
al3.add(new Worker("stu2",22));
ArrayList<String> al4 = new ArrayList<String>();
al4.add("abcdeef");
al1.addAll(al2);
al1.addAll(al3);
System.out.println(al1.size());
}
}
class MyCollection<E>{
public void add(E e){
}
public void addAll(MyCollection<? extends E> e){
}
}
13、通常对集合中的元素进行取出操作时,可以是用下限。比较器
14、通配符的体现
public class GenericAdvanceDemo{
public static void main(String[] args) {
ArrayList<Person> al1 = new ArrayList<Person>();
al1.add(new Person("abc",30));
al1.add(new Person("abc4",34));
ArrayList<Person> al2 = new ArrayList<Person>();
al2.add(new Person("abc22222",30));
al2.add(new Person("abc42222222",34));
ArrayList<String> al4 = new ArrayList<String>();
al4.add("abcdeef");
al4.add("abc");
al1.containsAll(al4);
}
public static void printCollection(Collection<?> al){
Iterator<?> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
}
class MyCollection2<E>{
public boolean containsAll(Collection<?> coll){
return true;
}
}
15、集合使用技巧
是否需要唯一
需要:set
是否需要指定顺序:
需要:TreeSet
不需要:HashSet
但是想要一个和存储一致的顺序:LinkedHashSet
不需要:list
是否需要频繁增删:
需要:LinkedList
不需要:ArrayList
后缀名就是该集合所属的体系,前缀名就是该集合的数据结构。
看到array:数组,查询快,有角标。
看到link:链表,增删快,add\get\remove+first\last方法。
看到hash:哈希表,想到唯一性,元素需要覆盖hashcode方法和equals方法。
看到tree:二叉树,排序,两个接口Comparable和Comparator。
day19
1、集合框架工具类Collections(s和Collection接口分开)
2、排序、折半查找、最值、逆序、替换、随机 https://docs.oracle.com/javase/8/docs/api/
3、将非同步集合转换为同步集合的方法
4、集合框架工具类Arrays
public static String myToString(int[] a){
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
5、将数组转换为List集合 Arrays类 public static <T> List<T> asList(T... a)
好处:可以使用集合的方法操作数组中的元素
注意:
数组的长度是固定的,所以对于集合的增删方法是不可以使用的,否则会报异常。
如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。
如果数组中的元素是基本类型数值,那么会将该数组作为集合中的元素进行存储。
6、将List集合转换为数组 Collection类 Object[] toArray()
作用:对集合中的元素操作的方法进行限定,不允许对其进行增删。
toArray方法需要传入一个指定类型的数组。
如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同size的数组。
如果长度大于集合的size,那么该方法就会使用指定的数组,存储集合中的元素,其他位置默认为null。
所以建议,最后长度就指定为,集合的size。
String[] arr = list.toArray(new String[list.size()]);
7、jdk1.5新特性:ForEach 只用于遍历,不操作,简化书写
public class ForEachDemo {
public static void main(String[] args) {
List<String> list =new ArrayList<String>();
list.add("abc1");
list.add("abc2");
list.add("abc3");
for(String s : list){
System.out.println(s);
}
int[] arr = {3,1,5,7,4};
for(int i : arr){
System.out.println(i);
}
Map<Integer,String> map = new HashMap<Integer,String>();
map.put(3,"zhagsan");
map.put(1,"wangyi");
map.put(7,"wagnwu");
map.put(4,"zhagsansan");
for(Integer key : map.keySet()){
String value = map.get(key);
System.out.println(key+"::"+value);
}
for(Map.Entry<Integer,String> me : map.entrySet()){
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+":"+value);
}
}
}
8、jdk1.5新特性:函数可变参数
public class ParamterDemo {
public static void main(String[] args) {
int sum = newAdd(5,1,4,7,3);
System.out.println("sum="+sum);
int sum1 = newAdd(5,1,2,7,3,9,8,7,6);
System.out.println("sum1="+sum1);
}
public static int newAdd(int a,int... arr){
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
return sum;
}
public static int add(int[] arr){
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
return sum;
}
}
9、jdk1.5新特性:静态导入
import java.util.Collections;
import java.util.List;
import static java.util.Collections.*;
import static java.lang.System.*;
public class StaticImportDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("abc3");
list.add("abc7");
list.add("abc1");
out.println(list);
sort(list);
System.out.println(list);
String max = max(list);
System.out.println("max="+max);
}
}
day20
1、System类
public class SystemDemo {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static void main(String[] args) {
System.out.println("hello-"+LINE_SEPARATOR+" world");
demo_1();
System.setProperty("myclasspath", "c:\myclass");
}
public static void demo_1(){
Properties prop = System.getProperties();
Set<String> nameSet = prop.stringPropertyNames();
for(String name : nameSet){
String value = prop.getProperty(name);
System.out.println(name+"::"+value);
}
}
}
2、Runtime类
public class RuntimeDemo {
public static void main(String[] args) throws IOException, InterruptedException {
Runtime r = Runtime.getRuntime();
Process p = r.exec("notepad.exe");
Thread.sleep(5000);
p.destroy();
}
}
3、Math类 其中的方法全部都是静态的。
4、Date类
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateDemo {
public static void main(String[] args) throws ParseException {
methodDemo_1();
methodDemo_2();
methodDemo_3();
}
public static void methodDemo_3() throws ParseException {
String str_date = "2012年4月19日";
str_date = "2011---8---17";
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);
dateFormat = new SimpleDateFormat("yyyy---MM---dd");
Date date = dateFormat.parse(str_date);
System.out.println(date);
}
public static void methodDemo_2() {
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);
dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
dateFormat = new SimpleDateFormat("yyyy--MM--dd");
String str_date = dateFormat.format(date);
System.out.println(str_date);
}
public static void methodDemo_1() {
long time = System.currentTimeMillis();
Date date = new Date();
System.out.println(date);
Date date2 = new Date(1335664696656l);
System.out.println(date2);
}
}
5、Calendar类
因为Date的接口不易于实现国际化,从jdk1.1开始,使用Calendar类来
实现日期和时间字段之间的转换,使用DateFormat类来格式化和解析日期字符串。
import java.util.Calendar;
public class CalendarDemo {
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
int year = 2012;
showDays(year);
}
public static void showDays(int year) {
Calendar c = Calendar.getInstance();
c.set(year, 2, 1);
c.add(Calendar.DAY_OF_MONTH, -1);
showDate(c);
}
public static void showDate(Calendar c) {
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+1;
int day = c.get(Calendar.DAY_OF_MONTH);
int week = c.get(Calendar.DAY_OF_WEEK);
System.out.println(year+"年"+month+"月"+day+"日"+getWeek(week));
}
public static String getWeek(int i) {
String[] weeks = {"","星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
return weeks[i];
}
}
6、IO流
IO流用来处理设备之间的数据输出
Java对数据的操作是通过流的方式,用于操作流的对象都在IO包中
流按操作数据分为两种:字节流与字符流
7、字符流的由来:字节流读取文字字节数据后,不直接操作而是先查指定的编码表,
获取对应的文字,然后对文字进行操作。简单说:字节流+编码表
8、字节流的抽象基类 InputStream、OutputStream
字符流的抽象基类 Reader、Writer
字符流和字节流的子类以基类作为名称后半部分,前半部分就是该类的功能
9、要操作文字数据,优先考虑字符流。要将数据从内存写到硬盘上,要使用字符流中的输出流。
FileWriter
import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static void main(String[] args) throws IOException{
FileWriter fw = new FileWriter("demo.txt", true);
fw.write("test filewriter"+LINE_SEPARATOR+"test change line");
fw.close();
}
}
10、流对象在try的外面创建引用变量,在try的里面初始化
import java.io.FileWriter;
import java.io.IOException;
public class IOExceptionDemo {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("k:\\demo.txt");
fw.write("test filewriter"+LINE_SEPARATOR+"test change line");
} catch (IOException e) {
System.out.println(e.toString());
} finally {
if (fw != null)
try {
fw.close();
} catch (IOException e) {
throw new RuntimeException("关闭失败");
}
}
}
}
11、Reader FileReader read和read(char[])
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("demo.txt");
int ch = 0;
while((ch=fr.read())!=-1){
System.out.println((char)ch);
}
fr.close();
}
}
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo2 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("demo.txt");
char[] buf = new char[1024];
int len = 0;
while((len=fr.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
fr.close();
}
}
day21
1、复制文件
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("IO流_2.txt");
FileWriter fw = new FileWriter("copytext_1.txt");
int ch = 0;
while((ch=fr.read())!=-1){
fw.write(ch);
}
fw.close();
fr.close();
}
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader("IO流_2.txt");
fw = new FileWriter("copytest_2.txt");
char[] buf = new char[BUFFER_SIZE];
int len = 0;
while((len=fr.read(buf))!=-1){
fw.write(buf, 0, len);
}
} catch (Exception e) {
throw new RuntimeException("读写失败");
}finally{
if(fw!=null)
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
if(fr!=null)
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2、字符流的缓冲区
缓冲区的出现提高了对数据的读写效率。对应类BufferWriter、BufferReader
缓冲区要结合流才可以使用,在流的基础上对流的功能进行了增强。
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriterDemo {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("buf.txt");
BufferedWriter bufw = new BufferedWriter(fw);
for(int x=1; x<=4; x++){
bufw.write("abcdef"+x);
bufw.newLine();
bufw.flush();
}
bufw.close();
}
}
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("buf.txt");
BufferedReader bufr = new BufferedReader(fr);
String line = null;
while((line=bufr.readLine())!=null){
System.out.println(line);
}
bufr.close();
}
}
3、装饰设计模式:对一组对象的功能进行增强时,可以使用该模式。
public class PersonDemo {
public static void main(String[] args) {
Person p = new Person();
p.chifan();
NewPerson p1 = new NewPerson(p);
p1.chifan();
NewPerson2 p2 = new NewPerson2();
p2.chifan();
}
}
class Person{
void chifan(){
System.out.println("吃饭");
}
}
class NewPerson{
private Person p ;
NewPerson(Person p){
this.p = p;
}
public void chifan(){
System.out.println("开胃酒");
p.chifan();
System.out.println("甜点");
}
}
class NewPerson2 extends Person{
public void chifan(){
System.out.println("开胃酒");
super.chifan();
System.out.println("甜点");
}
}
4、装饰设计模式和继承(都进行功能的扩展)的区别
继承会导致继承体系越来越臃肿。装饰比继承更为灵活。
装饰类和被装饰类都必须属于同一个接口或者父类。装饰类也要继承,直接继承父类。
5、LineNumberReader 设置和读取行号
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
public class LineNumberReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("IO流_2.txt");
LineNumberReader lnr = new LineNumberReader(fr);
String line = null;
lnr.setLineNumber(100);
while((line=lnr.readLine())!=null){
System.out.println(lnr.getLineNumber()+":"+line);
}
lnr.close();
}
}
6、字节流
基本操作与字符流相同,但它不仅可以操作字符,还可以操作其他类型文件。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamDemo {
public static void main(String[] args) throws IOException {
demo_read();
}
public static void demo_read() throws IOException {
FileInputStream fis = new FileInputStream("bytedemo.txt");
System.out.println(fis.available());
byte[] buf = new byte[fis.available()];
fis.read(buf);
System.out.println(new String(buf));
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
fis.close();
}
public static void demo_write() throws IOException {
FileOutputStream fos = new FileOutputStream("bytedemo.txt");
fos.write("abcdefg".getBytes());
fos.close();
}
}
7、copy一个MP3文件
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyMp3Test {
public static void main(String[] args) throws IOException {
copy_4();
}
public static void copy_4() throws IOException {
FileInputStream fis = new FileInputStream("c:\\0.mp3");
FileOutputStream fos = new FileOutputStream("c:\\4.mp3");
int ch = 0;
while((ch =fis.read())!=-1){
fos.write(ch);
}
fos.close();
fis.close();
}
public static void copy_3() throws IOException {
FileInputStream fis = new FileInputStream("c:\\0.mp3");
FileOutputStream fos = new FileOutputStream("c:\\3.mp3");
byte[] buf = new byte[fis.available()];
fis.read(buf);
fos.write(buf);
fos.close();
fis.close();
}
public static void copy_2() throws IOException {
FileInputStream fis = new FileInputStream("c:\\0.mp3");
BufferedInputStream bufis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("c:\\2.mp3");
BufferedOutputStream bufos = new BufferedOutputStream(fos);
int ch = 0;
while((ch=bufis.read())!=-1){
bufos.write(ch);
}
bufos.close();
bufis.close();
}
public static void copy_1() throws IOException {
FileInputStream fis = new FileInputStream("c:\\0.mp3");
FileOutputStream fos = new FileOutputStream("c:\\1.mp3");
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
fis.close();
}
}
day22
1、读取键盘输入
public static void readKey2() throws IOException {
StringBuilder sb = new StringBuilder();
InputStream in = System.in;
int ch = 0;
while((ch=in.read())!=-1){
if(ch=='\r')
continue;
if(ch=='\n'){
String temp = sb.toString();
if("over".equals(temp))
break;
System.out.println(temp.toUpperCase());
sb.delete(0, sb.length());
}
else
sb.append((char)ch);
}
}
2、转换流
InputStreamReader 字节流通向字符流的桥梁,将字节解码成字符
public static void readKey3() throws IOException {
StringBuffer sb = new StringBuffer();
InputStream in = System.in;
InputStreamReader isr = new InputStreamReader(in);
BufferedReader bufr = new BufferedReader(isr);
String line = null;
while((line = bufr.readLine()) != null){
if("over".equals(line))
break;
System.out.println(line.toUpperCase());
}
}
OutputStreamWriter 字符流通向字节流的桥梁,将写入流中的字符编码成字节
public static void readKey3() throws IOException {
StringBuffer sb = new StringBuffer();
InputStream in = System.in;
InputStreamReader isr = new InputStreamReader(in);
BufferedReader bufr = new BufferedReader(isr);
OutputStream out = System.out;
OutputStreamWriter osw = new OutputStreamWriter(out);
BufferedWriter bufw = new BufferedWriter(osw);
String line = null;
while((line = bufr.readLine()) != null){
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
}
简化,一旦有键盘录入
public static void main(String[] args) throws IOException {
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
String line = null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
}
}
a,需求:将键盘录入的数据写入到一个文件中。
b,需求:将一个文本文件内容显示在控制台上。
c,需求:将一个文件文件中的内容复制到的另一个文件中。
该三种需求只需要修改简化代码中的源和目的
3、流的操作规律
转换流:
InputStreamReader:字节流通向字符流的桥梁,将字节解码成字符
OutputStreamWriter:字符流通向字节流的桥梁,将写入流中的字符编码成字节
a、明确源和目的
源:InputStream Reader
目的:OutputStream Writer
b、明确数据是否是纯文本数据
源是否纯文本 是:Reader 否:InputStream
目的是否纯文本 是:Writer 否:OutputStream
c、明确具体设备
源设备:硬盘:File 键盘:System.in 内存:数组 网路:Socket流
目的设备:硬盘:File 控制台:System.out 内存:数组 网路:Socket流
d、是否需要其他额外功能:
是否需要高效(缓冲区)是,就加buffer
4、将一个中文字符串数据按照指定的编码表写入到一个文本文件中.
a、目的。OutputStream,Writer b、是纯文本,Writer。c、设备:硬盘File
FileWriter fw = new FileWriter("a.txt");
fw.write("你好");
注意:既然需求中已经明确了指定编码表的动作。
那就不可以使用FileWriter,因为FileWriter内部是使用默认的本地码表。 只能使用其父类。OutputStreamWriter.
OutputStreamWriter接收一个字节输出流对象,既然是操作文件,那么该对象应该是FileOutputStream
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"),charsetName);
需要高效吗?
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt"),charsetName));
5、什么时候使用转换流?
a、源或者目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换作为桥梁。 提高对文本操作的便捷。
b、一旦操作文本涉及到具体的指定编码表时,必须使用转换流 。
6、File类
用来将文件或者文件夹封装成对象,方便对文件及文件夹的属性信息进行操作。
File对象可以作为参数传递给流的构造函数。
public class FileDemo {
public static void main(String[] args) {
constructorDemo();
}
public static void constructorDemo() {
File f1 = new File("c:\\a.txt");
File f2 = new File("c:\\","a.txt");
File f = new File("c:\\");
File f3 = new File(f,"a.txt");
File f4 = new File("c:"+File.separator+"abc"+File.separator+"a.txt");
System.out.println(f4);
}
}
7、常用方法
a、获取:名称、路径、大小、修改时间
String getName()
String getAbsolutePath();
Stirng getPath()
long length()
long lastModified()
b、创建与删除
boolean createNewFile()
boolean delete()
boolean mkdir()
boolean mkdirs()
c、判断
boolean exists()
boolean isFile())
boolean isDirectory()
d、重命名
boolean renameTo(File dest)
e、系统根目录和容量获取
long getFreeSpace()
long getTotalSpace()
long getUsableSpace()
static File[] listRoots()
f、获取目录内容
String[] list()
8、过滤器 String[] list(FilenameFilter filter)
import java.io.File;
import java.io.FilenameFilter;
public class SuffixFilter implements FilenameFilter {
private String suffix ;
public SuffixFilter(String suffix) {
super();
this.suffix = suffix;
}
@Override
public boolean accept(File dir, String name) {
return name.endsWith(suffix);
}
}
class FileDemo
public static void listDemo_2() {
File dir = new File("c:\\");
String[] names = dir.list(new SuffixFilter(".txt"));
for(String name : names){
System.out.println(name);
}
}
day23
1、深度遍历文件夹
import java.io.File;
public class FileTest {
public static void main(String[] args) {
File dir = new File("e:\\demodir");
listAll(dir,0);
}
public static void listAll(File dir,int level) {
System.out.println(getSpace(level)+dir.getName());
level++;
File[] files = dir.listFiles();
for(int x=0; x<files.length; x++){
if(files[x].isDirectory()){
listAll(files[x],level);
}
else
System.out.println(getSpace(level)+files[x].getName());
}
}
private static String getSpace(int level) {
StringBuilder sb = new StringBuilder();
sb.append("|--");
for(int x=0; x<level; x++){
sb.insert(0,"| ");
}
return sb.toString();
}
}
2、删除文件先删除最里面文件
import java.io.File;
public class RemoveDirTest {
public static void main(String[] args) {
File dir = new File("e:\\demodir");
removeDir(dir);
}
public static void removeDir(File dir) {
File[] files = dir.listFiles();
for(File file : files){
if(file.isDirectory()){
removeDir(file);
}else{
System.out.println(file+":"+file.delete());
}
}
System.out.println(dir+":"+dir.delete());
}
}
3、Properties
表示一个持久的属性集,Properties可保存在流中或从流中加载。
属性列表的每个键及其对应值都是一个字符串。
通常该集合用于操作以键值对形式存在的配置文件。
4、Properties集合的存和取
public static void propertiesDemo(){
Properties prop = new Properties();
prop.setProperty("zhangsan","30");
prop.setProperty("lisi","31");
prop.setProperty("wangwu","36");
prop.setProperty("wangwu","26");
Set<String> names = prop.stringPropertyNames();
for(String name : names){
String value = prop.getProperty(name);
System.out.println(name+":"+value);
}
}
5、Properties类的list方法,将属性列表输出到指定的输出流
public static void methodDemo_2(){
Properties prop = new Properties();
prop.setProperty("zhangsan","30");
prop.setProperty("lisi","31");
prop = System.getProperties();
prop.list(System.out);
}
6、Properties类的store方法
将Properties表中的属性列表(键和元素对)写入输出流。
public static void methodDemo_3() throws IOException {
Properties prop = new Properties();
prop.setProperty("zhangsan","30");
prop.setProperty("lisi","31");
FileOutputStream fos = new FileOutputStream("info.txt");
prop.store(fos, "info");
fos.close();
}
7、Properties类的load方法
从输入流中读取属性列表(键和元素对)。
public static void methodDemo_4() throws IOException {
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("info.txt");
prop.load(fis);
prop.list(System.out);
}
public static void myLoad() throws IOException{
Properties prop = new Properties();
BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));
String line = null;
while((line=bufr.readLine())!=null){
if(line.startsWith("#"))
continue;
String[] arr = line.split("=");
prop.setProperty(arr[0], arr[1]);
}
prop.list(System.out);
bufr.close();
}
8、对已有的配置文件中的信息进行修改。
注意:FileReader和FileWriter实例化的位置
public static void test() throws IOException{
File file = new File("info.txt");
if(!file.exists()){
file.createNewFile();
}
FileReader fr = new FileReader(file);
Properties prop = new Properties();
prop.load(fr);
prop.setProperty("wangwu", "16");
FileWriter fw = new FileWriter(file);
prop.store(fw,"");
fw.close();
fr.close();
}
9、打印流
public class PrintStreamDemo {
public static void main(String[] args) throws IOException {
PrintStream out = new PrintStream("print.txt");
out.close();
}
pubic class PrintWriterDemo {
public static void main(String[] args) throws IOException {
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new FileWriter("out.txt"),true);
String line = null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
out.println(line.toUpperCase());
}
out.close();
bufr.close();
}
10、序列流
SequenceInputStream表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个
输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的
最后一个输入流的文件末尾为止。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
public class SequenceInputStreamDemo {
public static void main(String[] args) throws IOException {
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int x=1; x<=3; x++){
al.add(new FileInputStream(x+".txt"));
}
Enumeration<FileInputStream> en = Collections.enumeration(al);
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("1234.txt");
byte[] buf = new byte[1024];
int len = 0;
while((len=sis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
}
day24
1、文件切割
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class SplitFileDemo {
private static final int SIZE = 1024 * 1024;
public static void main(String[] args) throws Exception {
File file = new File("c:\\aa.mp3");
splitFile_2(file);
}
private static void splitFile_2(File file) throws IOException {
FileInputStream fis = new FileInputStream(file);
byte[] buf = new byte[SIZE];
FileOutputStream fos = null;
int len = 0;
int count = 1;
Properties prop = new Properties();
File dir = new File("c:\\partfiles");
if (!dir.exists())
dir.mkdirs();
while ((len = fis.read(buf)) != -1) {
fos = new FileOutputStream(new File(dir, (count++) + ".part"));
fos.write(buf, 0, len);
fos.close();
}
prop.setProperty("partcount", count+"");
prop.setProperty("filename", file.getName());
fos = new FileOutputStream(new File(dir,count+".properties"));
prop.store(fos, "save file info");
fos.close();
fis.close();
}
public static void splitFile(File file) throws IOException {
FileInputStream fis = new FileInputStream(file);
byte[] buf = new byte[SIZE];
FileOutputStream fos = null;
int len = 0;
int count = 1;
File dir = new File("c:\\partfiles");
if (!dir.exists())
dir.mkdirs();
while ((len = fis.read(buf)) != -1) {
fos = new FileOutputStream(new File(dir, (count++) + ".part"));
fos.write(buf, 0, len);
}
fos.close();
fis.close();
}
}
2、文件合并
import java.io.File;
import java.io.FilenameFilter;
public class SuffixFilter implements FilenameFilter {
private String suffix;
public SuffixFilter(String suffix) {
super();
this.suffix = suffix;
}
@Override
public boolean accept(File dir, String name) {
return name.endsWith(suffix);
}
}
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;
public class MergeFile {
public static void main(String[] args) throws IOException {
File dir = new File("c:\\partfiles");
mergeFile_2(dir);
}
public static void mergeFile_2(File dir) throws IOException {
File[] files = dir.listFiles(new SuffixFilter(".properties"));
if(files.length!=1)
throw new RuntimeException(dir+",该目录下没有properties扩展名的文件或者不唯一");
File confile = files[0];
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(confile);
prop.load(fis);
String filename = prop.getProperty("filename");
int count = Integer.parseInt(prop.getProperty("partcount"));
File[] partFiles = dir.listFiles(new SuffixFilter(".part"));
if(partFiles.length!=(count-1)){
throw new RuntimeException(" 碎片文件不符合要求,个数不对!应该"+count+"个");
}
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int x=0; x<partFiles.length; x++){
al.add(new FileInputStream(partFiles[x]));
}
Enumeration<FileInputStream> en = Collections.enumeration(al);
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream(new File(dir,filename));
byte[] buf = new byte[1024];
int len = 0;
while((len=sis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
public static void mergeFile(File dir) throws IOException{
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int x=1; x<=3 ;x++){
al.add(new FileInputStream(new File(dir,x+".part")));
}
Enumeration<FileInputStream> en = Collections.enumeration(al);
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream(new File(dir,"1.bmp"));
byte[] buf = new byte[1024];
int len = 0;
while((len=sis.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
}
3、操作对象ObjectInputStream和ObjectOutputStream,序列化和反序列化
被操作的对象需要实现Serializable接口(标记接口)
import java.io.Serializable;
public class Person implements Serializable {
private static final long serialVersionUID = 9527l;
private transient String name;
private static int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import cn.itcast.io.p2.bean.Person;
public class ObjectStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
writeObj();
readObj();
}
public static void readObj() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.object"));
Person p = (Person)ois.readObject();
System.out.println(p.getName()+":"+p.getAge());
ois.close();
}
public static void writeObj() throws IOException, IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.object"));
oos.writeObject(new Person("小强",30));
oos.close();
}
}
4、Serializable接口(标记接口)
序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和
接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该对象的类的 serialVersionUID 与对应的发送者的类的版本号不同,则反序列化将会导致InvalidClassException。
可序列化类可以通过声明名为 "serialVersionUID" 的字段(该字段必须是静态 (static)、
最终 (final) 的 long 型字段)显式声明其自己的 serialVersionUID。
5、RandomAccessFile
随机访问文件,自身具备读写的方法,通过skipBytes(int x),seek(int x)来达到随机访问。
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
writeFile();
readFile();
randomWrite();
}
public static void randomWrite() throws IOException{
RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "rw");
raf.seek(3*8);
raf.write("哈哈".getBytes());
raf.writeInt(108);
raf.close();
}
public static void readFile() throws IOException {
RandomAccessFile raf = new RandomAccessFile("ranacc.txt", "r");
raf.seek(1*8);
byte[] buf = new byte[4];
raf.read(buf);
String name = new String(buf);
int age = raf.readInt();
System.out.println("name="+name);
System.out.println("age="+age);
System.out.println("pos:"+raf.getFilePointer());
raf.close();
}
public static void writeFile() throws IOException{
RandomAccessFile raf = new RandomAccessFile("ranacc.txt","rw");
raf.write("张三".getBytes());
raf.writeInt(97);
raf.write("小强".getBytes());
raf.writeInt(99);
raf.close();
}
}
6、管道流PipedStream
输入输出可以直接进行连接,通过结合线程使用。
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipedStream {
public static void main(String[] args) throws IOException {
PipedInputStream input = new PipedInputStream();
PipedOutputStream output = new PipedOutputStream();
input.connect(output);
new Thread(new Input(input)).start();
new Thread(new Output(output)).start();
}
}
class Input implements Runnable{
private PipedInputStream in;
Input(PipedInputStream in){
this.in = in;
}
public void run(){
try {
byte[] buf = new byte[1024];
int len = in.read(buf);
String s = new String(buf,0,len);
System.out.println("s="+s);
in.close();
} catch (Exception e) {
}
}
}
class Output implements Runnable{
private PipedOutputStream out;
Output(PipedOutputStream out){
this.out = out;
}
public void run(){
try {
Thread.sleep(5000);
out.write("hi,管道来了!".getBytes());
} catch (Exception e) {
}
}
}
7、DataInputStream、DataOutputStream 操作基本数据类型
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class DataSteamDemo {
public static void main(String[] args) throws IOException {
writeData();
readData();
}
public static void readData() throws IOException {
DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
String str = dis.readUTF();
System.out.println(str);
}
public static void writeData() throws IOException {
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeUTF("你好");
dos.close();
}
}
8、ByteArrayInputStream、ByteArrayOutputStream 操作字节数组
关闭此流无效,其没有调用底层资源。此类方法在关闭流后仍可调用,不会抛出异常。
9、CharArrayReader与CharArrayWriter 操作字符数组
10、StringReader与StringWriter 操作字符串
11、编码表
import java.io.IOException;
import java.io.UnsupportedEncodingException;
public class EncodeDemo {
public static void main(String[] args) throws IOException {
String str = "谢谢";
byte[] buf = str.getBytes("gbk");
String s1 = new String(buf,"UTF-8");
System.out.println("s1="+s1);
byte[] buf2 = s1.getBytes("UTF-8");
printBytes(buf2);
String s2 = new String(buf2,"GBK");
System.out.println("s2="+s2);
}
public static void encodeDemo(String str)
throws UnsupportedEncodingException {
byte[] buf = str.getBytes("UTF-8");
String s1 = new String(buf,"UTF-8");
System.out.println("s1="+s1);
}
private static void printBytes(byte[] buf) {
for(byte b : buf){
System.out.print(b +" ");
}
}
}
12、截取字符串
public class Test {
public static void main(String[] args) throws IOException {
String str = "ab你好cd谢谢";
int len = str.getBytes("utf-8").length;
for(int x=0; x<len; x++){
System.out.println("截取"+(x+1)+"个字节结果是:"+cutStringByU8Byte(str, x+1));
}
}
public static String cutStringByU8Byte(String str, int len) throws IOException {
byte[] buf = str.getBytes("utf-8");
int count = 0;
for(int x=len-1; x>=0; x--){
if(buf[x]<0)
count++;
else
break;
}
if(count%3==0)
return new String(buf,0,len,"utf-8");
else if(count%3==1)
return new String(buf,0,len-1,"utf-8");
else
return new String(buf,0,len-2,"utf-8");
}
public static String cutStringByByte(String str,int len) throws IOException{
byte[] buf = str.getBytes("gbk");
int count = 0;
for(int x=len-1; x>=0; x--){
if(buf[x]<0)
count++;
else
break;
}
if(count%2==0)
return new String(buf,0,len,"gbk");
else
return new String(buf,0,len-1,"gbk");
}
}
day25
1、GUI 图形用户接口
java为GUI提供的对象都存在java.awt和java.swing中
Awt Abstract Windows ToolKit,调用本地系统方法实现功能,属于重量级控件
swing 在Awt基础上用java实现,受系统影响小,属轻量级控件
2、CLI 命令行用户接口
3、Container:为容器,是一个特殊的组件,该组件可以通过add方法添加其他组件进来。
4、布局管理器
5、事件监听机制
事件源(组件,承载事件的载体) 事件(Event) 监听器(Listener) 事件处理(引发事件后处理方式)
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class FrameDemo {
public static void main(String[] args) {
Frame f = new Frame("my frame");
f.setBounds(400, 200, 500, 400);
f.setLayout(new FlowLayout());
Button but = new Button("一个按钮");
f.add(but);
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
but.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
f.setVisible(true);
System.out.println("over");
}
}
6、鼠标事件和键盘事件
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class MouseAndKeyDemo {
private Frame f;
private TextField tf;
private Button but;
public MouseAndKeyDemo() {
init();
}
private void init() {
f = new Frame("演示鼠标和键盘监听");
f.setBounds(400,200,500,400);
f.setLayout(new FlowLayout());
tf = new TextField(35);
but = new Button("一个按钮");
f.add(tf);
f.add(but);
myEvent();
f.setVisible(true);
}
private void myEvent() {
tf.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
System.out.println("KeyEvent.getKeyText(e.getKeyCode())+":"+e.getKeyCode());
int code = e.getKeyCode();
if(!(code>=KeyEvent.VK_0 && code<=KeyEvent.VK_9)){
System.out.println("必须是数字");
e.consume();
}
if(e.isControlDown() && e.getKeyCode()==KeyEvent.VK_ENTER){
System.out.println("enter run ...");
}
}
});
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
but.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("action run.....");
}
});
but.addMouseListener(new MouseAdapter() {
private int count = 1;
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
if(e.getClickCount()==2)
tf.setText("mouse double click..."+count++);
}
});
}
public static void main(String[] args) {
new MouseAndKeyDemo();
}
}
7、Swing与装插件
day26
1、网络模型:
osi tcp/ip
2、网络通信要素 IP 端口号 通信协议
3、物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
4、UDP 将数据及源和目的封装成数据包,不需要建立连接,每个数据包限制在64K,不可靠但速度快
5、TCP 建立连接,形成数据传输的通道,进行大数据量传输,三次握手建立连接,可靠,效率低
6、java网络相关java.net包
7、InetAddress类 Inet4Address Inet6Address
import java.net.InetAddress;
import java.net.UnknownHostException;
public class IPDemo {
public class IPDemo {
public static void main(String[] args) throws UnknownHostException{
InetAddress ip = InetAddress.getLocalHost();
System.out.print(ip.getHostAddress()+" ");
System.out.print(ip.getHostName()+" ");
ip = InetAddress.getByName("192.168.1.102");
System.out.print(ip.getHostAddress()+" ");
System.out.print(ip.getHostName());
}
}
8、有的主机对应多个IP地址
static InetAddress[] getAllByName(String host)
在给定主机名的情况下,根据系统上配置的名称服务返回其IP地址所组成的数组。
9、域名解析 无IP无访问
先查找system32目录下的hosts文件,再查找DNS服务器。
10、Socket就是为网络服务提供的一种机制,数据在两个Socket之间通过IO传输。
11、DatagramSocket 用来发送和接收数据包的套接字。
12、UDP发送、接收
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class UDPSendDemo {
public static void main(String[] args) throws IOException {
System.out.println("发送端启动......");
DatagramSocket ds = new DatagramSocket(8888);
String str = "udp传输演示:哥们来了!";
byte[] buf = str.getBytes();
DatagramPacket dp =
new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000);
ds.send(dp);
ds.close();
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPReceDemo {
public static void main(String[] args) throws IOException {
System.out.println("接收端启动......");
DatagramSocket ds = new DatagramSocket(10000);
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(),0,dp.getLength());
System.out.println(ip+":"+port+":"+text);
ds.close();
}
}
13、TCP Socket客户端套接字 ServerSocket服务器套接字
14、TCP发送、接收
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10002);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(ip+":"+text);
s.close();
ss.close();
}
}
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientDemo {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("192.168.1.100",10002);
OutputStream out = socket.getOutputStream();
out.write("tcp演示:哥们又来了!".getBytes());
socket.close();
}
}
15、常见问题 缺少结束标记、阻塞式方法 shutdownOutput();
day27
1、服务端多线程
2、常用客户端(IE浏览器)和服务端(Tomcat)
3、客户端和服务端原理
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class MyBrowser {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket("192.168.1.100",8080);
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
out.println("GET /myweb/1.html HTTP/1.1");
out.println("Accept: */*");
out.println("Host: 192.168.1.100:8080");
out.println("Connection: close");
out.println();
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String str =new String(buf,0,len);
System.out.println(str);
s.close();
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class MyTomcat {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(9090);
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress()+".....connected");
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(text);
//给客户端一个反馈信息。
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
out.println("<font color='red' size='7'>欢迎光临</font>");
s.close();
ss.close();
}
}
3、URL统一资源定位符 URI统一资源标识符
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class URLDemo {
public static void main(String[] args) throws IOException {
String str_url = "http://192.168.1.100:8080/myweb/1.html";
URL url = new URL(str_url);
//System.out.println("getProtocol:"+url.getProtocol());
//System.out.println("getHost:"+url.getHost());
//System.out.println("getPort:"+url.getPort());
//System.out.println("getFile:"+url.getFile());
//System.out.println("getPath:"+url.getPath());
//System.out.println("getQuery:"+url.getQuery());
//InputStream in = url.openStream();(url.openConnection()和conn.getInputStream()组合)
//获取url对象的Url连接器对象。
//将连接封装成了对象:java中内置的可以解析的具体协议的对象+socket.
URLConnection conn = url.openConnection();
//String value = conn.getHeaderField("Content-Type");
//System.out.println(value);
//output:text/htmml
//System.out.println(conn);
//output:sun.net.www.protocol.http.HttpURLConnection:http://192.168.1.100:8080/myweb/1.html
InputStream in = conn.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(text);
in.close();
}
}
day28
1、正则表达式:正则表达式用于操作字符串数据
正则表达式用于操作字符串数据,通过一些特定符号来体现。
2、匹配
使用String类中的matches方法
长度5~15. 只能是数字, 0不能开头 String regex = "[1-9][0-9]{4,14}";//正则表达式。
public static void functionDemo_1(){
//匹配手机号码是否正确。
String tel = "15800001111";
String regex = "1[358]\\d{9}";
String regex = "1[358][0-9]{9}";
boolean b = tel.matches(regex);
System.out.println(tel+":"+b);
}
3、切割
使用String类中的split方法
组:((A)(B(C)))
public static void functionDemo_2(){
String str = "zhangsanttttxiaoqiangmmmmmmzhaoliu";
String[] names = str.split("(.)\\1+");//str.split("\\.");
for(String name : names){
System.out.println(name);
}
}
4、替换
使用String类中的replaceAll方法
public static void functionDemo_3() {
String str = "zhangsanttttxiaoqiangmmmmmmzhaoliu";
str = str.replaceAll("(.)\\1+", "$1");
System.out.println(str);
String tel = "15800001111";//158****1111;
tel = tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
System.out.println(tel);
}
5、获取
public static void functionDemo_4() {
String str = "da jia hao,ming tian bu fang jia!";
String regex = "\\b[a-z]{3}\\b";
//1,将正则封装成对象。
Pattern p = Pattern.compile(regex);
//2, 通过正则对象获取匹配器对象。
Matcher m = p.matcher(str);
//使用Matcher对象的方法对字符串进行操作。
//既然要获取三个字母组成的单词
//查找。 find();
System.out.println(str);
while(m.find()){
System.out.println(m.group());//获取匹配的子序列
System.out.println(m.start()+":"+m.end());
}
}
6、反射
JAVA反射机制是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方
法的功能称为java语言的反射机制。
动态获取类中信息,就是java反射 。可以理解为对类的解剖。
要想要对字节码文件进行解剖,必须要有字节码文件对象。
7、Tomcat提供了处理请求和应答的方式,因为具体的处理动作不同,所以对外提供了接口,
由开发者来具体实现请求和应答处理。
interface Servlet,例如下
web.xml
<servlet>
<servlet-name>RegServlet</servlet-name>
<servlet-class>cn.itcast.servlet.RegServlet</servlet-class>
</servlet>
AllUserServlet.xml
public class AllUserServlet extends HttpServlet{}
8、获取字节码对象的三种方式
a、Object类中的getClass()方法 必须明确具体的类和创建对象
b、类名.class 任何数据类型都具备一个静态的属性,class来获取其对应的class对象
c、class.forname(包名.类名) 只需知道类的字符串名称,更为扩展
9、new和forname创建对象
public static void createNewObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
//早期:new时候,先根据被new的类的名称找寻该类的字节码文件,并加载进内存,
//并创建该字节码文件对象,并接着创建该字节文件的对应的Person对象.
cn.itcast.bean.Person p = new cn.itcast.bean.Person();
//现在:
String name = "cn.itcast.bean.Person";
//找寻该名称类文件,并加载进内存,并产生Class对象。
Class clazz = Class.forName(name);
//如何产生该类的对象呢?
Object obj = clazz.newInstance();
}
public static void createNewObject_2() throws Exception {
cn.itcast.bean.Person p = new cn.itcast.bean.Person("小强",39);
String name = "cn.itcast.bean.Person";
Class clazz = Class.forName(name);
Constructor constructor = clazz.getConstructor(String.class,int.class);
Object obj = constructor.newInstance("小明",38);
}
10、获取Class中的字段
public static void getFieldDemo() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
Field field = null;
field = clazz.getDeclaredField("age");
field.setAccessible(true);
Object obj = clazz.newInstance();
field.set(obj, 89);
Object o = field.get(obj);
System.out.println(o);
}
11、获取Class中的方法并运行
public static void getMethodDemo_3() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
Method method = clazz.getMethod("paramMethod", String.class,int.class);
Object obj = clazz.newInstance();
method.invoke(obj, "小强",89);
}
public static void getMethodDemo_2() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
Method method = clazz.getMethod("show", null);
Constructor constructor = clazz.getConstructor(String.class,int.class);
Object obj = constructor.newInstance("小明",37);
method.invoke(obj, null);
}
public static void getMethodDemo() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
Method[] methods = clazz.getMethods();
methods = clazz.getDeclaredMethods();
for(Method method : methods){
System.out.println(method);
}
}
day29
HTML
1、标签的操作思想
为了操作数据,都需要对数据进行不同标签的封装,通过标签中的属性对封装的数据进行操作。
标签就相当于一个容器。对容器中的数据进行操作,就是在不断改变容器的属性值。
2、列表标签
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>
</head>
<body>
<!--HTML注释:演示列表标签。
列表标签:dl
上层项目:dt
下层项目:dd : 封装的内容是会被缩进的。 有自动缩进效果。
-->
<dl>
<dt>上层项目内容</dt>
<dd>下层项目内容</dd>
<dd>下层项目内容</dd>
<dd>下层项目内容</dd>
</dl>
<hr/>
<!--有序和无序的项目列表
有序:<ol>
无序:<ul>
无论有序和无序,条目的封装用的都是<li>,而且它们都有缩进效果。
-->
<ul type="square">
<li>无序项目列表</li>
<li>无序项目列表</li>
<li>无序项目列表</li>
<li>无序项目列表</li>
</ul>
<ol type="a">
<li>有序的项目列表</li>
<li>有序的项目列表</li>
<li>有序的项目列表</li>
<li>有序的项目列表</li>
</ol>
</body>
</html>
3、图像标签
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>
</head>
<body>
<!--演示图片标签 img.-->
<img src="imgs\1.jpg" height=350 width=500 border=10 alt="显示图片提示!" />
</body>
</html>
4、表格标签
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>
</head>
<body>
<table border=1 bordercolor="#0000EE" cellpadding=10 cellspacing=0 width=500>
<tbody><!--表格的下一级标签是tbody,不定义也存在-->
<tr>
<th rowspan=2>个人信息</th>
<td>张三</td>
</tr>
<tr>
<td>30</td>
</tr>
</tbody>
</table>
<hr/>
<table border=1 bordercolor="#0000EE" cellpadding=10 cellspacing=0 width=500>
<tr>
<th colspan=2>个人信息</th>
</tr>
<tr>
<td>张三</td>
<td>30</td>
</tr>
</table>
<hr/>
<table border=1 bordercolor="#0000EE" cellpadding=10 cellspacing=0 width=500>
<caption>表格标题</caption>
<tr>
<th>姓名:</th>
<th>年龄:</th>
</tr>
<tr>
<td>张三</td>
<td>39</td>
</tr>
</table>
</body>
</html>
5、超链接
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>
</head>
<body>
<!--超链接作用:连接资源。
当有了href属性才有了点击效果。href属性的值的不同,解析的方式也不一样。
如果在该值中没有指定过任何协议。解析时,是按照默认的协议来解析该值的。默认协议是file协议。
-->
<a href="http://www.sohu.com.cn" target="_blank">新浪网站</a>
<hr/>
<a href="imgs/1.jpg">图片</a>
<hr/>
<a href="mailto:abs@sina.com">联系我们</a>
<hr/>
<a href="http://www.xunlei.com/movies/fczlm.rmvb">复仇者联盟</a><br/>
<a href="thunder://wertyuioasdfghjklwertyuio==">复仇者联盟</a>
<a href="javascript:void(0)" onclick="alert('我弹')">这是一个超链接</a>
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>
</head>
<body>
<!--
定位标记。专业术语:锚-->
<a name=top>顶部位置</a>
<hr/>
<img src="111.jpg" height=900 width=400 border=10/>
<hr/>
<a name=center>中间位置</a>
<hr/>
<img src="111.jpg" height=900 width=400 border=10/>
<a href="#top">回到顶部位置</a>
<a href="#center">回到中间位置</a>
</body>
</html>
6、框架
Framedemo.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>
</head>
<!--定义框架。使用标签frameset-->
<frameset rows="30%,*">
<frame src="top.html" name="top" />
<frameset cols="30%,*">
<frame src="left.html" name="left" />
<frame src="right.html" name="right"/>
</frameset>
</frameset>
<body>
</body>
</html>
Left.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>
</head>
<body>
<H3>左边栏连接</H3>
<a href="../img.html" target="right">链接一</a>
<a href="../table.html" target="right">链接一</a>
<a href="../link.html" target="right">链接一</a>
</body>
</html>
Right.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>
</head>
<body>
<h2> 内容显示区域</h2>
</body>
</html>
Top.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>
</head>
<body>
<h1>这是我的网站LOGO</h1>
</body>
</html>
7、画中画标签
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>
</head>
<body>
<iframe src="http://www.xxx.com/1.js" height=0 width=0>这是画中画标签,您如果看到该文字,很遗憾,您的浏览器不支持该标签</iframe>
</body>
</html>
8、表单组件
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>
</head>
<body>
<!--
如果要给服务端提交数据,表单中的组件必须有name和value属性。
用于给服务端获取数据方便。
-->
<form>
输入名称:<input type="text" name="user" value="" /><br/>
输入密码:<input type="password" name="psw" /><br/>
选择性别:<input type="radio" name="sex" value="nan" />男
<input type="radio" name="sex" value="nv" checked="checked" />女<br/>
选择技术:<input type="checkbox" name="tech" value="java"/>JAVA
<input type="checkbox" name="tech" value="html"/>HTML
<input type="checkbox" name="tech" value="css"/>CSS<BR/>
选择文件:<input type="file" name="file"/><br/>
一个图片:<input type="image" src="11.jpg"/><br/>
<!--数据不需要客户端知道,但是可以将其提交服务端。-->
隐藏组件:<input type="hidden" name="myke" value="myvalue"/><br/>
一个按钮:<input type="button" value="有个按钮" onclick="alert('有个阿牛')" /><br/>
<select name="country">
<option value="none">--选择国家--</option>
<option value="usa">美国</option>
<option value="en">英国</option>
<option value="cn" selected="selected">中国</option>
</select>
<textarea name="text"></textarea>
<br/>
<input type="reset" value="清除数据"/><input type="submit" value="提交数据" />
</form>
</body>
</html>
9、表单格式化
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<!--meta http-equiv="refresh" content="3;url=http://www.sina.com.cn" /-->
<title>Untitled Document</title>
</head>
<body>
<form action="http://10.1.31.69:9090" method="post">
<table border="1" bordercolor="#0000ff" cellpadding=10 cellspacing=0 width=600>
<tr>
<th colspan="2">注册表单</th>
</tr>
<tr>
<td>用户名称:</td>
<td><input type="text" name="user" /></td>
</tr>
<tr>
<td>输入密码:</td>
<td><input type="password" name="psw" /></td>
</tr>
<tr>
<td>确认密码:</td>
<td><input type="password" name="repsw" /></td>
</tr>
<tr>
<td>选择性别:</td>
<td>
<input type="radio" name="sex" value="nan" />男
<input type="radio" name="sex" value="nv" />女
</td>
</tr>
<tr>
<td>选择技术:</td>
<td>
<input type="checkbox" name="tech" value="java" />JAVA
<input type="checkbox" name="tech" value="html" />HTML
<input type="checkbox" name="tech" value="css" />CSS
</td>
</tr>
<tr>
<td>选择国家:</td>
<td>
<select name="country">
<option value="none">--选择国家--</option>
<option value="usa">--美国--</option>
<option value="en">--英国--</option>
<option value="cn">--中国--</option>
</select>
</td>
</tr>
<tr>
<th colspan="2">
<input type="reset" value="清除数据" />
<input type="submit" value="提交数据" />
</th>
</tr>
</table>
</form>
</body>
</html>
10、Get和Post的区别
提交方式:get提交。
地址栏:http://10.1.31.69:9090/?user=abc&psw=123&repsw=123&sex=nan&tech=java&tech=html&country=cn
GET /?user=abc&psw=123&repsw=123&sex=nan&tech=java&tech=html&country=cn HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, **
Accept-Language: zh-cn,zu;q=0.5
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2)
Host: 10.1.31.69:9090
Content-Length: 68
Connection: Keep-Alive
Cache-Control: no-cache
user=hahah&psw=8989&repsw=8989&sex=nv&tech=html&tech=css&country=usa
a、get提交,提交的信息都显示在地址栏中。post提交,提交的信息不显示地址栏中。
b、get提交,对于敏感的数据信息不安全。 post提交,对于敏感信息安全。
c、get提交,对于大数据不行,因为地址栏存储体积有限。post提交,可以提交大体积数据。
d、get提交,将信息封装到了请求消息的请求行中。post提交,将信息封装到了请求体中。
11、Get和Post在服务端的区别
如果出现将中文提交到tomcat服务器,服务器默认会用iso8859-1进行解码会出现乱码,
通过iso8859-1进行编码,再用指定的中文码表解码。即可。这种方式对get提交和post提交都有效。
但是对于post提交方式提交的中文,还有另一种解决办法,就是直接使用服务端一个对象
request对象的setCharacterEncoding方法直接设置指定的中文码表就可以将中文数据解析出来。
这个方法只对请求体中的数据进行解码。 综上所述:表单提交,建议使用post
12、和服务端交互的三种方式:地址栏输入url地址get、超链接get、表单get和post
13、校验
如果在客户端进行增强型的校验(只要有一个组件内容是错误,是无法继续提交的。只有全对才可以提交)
问,服务端接收到数据后,还需要校验吗?需要,为了安全性。
如果服务端做了增强型的校验,客户端还需要校验,提高用户的上网体验效果,减轻服务器端的压力。
14、其他标签
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>
</head>
<body>
<pre>
class Demo
{
public static void main(String[] args)
{
System.out.println("hello");
}
}
</pre>
<hr/>
<marquee direction="down" behavior="slide">嘿,原来我会飞!</marquee>
<b>这是</b><i>演示</i><u>其他</u>常见的小标签。
X<sub>2</sub> X<sup>2</sup>
</body>
</html>
15、标签分为两大类。
a、块级标签(元素):标签结束后都有换行。div p dl table title ol ul
b、行内标签(元素):标签结束后没有换行。 font span img input select a
day30
1、CSS 层叠样式表,定义网页的现实效果,将页面内容和显示样式进行分离,提高了显示功能。
2、CSS和HTML在网页代码中如何相结合?
通过四种方式
a、style属性方式
<div style="background-color:#09F; color:#FFF">这是一个div区域</div>
b、style标签的方式
<style type="text/css">
div{
background-color:#09F;
color:#FFF
}
</style>
c、导入文件
div.css
@charset "utf-8";
div{
background-color:#090;
color:#FFF
}
div.html
div{
@import url(1.css);
}
</style>
d、使用html的link标签
<link rel="stylesheet" href="1.css" type="text/css" />
3、样式优先级
由上到下,由外到内,优先级由低到高
4、CSS代码格式
选择器名称 {属性名:属性值;属性名:属性值;......}
属性与属性之间用分号隔开,属性与属性值直接用冒号连接,
如果一个属性有多个值,多个值用空格隔开
5、选择器
就是指定CSS要作用的标签,标签的名称就是选择器,意为选择那个容器
选择器共有三种:
html标签选择器:html的标签名。
class选择器:使用标签中的class属性。
id选择器:使用的就是标签中的id属性。
每个标签都定义了class属性和id属性,方便对标签进行操作。
在定义标签值,多个标签的class属性可以相同,但id值要唯一,因为js中经常用。
6、类选择器 优先级高于标签,低于id选择器
div.class名{
background-color:#090;
color:#FFF
}
.class名{
background-color:#090;
color:#FFF
}
7、id选择器
div#id值{
background-color:#090;
color:#FFF
}
#id值{
background-color:#090;
color:#FFF
}
8、关联选择器
span b{
background-color:#090;
color:#FFF
}
9、组合选择器
.class名, div b{
background-color:#090;
color:#FFF
}
10、伪元素选择器
超链接的状态
a:link{
background-color:#06F;
color:#FFF;
text-decoration:none;
font-size:18px;
}
a:hover{
background-color:#FFF;
color:#F00;
font-size:24px;
}
a:active{
background-color:#000;
color:#FFF;
font-size:36px;
}
a:visited{
background-color:#FF9;
color:#000;
text-decoration:line-through;
}
<a href="http://www.sina.com.cn" target="_blank">伪元素选择器演示</a>
11、其他
p:first-letter{
font-size:36px;
color:#F00;
}
div:hover{
background-color:#F00;
color:#FFF;
}
input:focus{
background-color:#09F;
}
<input type="text" />
12、无序列表和表单
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style type="text/css">
ul{
list-style-type:none;
list-style-image:url(1.bmp);
}
table{
border-bottom:#0C0 double 3px;
border-left:#F00 solid 3px;
border-right:#FF0 dashed 3px;
border-top:#0C0 groove 3px;
width:500px;
}
table td{
border:#0CF dotted 1px;
padding:20px;
}
div{
border:#F90 dashed 2px;
height:200px;
width:400px;
}
input {
border:none;
border-bottom:#000 1px solid;
}
.haha{
border:none;
}
</style>
</head>
<body>
姓名:<input type="text" />成绩:<input type="text" />
<hr />
<div>div区域</div>
<hr />
<table>
<tr>
<td><input type="text" class="haha" /></td>
<td><input type="text" class="haha" /></td>
</tr>
<tr>
<td>单元格一</td>
<td>单元格一</td>
</tr>
</table>
<hr />
<ul>
<li>无序项目列表</li>
<li>无序项目列表</li>
<li>无序项目列表</li>
<li>无序项目列表</li>
</ul>
</body>
</html>
13、CSS的盒子模型 边框
14、CSS布局 漂浮 定位 图文混合 图像签名