【035】内部类和匿名内部类
如:
class A{
class B{
//B就是A的内部类
}
}
编译过后,会生成什么呢~
A.class
A$B.class
tips:内部类生成后会生成外部$内部.class的编译文件
如何生成一个内部类对象呢~
如:
B b = new A().new B();
内部类可以任意使用外部类的成员变量。
A.java
class A{
int i;
class B{
//B就是A的内部类
int j;
int funB(){
int result = i+j;
return result;
}
}
}
test.java
class test{
public static void main(String args []){
//如何创建对象
A a = new A();
A.B b = new A().new B();
A.B bb = a.new B();
a.i = 3;
b.j = 1;
System.out.println(b.funB());
bb.j = 2;
System.out.println(bb.funB());
}
}
输出为
1
5
匿名内部类,最常用的
①非匿名内部类示例
A.java
interface A{
public void doSomething();
}
B.java
class B{
public void fun(A a){
System.out.println("B类的函数");
a.doSomething();
}
}
AImpl.java
class AImpl implements A{
public void doSomething(){
System.out.println("DO SOMETHING");
}
}
test.java
class test{
public static void main(String args []){
//生成一个接口实现类对象
AImpl al = new AImpl();
A a = al;
B b = new B();
b.fun(a);
}
}
结果
![](https://img-my.csdn.net/uploads/201211/04/1351994859_4851.jpg)
Tips:还记得接口和接口的实现类么~接口只有没有函数体的方法,需要创建对应接口的对象,必须要有一个接口实现类来重写这个方法
②匿名内部类
test.java
class test{
public static void main(String args []){
B b = new B();
//直接生成一个A接口的对象,并且复写doSomething()方法
b.fun(new A(){
public void doSomething(){
System.out.println("这是一个匿名内部类");
}
});
}
}
结果
![](https://img-my.csdn.net/uploads/201211/04/1351994904_6807.jpg)
【036】java中的线程
android是一个多进程的系统
一个进程下存在多个线程
![](https://img-my.csdn.net/uploads/201211/04/1351994930_9560.png)
创建线程的方法:
方法1:
定义一个线程类,继承类Thread并重写其中的方法run(),方法run()称为线程体。
例如:
firstThread.java
class firstThread extends Thread{
public void run(){
//复写Thread里的run方法
for(int i = 0;i<20;i++){
System.out.println("fisrtThread:"+i);
}
}
}
test.java
class test{
public static void main(String args []){
//生成线程类的对象
firstThread ft = new firstThread();
//启动firstThread线程,而不是这样写ft.run();
ft.start();
for(int i = 0;i<20;i++){
System.out.println("main:"+i);
}
}
}
Tips:
主函数代码里有三个线程
一个main函数开始线程
一个firstThread对象的start函数开始线程
一个是垃圾回收对象
注意Thread启动和运行的写法
结果
![](https://img-my.csdn.net/uploads/201211/04/1351994989_5040.png)
学过线程的相关知识的理解起来应该很容易= =电脑跑太快数值比较小的话,看的不明显
【037】线程·二
1、实现线程的第二种方法
有一个实现接口Runable的类作为线程的目标对象,在初始化一个Thread类或者Thread子类的线程对象时,把目标对象传递给这个线程实例,由该目标对象提供线程体
class RunnableImpl implements Runnable{
public void run(){
for(int i = 0;i<13;i++){
System.out.println("RunnableImpl:"+i);
}
}
}
class test{
public static void main(String args []){
//生成一个Runnable接口实现类的对象
RunnableImpl rl = new RunnableImpl();
//生成一个Thread对象,并将Runnable接口实现类对象作为参数传入
Thread t = new Thread(rl);
//start函数~
t.start();
}
}
结论:在实际开发过程中,先定义一个实现Runnable接口的类,再把这个实现类的对象作为参数传给Thread类的构造函数,并且生成Thread对象,再启动线程~
(上一课说的继承方法不常用,因为java是单继承,继承了Thread之后的类就不太好扩展了~)
2、线程的常用函数和控制方法
中断线程
①Thread.sleep() //休眠,时间ms作为参数,注意会抛出异常
class RunnableImpl implements Runnable{
public void run(){
for(int i = 0;i<13;i++){
System.out.println("RunnableImpl:"+i);
if(i==10){
try{
Thread.sleep(2000); //2000休眠
}
catch(Exception e){
System.out.println(e);
}
}
}
}
}
②Thread.yield() //当前线程让出cpu,但是不是说永久让出,只是让出,之后马上进入抢占cpu状态
③设置线程的优先级
getPriority()
setPriority()
class test{
public static void main(String args []){
//生成一个Runnable接口实现类的对象
RunnableImpl rl = new RunnableImpl();
//生成一个Thread对象,并将Runnable接口实现类对象作为参数传入
Thread t = new Thread(rl);
//打印优先级,输出结果为5
System.out.println(t.getPriority());
//设置为最大优先级
t.setPriority(Thread.MAX_PRIORITY);
//并打印,结果为10
System.out.println(t.getPriority());
//设置为最小优先级
t.setPriority(Thread.MIN_PRIORITY);
//并打印,结果为1
System.out.println(t.getPriority());
//start函数~
t.start();
}
}
结论:线程优先级分为1~10,优先级越高,取得cpu的概率越高。
【038】继续线程~~~
1、多线程数据安全
如以下代码:
class MyThread implements Thread{
int i = 100;
public void run(){
while(true){
//Thread.currentThread()方法是Thread类中的静态方法,可以取得当前执行的线程对象
System.out.println(Thread.currentThread().getName()+i);
i--;
//Thread.yield()方法是Thread类中的静态方法,使得当前线程让出cpu
Thread.yield();
if(i<0){
break;
}
}
}
}
class test{
public static void main(String args []){
//生成线程体对象
MyThread mt = new MyThread();
//生成两个Thread对象
//但是这两个Thread对象公用一个线程体
Thread t1 = new Thread(mt);
Thread t2 = new Thread(mt);
//每一个线程都有名字,可以通过Thread对象的SetName()方法设置线程名字,也可以使用getName()来获取线程的名字
t1.setName("a");
t2.setName("b");
//启动两个线程
t1.start();
t2.start();
}
}
理想的输出应该是
a100
b99
a98
b97
这样的数据
但是会出现如
a100
b100
a99
b99
这样的错误代码
也就是出现了多线程的数据错误,a和b在某个时间段取得了相同的i~
为了让数据不出现这种错误,a读取i值时需要需要锁定权限,b不可以读取i值
更改如下,使用synchronied(this){}方法
class MyThread implements Thread{
int i = 100;
public void run(){
while(true){
//使得以下代码块成为同步代码块
Synchronized(this){
//Thread.currentThread()方法是Thread类中的静态方法,可以取得当前执行的线程对象
System.out.println(Thread.currentThread().getName()+i);
i--;
//Thread.yield()方法是Thread类中的静态方法,使得当前线程让出cpu
Thread.yield();
if(i<0){
break;
}
}
}
}
}
【039】据说视频压缩挂了,至今未出,什么教学内容依旧是个迷……
【040】数组定义
1、数组的静态声明法
int arr [] = {0,1,2,3,4,5};
2、数组的动态声明法
int arr [] = new int[10];
int类的默认值为0
boolean类型的默认值为false;
ASCII类的默认值为空~
3、二维数组
int arr [][] = {{0,1},{2,3},{4,5}}; //静态声明
int arr [][] = new int[3][2]; //动态声明
如arr[2][1]=5;
【041】类集框架
类集框架是一组类和接口,位于java.util包当中,主要用户存储和管理对象,主要分为三大类-集合、列表和映射
1、集合set
集合中的对象不按特定的方式排序,并且没有重复的
2、列表list
集合中对象按照索引位置排序,可以有重复的对象
3、映射map
集合中的每一个元素包含一个键对象和一个值对象,键不可以重复,值可以重复
类集框架的主要结构
![](https://img-my.csdn.net/uploads/201211/04/1351995207_4235.png)
一个ArrayList的例子
test.java
import java.util.List;
import java.util.ArrayList;
class test{
public static void main(String args []){
//声明一个String类型的对象列表
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.remove(1);
for(int i = 0;i<arrayList.size();i++){
String s = arrayList.get(i);
System.out.println(s);
}
}
}
![](https://img-my.csdn.net/uploads/201211/04/1351995241_7071.png)
【042】类集框架2
1、Collection和Iterator接口
2、Set和HashSet的使用方法
①Collection接口
boolean add(Object o) 向集合中加入一个对象
void clear() 删除集合中的所有对象
boolean isEmpty() 判断集合是否为空
remove(Object o) 从集合中删除一个对象的引用
int size() 返回集合中元素的数目
②Set是Collection接口的子接口,HashSet是Set接口的实现类
③Collection接口是Iterator接口的子接口
hasNext() 游标后是否还有元素
next() 游标所指位置的下一个元素
也就是说
Iterator<---Collection<----Set<----HashSet;
前三个接口的方法被HashSet所实现。
*Iterator:译作迭代器模式,叫做游标模式。
一个例子:
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
class test{
public static void main(String args []){
HashSet<String> hashset = new HashSet<String>();
Set<String> set = hashset;
//或者这样Set<String> set =new HashSet<String>();
set.add("a");
set.add("b");
set.add("c");
set.add("d");
set.add("c");
int i = set.size();
//System.out.println(i);
//结果为4,重复元素会被忽略掉
set.remove("d");
//则d被移除
//set.clear();
//结果set被清空
//System.out.println(set.isEmpty());
//结果为true
//调用Set对象的Iterator方法,生成一个游标对象,用于遍历整个Set
Iterator<String> it = set.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
}
}
![](https://img-my.csdn.net/uploads/201211/04/1351995322_5876.png)
*这几集有编程基础的看起来还是很轻松地= =
这里出现了个泛型对象的概念,也许是我看漏了哪一集-- 0
具体可以看下这篇
Java泛型简明教程
比较杂,遇到再说吧
【043】类集框架3
Map和HashMap
呃,没什么好说的,键值对的数据
例子如下:
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
class test{
public static void main(String args []){
HashMap<String,String> hashmap = new HashMap<String,String>();
Map<String,String> map = hashmap;
map.put("1","a");
map.put("2","b");
map.put("3","c");
map.put("4","d");
//对应3键的值改成了e
map.put("3","e");
int i = map.size();
System.out.println(i);
//结果为4
map.get("2");
//取出了键2的值b
}
}
【044】java的equals函数
equals函数属于Object类,是java最基本的操作函数
1、对象的内容相等需要符合:
①对象的类型相同(使用instanceof操作符进行比较)
②两个对象的成员变量的值完全相同
如:
x.equals(y)
比较x和y是否完全相同
在Object.java中
public boolean equals(object obj){
return (this == obj);
}
如果直接使用equals,则就直接继承了这个函数体,需要根据实际情况进行复写
例如
User.java
class User{
String name;
int age;
public boolean equals(Object obj){
if(this == obj){
return true;
}
boolean b = obj instanceof User;//注意instanceof是一个操作符,而不是一个函数
if(b){
//将obj转型为User对象
User u = (User)obj;
//将obj和this的成员变量进行比较,基本数据类型的用== 引用数据类型的用equals()
if(this.age == u.age && this.name.equals(u.name)){
return true;
}
else{
return false;
}
}
else{
return false;
}
}
}
test.java
class test{
public static void main(String args []){
User u1 = new User();
User u2 = new User();
User u3 = new User();
u1.name = "zhangsan";
u1.age = 19;
u2.name = "lili";
u2.age = 19;
u3.name = "zhangsan";
u3.age = 19;
System.out.println(u1.equals(u2));
System.out.println(u1.equals(u3));
}
}
![](https://img-my.csdn.net/uploads/201211/04/1351995404_8744.png)
实际情况中,有编辑器来自动生成equals
【045】hashCode()和toString
1、hashCode()也是Object类中的一个方法
散列值就不多说了,大文件完整性验证就是hash验证
map中的键对比是根据键的hashCode来对比的。
User.java
class User{
String name;
int age;
public User(){
}
public User(String name,int age){
this.name = name;
this.age = age;
}
public boolean equals(Object obj){
if(this == obj){
return true;
}
boolean b = obj instanceof User;//注意instanceof是一个操作符,而不是一个函数
if(b){
//将obj转型为User对象
User u = (User)obj;
//将obj和this的成员变量进行比较,基本数据类型的用== 引用数据类型的用equals()
if(this.age == u.age && this.name.equals(u.name)){
return true;
}
else{
return false;
}
}
else{
return false;
}
}
public int hashCode(){
int result = 17;
//生成一个散列值,习惯上使用31,性能最好
result = 31 * result + age;
result = 31 * result + name.hashCode();
return result;
}
}
test.java
import java.util.*;
class test{
public static void main(String args []){
User u = new User("zhangsan",12);
HashMap<User,String> map = new HashMap<User,String>();
map.put(u,"abc");
String s = map.get(new User("zhangsan",12));
System.out.println(s);
}
}
*hashCode()以后也是工具实现的
2、toString()是Object类的方法,可以复写