------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、函数
1,函数的定义:函数是定义在类中的具有特定功能的一段独立小程序,又称为方法。
2,函数的格式:
修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,。。。){
执行语句;
return 返回值;
}
注意1:当函数没有返回值时,返回值类型用void表示,函数体内的return语句可以不写。
如果写的话,后面不用加返回值,直接跟‘;’。
注意2:在return语句下面不能再有语句。
3,函数的特点:
a,定义函数可以将功能代码进行封装,可以方便对功能进行使用,提高了复用性。
b,函数只有在被调用时才会执行
在使用函数时,要明确函数的参数列表,要明确函数的返回值类型。
4,函数的一个重要特性:重载
在同一个类中,允许存在一个以上的同名函数,只要它们的参数列表不同即可。
参数列表包括参数个数、参数类型、参数顺序,有一项不同,函数就不同。
重载与返回值类型无关,只与参数名和参数列表有关。
Java是严谨性语言,如果函数出现调用的不确定性就会失败。
演示代码:
/*
* 重载:同一个类中,允许存在一个以上的同名函数,只要它们的参数列表不同即可
*/
public class FunctionDemo {
public static void main(String[] args) {
}
// 返回值:int 参数列表:2个,都是int
private static int add(int a,int b){
return a+b;
}
// 返回值:int 参数列表:3个,都是int
private static int add(int a,int b,int c){
return a+b+c;
}
// 返回值:int 参数列表:2个,都是double
private static int add(double a,double b){
return (int)(a+b);
}
// 返回值:double 参数列表:2个,都是int 与上面的函数相同。
// 虽然返回值类型不同,但函数名与参数列表相同,
// java是严谨性语言,不允许这种形式存在
// private static double add(int a,int b){
// return (double)(a+b);
// }
}
1,数组的概念:同一种类型数据的集合。
2,数组的好处:可以给数组中的元素进行编号,从0开始。方便操作这些元素。
3,数组的格式:元素类型[ ] 数组名 = new 元素类型[元素个数或数组长度] 。
数组一旦建立,必须明确长度。演示代码:
/*
* 数组的定义格式
*/
public class ArrayDemo1 {
public static void main(String[] args) {
// 数组定义时必须明确数组的长度 ,需要一个容器,但是不明确容器的具体数据
int[] arr1 = new int[3];
int arr2[] = new int[3];
// 数组定义并初始化,不要在[]填写长度,存储已知具体数据
int[] arr3 = new int[]{3,2,1};
int arr4[] = new int[]{2,4,6,8};
// 方式三 静态初始化
int[] arr5 = {33,44,55,66};
}
}
栈内存:存储的是局部变量。变量所属的作用域一旦消失,变量就会释放。
堆内存:存储数组和对象(数组也是对象),凡是被new出来的都在堆内存。
对内存的特点:a,每一个实体都有首地址值。b,对内存中每一个变量都有默认化初始值,
根据类型的不同而不同。整数--0,小数--0.0或0.0f,boolean--false,char--\u0000
c,对内存中的对象不用后会变成垃圾,java会自动回收垃圾(垃圾回收机制)。
5,数组使用过程中一些常见问题:
a,当访问一个数组中不存在的角标时,会引发角标越界异常:ArrayIndexOutOfBoundsException
b,当引用型变量没有任何指向时,还在用其操作实体,会引起NullPointerException
5,数组的基本操作:核心思想就是对角标的操作。
数组的基本操作包括存入、取出、获得最大(小)值、排序(升/降)、二分查找等,演示代码:
public class ArrayDemo1 {
public static void main(String[] args) {
show1(); // 数组的存取
show2(); // 数组的最大值和最小值
show3(); // 选择排序
show4(); // 冒泡排序
show5(); // 二分查找
}
private static void show5() {
int[] arr = new int[]{33,22,11,44,66,55};
int index = binarySearch(arr,44);
index = binarySearch2(arr,66);
System.out.println(index);
}
private static int binarySearch2(int[] arr,int key){ // 二分查找第二种形式
int min,mid,max;
min = 0;
max = arr.length-1;
while(min>1;
if(key>arr[mid])
min = mid+1;
else if(keyarr[mid])
min = mid+1;
else if(keymax)
return -1;
mid = (max+min)/2;
}
return mid;
}
private static void show4() {
int[] arr = new int[]{33,22,11,44,66,55};
bubbleSort(arr);
}
/*
* 冒泡排序
* 思路:遍历数组,第一轮:从第一个值(0角标)开始,与第二个值比较,如果第一个值 大于
* 第二个值,将二者位置交换,反之则不交换。然后用第二个值与第三个值比较,依次类推
* 当遍历到倒数第二个值时,就能确定最后一个值时数组中的最大值。
* 然后从头开始遍历,开始第二轮排序,此时不用考虑最后一个元素,这样额可以
* 确定倒数第二个角标的数值。
* 然后依次循环即可。
*/
private static void bubbleSort(int[] arr) {
// 确定外循环的次数
for(int i=0; iarr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for(int i=0; iarr[j]){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
/*
* 取数组中的最大值
* 思路:定义一个变量记录最大值
* 遍历数组,先将第一个值默认为最大值,跟后面一个数值进行比较,如果第一个数大于第二个数值,
* 那么最大值仍然是第一个数值,否则是第二个数值,依次类推,知道遍历完数组为止
*/
private static void show2() {
int[] arr = {3,2,11,25,99,23,45};
// 定义方法获取最大值。最小值思路一样
int max = getMax(arr);
System.out.println(max);
}
private static int getMax(int[] arr) {
// 注意对max进行初始化时,应该将数组中的一耳光值赋值给max
int max=arr[1];
// 遍历数组,当有值比max大时,就将这个值赋值给max
for(int i=1; imax)
max = arr[i];
}
return max;
}
// 数组的存取
private static void show1() {
int[] arr = new int[5];
// 对数组赋值
for(int i=0; i
6,进制转换:
思路(以16进制为例):将数字num与15进行&运算,得到最低4位的数值,再将该数值转换为
相应进制的数字即可,这个转换过程可以根据查表法来完成。然后将数字num右移4位(无符号
右移>>>),如果右移后的数字不为0,再与15进行&运算,依次类推。0为特殊情况,单独列出。
演示代码:
public class ArrayTest {
public static void main(String[] args) {
int num = 28;
toBinary(num);
toOctal(num);
toHex(num);
}
private static void toHex(int i) {
trans(i,15,4);
}
private static void toOctal(int i) {
trans(i,7,3);
}
private static void toBinary(int i) {
trans(i,1,1);
}
private static void trans(int num, int j, int k) {
// 当num为0时,直接返回0
if(num==0){
System.out.println(num);
return;
}
// 建立一个表,用于查询
char[] chs = {'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F'};
char[] arr = new char[32];
int pos = arr.length;
while(num!=0){
int temp = num&j;
arr[--pos] = chs[temp];
num>>>=k;
}
for(int i=pos; i
7,二维数组
public class ArrayDemo2 {
public static void main(String[] args) {
show1(); // 二维数组的定义
show2(); // 常见问题
show3(); // 二维数组遍历
}
private static void show3() {
int[][] arr = {{2,3,4},{2,3},{5}};
for(int i=0; i
三、多线程2
1,同步代码块对锁的操作是隐式的。
jdk1.5后,将锁封装成对象,提供了lock(获取锁)和unlock(释放锁)方法。
ReentrantLock,一个可重入的互斥锁Lock,它具有与使用synchronized相同的作用。
Lock接口:替代了同步代码块或者同步函数,将同步代码块的隐式锁操作变成显式操作。
同时更为灵活,可以在一个锁上加上多个监视器对象。
lock用来获取锁,unlock用来释放锁,通常需要定义在finally代码块中。
Condition接口:替代了Object中的wait、notify、notifyAll方法,将这些监视器方法进行单独
的封装,变成Condition监视器对象,可以任意锁进行组合。演示代码:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadDemo10 {
public static void main(String[] args) {
// 创建公共资源的对象
Duck d = new Duck();
// 将该对象分别封装到生产和消费线程,再将消费或生产线程的对象作为Thread对象的构造函数
// 的参数进行传递,并开启线程
new Thread(new Producer(d)).start();
new Thread(new Consumer(d)).start();
new Thread(new Producer(d)).start();
new Thread(new Consumer(d)).start();
}
}
class Duck{
private String name;
private int count = 1;
private boolean flag = false;
// 创建锁对象
Lock lock = new ReentrantLock();
Condition pro = lock.newCondition(); // 创建监视器对象
Condition con = lock.newCondition(); // 一个锁上可以绑上多个监视器对象
public void setDuck(String name){
lock.lock();
try{
while(flag)
try {
pro.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
this.name = name+count;
System.out.println(this.name+"++++++++");
count++;
this.flag = true;
// 使用notify,一次只唤醒一个线程,无法确保唤醒对方线程,如果唤醒本方线程,无意义
con.signal();
}finally{
lock.unlock();
}
}
public void getDuck(){
lock.lock();
try{
while(!flag)
try {
con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.name+"--------");
this.flag = false;
pro.signal();
}finally{
lock.unlock();
}
}
}
// 将任务进行封装
class Producer implements Runnable{
// 将Duck进行封装,确保公共资源的唯一性
private Duck duck;
public Producer(Duck duck){
this.duck = duck;
}
public void run(){
while(true){
duck.setDuck("烤鸭");
}
}
}
//将任务进行封装
class Consumer implements Runnable{
// 将Duck进行封装,确保公共资源的唯一性
private Duck duck;
public Consumer(Duck duck){
this.duck = duck;
}
public void run(){
while(true){
duck.getDuck();
}
}
}
2,wait和sleep的区别
a,wait可以指定时间也可以不指定时间,sleep必须指定时间
b,在同步中,对CPU的执行权和锁的处理不同,
wait:释放执行权,释放锁。sleep:释放执行权,不释放锁。
注意:在同步中,谁拿锁谁执行。其他线程可以是阻塞状态,但不能执行。
3,线程的停止:
a,使用stop方法。b,run方法结束。
怎么控制线程任务的结束呢?任务中都会有循环结构,只要控制住循环就可以结束任务。
控制循环通常用定义标记来完成。演示代码:
public class ThreadDemo11 {
public static void main(String[] args) {
// 创建任务对象,并传递给线程对象的构造参数
StopThread st = new StopThread();
new Thread(st).start();
new Thread(st).start();
// 当满足条件时,将flag置为false
int num = 1;
for(int x=1; x<100; x++){
if(x==50){
st.setFlag();
break;
}
System.out.println(Thread.currentThread().getName()+"......"+num++);
}
System.out.println("over");
}
}
class StopThread implements Runnable{
private boolean flag = true;
public void setFlag(){
flag = false;
}
@Override
public void run() {
while(flag){ //定义标记,从而可以结束循环结构
System.out.println(Thread.currentThread().getName()+"......");
}
}
}
在Thread类中提供了一个interrupt方法,将线程的冻结状态清除掉,让线程具有CPU的执行资格,
但是会抛出一个InterruptedException。
4,守护线程:setDaemon,在线程启动前使用,当正在运行的线程都为守护线程时,java虚拟机退出。
5,join方法:可以加入一个线程。setPriority方法:设置执行优先级,最低为1,最高为10,默认为5。
当线程优先级最高时,并不意味着该线程可以执行完才运行其他线程,依然要和其他线程抢执行权,只不过
运行到的概率提高。
public class ThreadDemo11 {
public static void main(String[] args) throws InterruptedException {
// 创建任务对象,并传递给线程对象的构造参数
StopThread st = new StopThread();
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);
t1.start();
t1.join(); // t1线程要申请加入进来运行
t2.start();
// 优先级提高,默认优先级为5,最高位10,最低为1
t2.setPriority(Thread.MAX_PRIORITY);
for(int x=1; x<50; x++){
System.out.println(Thread.currentThread().getName()+"......"+x);
}
System.out.println("over");
}
}
class StopThread implements Runnable{
private boolean flag = true;
public void setFlag(){
flag = false;
}
@Override
public void run() {
for(int x=0; x<50; x++){
System.out.println(Thread.currentThread().getName()+"......");
}
}
}
The End