实现进制转换。
十进制转二进制。
//这段代码用来将十进制转化成二进制,原理是应用除2取余的方法
class toBin
{
public static void toBin(int num)
{
StringBuffer store=new StringBuffer(); //StringBuffer是一个对象
while(num>0)
{
store.append(num%2)//StringBuffer对象用来将字符串添加到指定字符串列
num/=2;
}
//StringBuffer.reverse()方法用来将存入的字符反转。
System.out.println(store.reverse());
}
public static void main(String[] args)
{
toBin(6); //输出结果是110
}
}
十进制转十六进制。
字符数组在初始化时默认是'\u0000',其中\u 的意思是unicode是国际标准码。其打印输出就是' '一个空。也就是说,字符数组在初始化的时候默认是空的。下面演示的是整个代码一步步达到优化的过程。
class toBin
{
//十进制转二进制
public static void toBin(int num)
{
StringBuffer store=new StringBuffer();
//cmd里边cls是清屏。哈哈哈偷师感觉不错。
while(num>0)
{
store.append(num%2);
num=num/2;
}
System.out.println(store.reverse());
}
//十进制转16进制
public static void toHex(int num)
{
StringBuffer store =new StringBuffer();
//while循环的弊端是,无法输出前边的0。用for比较好。for(int i=0;i<8;i++)里边代码一样。
while(num>0)
{
int temp = num&15;
if(temp>9)
{
char a=(char)(temp-10+'a');//这里两步可以合成一步滴~
store.append(a);
}else
store.append(temp);
num = num>>>4;
}
System.out.println(store);
}
public static void main(String[] args)
{
toBin(6); //System.out.println(Integer.toBinaryString(6));效果是一样的。
toHex(60);
}
}
//改进版的十进制转16进制。
class toHex
{
public static void toHex(int num)
{
//这里的高明之处在于,用查表的方式代替了计算,降低了复杂度。
char[] arr={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
StringBuffer store = new StringBuffer();
for (int i=0;i<8;i++)
{
int temp = num&15;
store.append(arr[temp]);
num=num>>>4;
}
System.out.println(store.reverse());
}
//再改进,用数组存储,而不用StringBuffer
public static void toHex_2(int num)
{
char[] arr={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
//定义一个临时容器
char[] ans=new char[8]; //定义一个字符数组用来存储,注意字符数组默认是' ',是空
/* int pos=0; //定义一个指针。
while(num!=0)
{
int temp = num&15;
ans[pos++]=arr[temp];
num=num>>>4;
}
for (int i=pos-1;i>=0;i--)
{
System.out.print(ans[i]+",");
}
*/
//再改进版
int pos=ans.length;
while(num!=0)
{
int temp=num&15;
ans[--pos]=arr[temp];
num=num>>>4;
}
//对存储字符的ans数组进行遍历。
for (int i=pos;i<ans.length;i++)
{
System.out.print(ans[i]+",");
}
}
public static void main(String[] args)
{
// toHex(60);
toHex_2(60);
}
}
//终级版,经过抽取后
class Demo
{
public static void trans(int num,int base,int offset)
{
if(num==0)
{ System.out.println("0");
return ;
}
char[] arr={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] ans=new char[32];
int pos=ans.length;
while(num!=0)
{
int temp = num & base;
ans[--pos] = arr[temp];
num=num >>>offset;
}
for (int i=pos;i<ans.length;i++) //注意是从pos 开始的
{
System.out.print(ans[i]);
}
System.out.println();
}
public static void toHex(int num)
{
trans(num,15,4);
}
public static void toBin(int num)
{
trans(num,1,1);
}
public static void main(String[] args)
{
toHex(60);
toBin(6);
}
}
二维数组:
//二维数组的一些基本知识
class Demo{
public static void main(String[] args)
{
//这段代码会输出 [I@15db9742 ,
//输出的是一维数组的首地址,[代表一维数组 I代表int型 后面是哈希映射后的一个地址
int[] arr=new int[3];
System.out.println(arr);
System.out.println("+++++++++++++++++++++++++++++++");
//这段输出 0 Int型数组默认值是0;
int[] arr1=new int[3];
System.out.println(arr1[0]);
System.out.println("+++++++++++++++++++++++++++++++");
//这段输出 [[C@15db9742 ,[[代表二维数组,C代表字符型,后面是地址
char[][] arr0=new char[3][];
System.out.println(arr0);
System.out.println("+++++++++++++++++++++++++++++++");
//这段输出null,因为未定义一维数组的长度,二维数组是引用类型,默认是null
int[][] arr2=new int[3][];
System.out.println(arr2[0]);
System.out.println("+++++++++++++++++++++++++++++++");
//这段输出一维数组地址,arr3[0]这个一维数组的地址
int[][] arr3=new int[3][3];
System.out.println(arr3[0]);
System.out.println("+++++++++++++++++++++++++++++++");
//[[C@4e25154f
char[][] arr4=new char[3][3];
System.out.println(arr4);
System.out.println("+++++++++++++++++++++++++++++++");
int[][] a=new int[3][];
a[0]=new int[3];
a[1]=new int[1];
a[2]=new int[2];
System.out.println(a.length);//打印的是二维数组里包含几个一维数组,3
System.out.println(a[1].length);//打印的是二维数组中a[0]这个一维数组的长度
int[][] dem={{3,4,5},{1},{34,78,90,12}};
//二维数组求和。
int sum=0;
for (int i=0;i<dem.length;i++)
{
for(int j=0;j<dem[i].length;j++)
{
sum=sum+dem[i][j];
}
}
System.out.println(sum);
}
}
面向对象:
1、是一种思想,能让我们的角色转变从执行者变成指挥者,让问题简单化。
2、如面试招聘:面试官就是在指挥员工的专业功能去完成任务。
3、如点菜,吃饭的人在调用服务员的点菜功能。
4、有对象就使用,没对象就造一个对象使用。
面向对象的三个特征:封装、继承、多态。
类:即对现实生活中事物的描述。(主要是属性和行为)
对象:生活中实实在在的事物。
类中的属性和行为专业称呼是成员变量和成员函数,类通过new来产生一个类类型对象,所谓“类类型”是除八种基本数据类外的三种引用数据类型,第一种是数组,第二种是类类型,第三种待续。类类型变量指向一个对象,这个对象是用类实例化的实体。
堆内存中所有东西都有默认初始化值。
不独立运行的可以不写主函数。即:不是所有类都必须写主函数。
成员变量和局部变量的区别:
先说一下定义,类中有两种成员,一种描述事物属性(即成员变量),一种描述事物的功能(成员函数)。局部变量是定义在语句或者一个函数中的变量,如for ( int i=0 ;i<arr.length ;i++)这里的变量 i 就是一个局部变量,出了for循环就不再存在了。
成员变量和局部变量区别有二:一是作用范围不同,成员变量作用于整个类而局部变量只在其存在的函数或语句内。二是存储位置不同,成员变量是一个对象的属性,它存在于堆内存中,因为对象存在于堆内存中。局部变量只是一个引用,它存在于栈内存中。
匿名对象:
new Car(); // 建立一个匿名对象1
new Car().color = blue; //又建立一个匿名对象b,b的color属性是blue
new Car().run(); //v建立一个匿名对象,运行run方法
基于上三句,匿名对象调用属性是无用的。匿名对象调用方法是有用的。
匿名对象使用方式一:只调用一次对象方法时使用,比较方便。
匿名对象使用方式二:可以作为实际参数进行传递。
show 方法里有很多局部变量,所以会在栈内存中开一个show的内存。当函数执行完毕后,栈内存释放,堆内存释放,都当成垃圾处理。而不使用匿名对象的还会有一个指针指向它,如下图的q。
封装encapsulation: 是指隐藏对象属性和实现细节,仅对外提供公共访问方式,比如你不必了解电脑内部构造但你可以直接使用。
原则:1将不对外提供的东西隐藏起来。2把属性都隐藏,提供公共接口对其访问。
如何隐藏呢?
通过关键字。private。
private:可修饰成员变量,可修饰成员函数,被修饰对象只在本类中有效。
类中的成员变量几乎都用private修饰以防外界乱改,那外界如何访问到这个变量 呢?
通过get和set两个函数。
//体会封装
class Person
{
private int age;
public static void setAge(int a)
{
if(a>0 &&a<130)
age=a;
else
System.out.pirntln("error");
}
public static int getAge(int a)
{
return age;
}
public static void speak()
{
System.out.println("age="+age);
}
}
class PersonTest
{
People xiaoM=new Person();
xiaoM.setAge(16);
xoaoM.getAge();
xiaoM.speak();
}
构造函数
当分析事物时,该事物一存在就具备的行为,就可以定义在构造函数内。
特点:
1名字与类名相同
2不需要返回值
3对象只要一建立,立即运行与之对应的构造函数,用于给对象初始化,每new一次就执行一次。
4当一个函数没有定义构造函数时,系统默认给加一个空的构造函数,但只要你写了系统就不给加了。
5构造函数可以重载,即一个类中可有多个构造函数(重载就是名字相同但参数列表不同的函数)
6与一般函数区别有二:一是构造函数在对象建立时运行(没构造函数对象无法建立)而普通函数在调用时才运行。二是构造函数只运行一次,而普通函数可以多次运行。
7构造函数可以私有化,但是私有化后的构造函数就无法创建对象了。
构造代码块:
作用:为对象初始化,优先于构造函数运行,只要有构造函数运行就先走一遍它。没名字,直接写大括号里。
与构造函数区别:构造代码块是抽取出所有构造函数都需执行的共性代码,而重载的构造函数针对不同对象运行不同的代码内容。
重点:this
下面这段代码执行起来没有任何问题,但是第一个构造函数处传的参数名string n;没有可读性,准备改成name。但改变后的代码打印出的name=null。 原因是,成员变量已经有一个名字叫name,当执行第一个构造函数时,系统会把等式左边的name也当成传参括号中的那个name而不是去找上面的成员变量。结果出了第一个构函数后,身为局部变量的name就被销毁了,参数并没有传给真正的成员函数name。
class Person
{
private String name;
private int age;
Person(String n) //第一个构造函数 为了可读性改变后是person(String name)
{
name=n; //{name = name;}
}
Person(String n,int a)
{
name=n;
age=a;
}
public static void speak()
{
show();
}
public static void show()
{
System.out.porintln("name="+name+",age="+age);
}
}
class PersonDemo
{
public static void main(String[] args)
{
Person p = new Person(lisi);
p.speak();
}
}
要解决上面的问题,需要用this。
无论是调用成员变量还是成员函数,都是对象在调用。this 在本类中就是指正在执行调用功能的那个对象。专业说法:“this是指其所在函数所属的对象的引用”。上面代码其实是系统简化了的。没有简化的代码如下
class Person
{
private String name;
private int age;
Person(String n) //第一个构造函数 为了可读性改变后是person(String name)
{
this.name=n; //{name = name;}
}
Person(String n,int a)
{
this.name=n;
this.age=a;
}
public static void speak()
{
this.show();
}
public static void show()
{
System.out.porintln("name="+name+",age="+age);
}
}
class PersonDemo
{
public static void main(String[] args)
{
Person p = new Person(lisi);
p.speak();
}
}
this应用:但凡本类函数内部使用到了本类对象,用this指代。当在代码中看到this先要考虑它是哪个对象的引用。
this语句
this语句用于构造函数间互相调用,构造函数间调用只能用this语句,与this关键字的区别是差个“.”,注意this语句只能定义在构造函数第一行。
class Person
{
private String name;
private int age;
Person(String name)
{
this.name=name;
}
Person (String name,int age)
{
//this.name=name;
this(name); //调用上面的构造函数。因为这个代码上面构造函数已经写完了。
this.age=age;
}
}