目录
java初级部分
注释:
单行注释://
多行注释:/**/ <!---->
文档注释:/** */
命名规范:
变量分类:
逻辑运算符:
关于&和&&的区别:
相同:&和&&的运算结果相同;当符号左边是true时,二者会执行符号右边的运算
不同:当符号左边是false,&会继续执行符号右边的运算,&&不再执行符号右边的运算。
关于|与||的区别:
相同:&和&&的运算结果相同;当符号左边是false时,二者会执行符号右边的运算
不同:当符号左边是true,|会继续执行符号右边的运算,||不在执行符号右边的运算。
位运算符:
数组概述:
初始化数组(一维数组):
堆栈:
栈中存放的是局部变量,堆中存放对象或数组。(int[] array=new int[]{1,2,3})
二维数组:
数组工具类:Arrays(现成的关于操作数组的方法)
生成随机数:使用 Math中的random()方法
代码格式:(数据类型)(最小值+Math.random()*(最大值-最小值+1))例:生成1-100的随机数
(int)(1+Math.random()*(100-1+1))
匿名对象:我们创建的对象没有显示赋给一个变量。(特征:匿名对象只能调用一次)
new person().name=XXX;
new person().age=XXX;
方法的重载
定义:同一个类中相同方法名中参数的个数或类型不同。
封装:
构造方法(构造器)
eclipse快捷键:
重写
子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作
多态
父类的引用指向子类发对象(Person p1=new Man();)
当调用父类同名同参数方法时,实际执行的是子类重写父类的方法。
instanceof关键字:
单元测试:
包装类:
自动装箱->基本数据类型转化为包装类
int num=10;
Interger n1=num;
自动拆箱->包装类转化为基本数据类型
Integer i1=11;
int m=i1;
基本数据类型、包装类转化为String类型:
1.连接运算
int num=10;
String n1=num1+"";
2.调用String的valueOf()
float f1=11.2;
String s1=String.valueOf(f1);
String类型转化为基本数据类型、包装类:调用包装类的parseXxx(String s)
String s1="123";
int num1=Integer.parseInt(s1);
static关键字:
单例模式:
/*
*单例模式 -饿汉式
*
*/
public class singletonTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Car c1=Car.getInstance();
Car c2=Car.getInstance();
System.out.println(c1==c2);
}
}
class Car{
private Car() {
}
private static Car instance=new Car();
public static Car getInstance() {
return instance;
}
}
/*
*懒汉式
*
*/
public class Bank {
}
class Bank {
private Bank() {
}
private static Bank instance = nu1l;
public static Bank getInstance() {
if (instance == nu11) {
synchronized (Bank.class) {
if (instance == null) {
instance = new Bank();
}
}
}
return instance;
}
}
代码块:
属性赋值的先后顺序:
final关键字
final可以用来修饰的结构:类、方法、变量。
final修饰类-此类不能被其他类所继承。
final修饰方法-此方法不能被重写。
final修饰变量-此时的“变量”就称为一个常量。
abstract关键字:
接口
接口与接口之间可以继承,而且可以多继承。
1.接口中定义的静态方法只能通过接口来调用。
2.通过实现类的对象可以调用接口的默认方法。
3.如果子类(实现类)继承的父类和实现的接口中声明了同名同参的默认方法,那么子类在没有重写此方法的情况下,默认调用的是父类中同名同参的方法。
4.如果实现类实现了多个接口,而这多个接口定义了同名同参的默认方法,那么实现类在没有重写此方法的情况下,会报错。
5.如何在子类(或实现类)的方法中调用接口中的默认方法
接口名.super.方法名
内部类
异常处理
java高级部分
多线程的创建
方式一:继承于Thread类
1. 创建一个继承于Thread类的子类
2. 重写Thread类的run() --> 将此线程执行的操作声明在run()中
3. 创建Thread类的子类的对象
4.通过此对象调用start()-->start()作用:1.启动当前线程 2.调用当前线程的run()PS:再启动一个线程,我们可以通过重新创建一个线程的对象实现。
创建多线程的方式二:实现Runnable接口
1.创建一个实现了Runnable接口的类
2.实现类去实现Runnable中的抽象方法: run()
3.创建实现类的对象
4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
5.通过Thread类的对象调用start()比较创建线程的两种方式。
开发中:优先选择:实现Runnable 接口的方式
原因: 1.实现的方式没有类的单继承性的局限性
2.实现的方式更适合来处理多个线程有共享数据的情况。
联系: public class Thread implements Runnable .
相同点:两种方式都需要重写run(),将线程要执行的逻辑声明在run()中。.
线程的生命周期
java中线程安全问题的解决方法
方式一:同步代码块
synchronized(同步监视器){
// 需要被同步的代码
}
说明:1.操作共享数据的代码,即为需要被同步的代码
2.共享数据:多个线程共同操作的变量。比如: ticket就是共享数据。
3.同步监视器,俗称:锁。任何一个类的对象,都可以充当锁。
要求:多个线程必须要共用同一把锁。补充:在实现Runnable接口创建多线程的方式中,我们可以考虑使用this充当同步监视器。
在继承Thread类创建多线程的方式中,慎用this充当同步监视器,考虑使用当前类充当同步监视器。方式二:同步方法
1.同步方法仍然涉及到同步监视器, 只是不需要我们显式的声明。
2.非静态的同步方法,同步监视器是: this
静态的同步方法,同步监视器是:当前类本身方式三:Lock锁
1.实例化ReentrantLock
2.调用Lock()
3.调用解锁方法: unLock( )
同步的方式,解决了线程的安全问题。---好处
操作同步代码时,只能有一个线程参与, 其他线程等待。相当于是一一个 单线程的过程,效率低。
//例如:模拟三个窗台发放100张车票
//方式一同步代码块
class window implements Runnable{
private int tickit=100;
Object o=new Object();
@Override
public void run() {
//synchronized(this) 方式一:不new对象,但得保证当前类的对象只有一个-唯一性
synchronized(o) {//方式二
while (true) {
if (tickit > 0) {
System.out.println(Thread.currentThread().getName() + "票号为:" + tickit);
tickit--;
} else {
break;
}
}
}
}
}
public class WindowTest1 {
public static void main(String[] args) {
window w1=new window();
Thread t1=new Thread(w1);
Thread t2=new Thread(w1);
Thread t3=new Thread(w1);
t1.start();
t2.start();
t3.start();
}
}
//方式二同步方法
public class WindowTest2 {
public static void main(String[] args) {
WindowTest w1=new WindowTest();
WindowTest w2=new WindowTest();
WindowTest w3=new WindowTest();
w1.start();
w2.start();
w3.start();
}
}
class window2 extends Thread {
private static int tickit = 100;
@Override
public void run() {
while (true) {
show();
}
}
private static synchronized void show() {
if (tickit > 0) {
System.out.println(Thread.currentThread().getName() + "票号为:" + tickit);
tickit--;
}
}
}
//方式三Lock锁
public class WindowTest3 implements Runnable {
private static int tickit=100;
private ReentrantLock lock=new ReentrantLock();
@Override
public void run() {
while(true){
try{
lock.lock();
if(tickit>0){
System.out.println(Thread.currentThread().getName()+"票号为:"+tickit);
tickit--;
}
else {
break;
}
}finally {
lock.unlock();
}
}
}
}
class Test{
public static void main(String[] args) {
WindowTest3 w=new WindowTest3();
Thread t1=new Thread(w);
Thread t2=new Thread(w);
Thread t3=new Thread(w);
t1.start();
t2.start();
t3.start();
}
}
线程通信的例子:使用两个线程打印1-100。线程1,线程2交替打印 |
线程通信涉及到的三个方法: .
wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。
notify():一旦执行此方法,就会唤醒被wait的一个线程。 如果有多个线程被wait,就唤醒优先级高的
notifyAll():一旦执行此方法,就会唤醒所有被wait的线程。说明: .
1.wait(), notify(), notifyALl()三个方法必须使用在同步代码块或同步方法中。
2. wait(), notify(), notifyAll()三个方法的调用者必须是同步代码块或同步方法中的同步监视器
否则,会出现IllegalMonitorStateException异 常
3. wait(), notify(), notifyALl()三个方法是定义在java. lang. object类中。
创建多线程的方式三:实现Callable接口
与使用Runnable相比,Callable功能 更强大些
➢相比run()方法,可以有返回值
➢方法可以抛出异常
➢支持泛型的返回值
➢需要借助FutureTask类,比如获取返回结果1.创建一个实现Callable的实现类
2.实现call方法,将此线程需要执行的操作声明在call()中
3. 创建Callable接口实现类的对象
4.将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对像
5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象, 并调用start()6.获取Callable中call方法的返回值(有则写无则不用)
创建多线程的方式四:使用线程池
NumberThread()为实现了Runnable接口的一个线程
字符串类String
String的实例化方式
1.String s1="XXX";此方式的数据声明在方法区中的字符串常量池中
2.String s2=new String("XXX");此方式s2保存的地址值,是数据在堆空间中开辟地址以后对应的地址值。
String常用方法:
String与char[]之间的转换
String --> char[]: 调用String的toCharArray()
char[]-->String: 调用String的构造器String与byte[]之间的转换
编码: String --> byte[]: 调用String的getBytes()
解码: byte[]--> String: 调用String的构造器
说明:解码时,要求解码使用的字符集必须与编码时使用的字符集一 致,否则会出现乱码:
对比String、StringBuffer、 StringBuilder. 三者的效率:
从高到低排列: StringBuilder > StringBuffer > String
StringBuffer类和StringBuilder类
关于处理时间的类
如何实现对象大小的比较 (java比较器)
枚举类的使用:
1.枚举类的理解:类的对象只有有限个,确定的。我们称此类为枚举类
2.当需要定义一组常量时,强烈建议使用枚举类
3.如果枚举类中只有一个对象,则可以作为单例模式的实现方式。
java集合框架
集合元素的遍历操作,使用迭代器Iterator接口
1.内部的方法: hasNext()和next()
2.集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。例:Iterator i1=list.iterator();
while(i1.hasNext()){
System.out.println(i1.next());}
foreach循环(用于遍历集合、数组)
for循环的高级用法
for(集合元素的类型 局部变量:数组对象)-------内部仍然调用了迭代器
Map接口
HashMap底层原理
Collections工具类常用方法
泛型
所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类
型或者是某个方法的返回值及参数类型。这个类型参数将在使用时(例如,
继承或实现这个接口,用这个类型声明变量、创建对象时)确定(即传入实
际的类型参数,也称为类型实参)。
从JDK1.5以后,Java引入了“参数化类型( Parameterized type)”的概念,
允许我们在创建集合时再指定集合元素的类型,正如:List<String>,这表明
该List只能保存字符串类型的对象。
JDK1.5改写了集合框架中的全部接口和类,为这些接口、类增加了泛型支持,
从而可以在声明集合变量、创建集合对象时传入类型实参。
IO流
1.对于文本文件(. txt, . java,.c,.cpp),使用字符流处理
2.对于非文本文件(. jpg, . mp3, .mp4,. avi,.doc, .ppt,...),使用字节流处理
反射
StreamAPI