char 字符型 占2个字节
bollen 布尔型 1个字节 true false
short 短整型 2
int 整型 4 (整形默认)
long 长整型 8
一个字节8个比特位
○ 十进制:数据以非0开头,例如:4,-15;
○ 八进制:数据以0开头,例如:054,012;
○ 十六进制:数据以0x开头,例如:0x11,0xAD00
○ 二进制(是JDK1.7新增功能):数据以0b开头,例如:0b101。
float类型以F/f结尾,double类型以D/d结尾。如果浮点常量不带后缀,则默认为双精度常量
○ 自动转换的次序为:
byte-->short-->char-->int-->long-->float-->double
○ 强制类型转换格式为:
变量 = (数据类型)表达式。 //注意:强制转换可能导致数据的失真。
出现各种类型数据的混合运算,系统将按自动转换原则将操作数转化为同一类型,再进行运算。
一个整数和一个浮点数进行运算,结果为浮点型。字符与整数的混合运算,字符转换为整数
设x=3,执行下面语句结果为true。
System.out.println((x==3)||(x/0>2)); 或运算符当前面为真不再计算后面
如果将代码改为:
System.out.println((x/0>2)||(x==3)); 则运行时将产生算术运算异常,不能用x去除0。
public class Test1 {
public static void main(String[] args) {
int x=5;
if(x=0)
System.out.println("false");
else
System.out.println("ture");
}
}
编译错误!
原因:if条件只接受boolean类型的值(true或false),x=0是int类型不能隐式地转换为boolean类型。
输出:
1)print()方法:实现不换行的数据输出;
2)println()方法:与上面方法的差别是输出数据后将换行。
3)printf()方法:带格式描述的数据输出。
%d代表十进制数
%f代表浮点数
%e代表科学表示法的指数位数(指数形式,默认6位小数:1.500340e+03)
%n代表换行符
%x代表十六进制数
%s代表字符串
%c 单个字符
%% 输出百分号%
输入:
1、字符类型数据的输入
利用标准输入流(System.in)的read()方法,可以从键盘读取字符,返回值为 int
char c=(char)System.in.read()
2、字符串的输入
1. 将键盘输入的数据看作字符流,利用InputStreamReader将从键盘输入的字节流数据转化为字符序列来识别。
2. 利用BufferedReader对字符流序列进行过滤,借助BufferedReader流对象提供的方法readLine()从键盘读取一个字符串。
import java.io.*;
public class InputString{
public static void main(String args[]) {
String s=“”; 必须赋初值,否则编译出错
System.out.print ("Enter a String please: ");
try {
BufferedReader in= new BufferedReader(new InputStreamReader(System.in));
s=in.readLine();
}
catch (IOException e) { }
System.out.println ("You've entered a String: " +s);
}
}
3、整数和双精度数的输入
通过上述字符串输入后将字符串转化
○ Integer.parseInt(String s) : 将数字字符串转化为整数 。
○ Double.parseDouble(String s) : 将字符串形式的数字数据转化为双精度数。
○ 例如:
■ String x="123"; int m= Integer.parseInt(x); //m 的值为123
■ x="123.41"; double n= Double.parseDouble(x) ; //n的值为123.41
java.util.Scanner类
1、import java.util.Scanner;
2、Scanner in=new Scanner(System.in);
3、 boolean hasNext() : 判是否有下一个数据
int nextInt() :读取整数
double nextDouble() :读取双精度数
String nextLine() : 读取一行字符串
● double random() 产生0~1之间随机数,不包括0和1
● long round(double d) 四舍五入的整数
● int abs(int i)
● int max(int i1,int i2)
● double ceil(double d) 不小于d的最小整数
● double floor(double d) 不大于d的最大整数
● double random() 产生0~1之间随机数,不包括0和1
● long round(double d) 四舍五入的整数
● double log(double d)
● double exp(double x)
● double pow(double a, double b)
● double sqrt(double a)
● double cos(double d)
例:三个数最大值 int c=Math.max(a,Math.max(b,c));
例:产生一个随机两位数 int a = 10 + (int)(90*Math.random());
产生[a,b]随机整数: a+(int)(Math.random()*(b-a+1))
1、相同数据类型元素的集合;
2、连续存放在内存之中;
3、用数组名和位置(称为下标)表达
增强 for循环 访问数组
for (数组存储元素类型 循环变量名 : 数组名) {
循环体
}
例:for (int x:score){sum += x;}其中,x的取值随循环从score[0],score[1],…,score[9]变化。
一维:{
声明:int a[];或int []a;
创建空间:int score[] = new int[10];
创建并初始化: ■ int score[ ] = {1,2,3,4,5,6,7,8,9,10};
■ int score[ ]=new int[这里不能有大小] {1,2,3,4,5,6,7,8,9,10};
score.length 指数组score的长度。
String str; str.length();字符串长度
}
二维:{
声明:int a[][];
创建空间:二维数组看作是数组的数组,不要求二维数组每一维的大小相同
(1)直接为每一维分配空间,如:
int a[][] = new int [2][3];
(2)从最高维开始,按由高到低的顺序分别为每一维分配空间。如:
int a[][] = new int [2][]; a[0] = new int [3]; a[1] = new int [4];
长度:
要获取数组的行数 a.length
通过某一行获取列数: a[1].length a[2].length
创建并初始化:
int a[][] = {{1,2,3},{4,5,6}};
int b[][] = {{1,2},{4,5,6}}; }
例:二维数组动态创建
public class ArrayOfArraysDemo2 {
public static void main(String[] args) {
int[][] aMatrix = new int[4][];
for (int i = 0; i < aMatrix.length; i++) {
aMatrix[i] = new int[i+1];
for (int j = 0; j < aMatrix[i].length; j++)
aMatrix[i][j] = i + j;
}
for (int i = 0; i < aMatrix.length; i++) {
for (int j = 0; j < aMatrix[i].length; j++)
System.out.print(aMatrix[i][j] + " ");
System.out.println();
}
}
/*
【运行结果】
0
1 2
2 3 4
3 4 5 6
*/
}
例:求矩阵的最外一圈元素之和
public class Demo {
public static void main(String[ ] args) {
int [ ][ ] a = new int[4][5];
int sum=0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
a [i][j] = (int)(Math.random()*10);
System.out.print(a[i][j] + "\t");
if (i==0||j==0||i==a.length-1||j==a[0].length-1)
sum += a[i][j];
}
System.out.println();
}
System.out.println("sum= " +sum);
}
/*
7 9 3 7 8
8 1 5 2 8
4 2 1 5 4
1 1 1 2 6
sum= 69
*/
}
因为是在堆中,所以new的时候jvm会自动给数组赋值。
1、int类型定义的数组,初始化默认是0
2、String类型定义的数组,默认值是null
3、char类型定义的数组,默认值是0对应的字符
4、double类型定义的数组,默认值是0.0
5、float类型定义的数组,默认值是0.0
6、boolean类型定义的数组,默认值是false
Arrays类封装了对数组进行操作的一系列静态方法。
1. 利用Arrays类的sort方法可方便地对数组排序。
例如: java.util.Arrays.sort(a) ;
2. 利用Arrays类的toString()方法可以将数组转化为字符串的形式。
例如: System.out.print(java.util.Arrays.toString(a) );
3. 利用Arrays类的copyOf()方法实现数组的拷贝。
例如: int[] b=Arrays.copyOf(a,3);
{
import java.util.Random;
public class test7_5 {
public static void main(String[] args) {
{
int[] a=new int[20];//整型数组
String str="";//存放抽到的随机数
for(int i=1;i<=20;)
{
int num=10+(int)(Math.random()*81);//Math.random()是用于随机生成一个[0.0, 1.0)
String S=num+","; //随机数之间用逗号隔开
if(str.indexOf(S)==-1) //是否已经存在该数
{
str=str+S; //拼接字符串
i++;
}
}
String[] str1=str.split(",");//以逗号为分隔符,存入str1
//将字符串类型转为整型并输出
System.out.println("随机函数产生 20 个 10 ~ 90 之间的不重复整数为:");
for(int i=0;i<str1.length;i++) {
a[i]=Integer.parseInt(str1[i]);
System.out.print(a[i]+" ");
}
System.out.println();
java.util.Arrays.sort(a); 排序
System.out.println("数组的内容按由小到大的顺序输出为:");
for(int i=0;i<a.length;i++)
System.out.print(a[i]+" ");
}
}
}
}
属性初始化执行次序:定义时赋值→ 初始代码块 → 构造方法
初始化:{
1、定义属性成员时初始化:
public class Point {private int x=10;}
2、初始化块来设置对象的初值:
public class Point {
private int x; 默认为0
{ //初始化代码块
x = 20;
}
}
3、构造方法:
public Point(int x1, int y1) {
x = x1;y = y1;
}
例:
public class A {
int v=0;
{ v=v+1; } //初始化块
public A( ) { }
public A(int x ) { v=x; }
public static void main(String args[ ]) {
A m1 = new A(25);
System.out.println(m1.v); 25
A m2 = new A();
System.out.println(m2.v); 1
}
}
}
static修饰的属性:{
访问:
在本类中直接访问:count
通过类名访问:User.count
通过类的一个对象访问,如:x1.count
静态初始化代码的执行是在main方法执行前完成。
初始化代码块:对象初始化,创建对象时,系统先调用类里定义的初始化块。在构造方法之前执行。
静态初始化代码块:又称类初始化代码块,对类进行初始化,在初始化代码块之前执行,其不能对实例变量进行初始化。
区别:
初始化代码块创建对象时执行,每次创建对象都会执行一次;(main之后)
静态初始化代码块在加载类时会执行,且只执行一次(main之前)
例:
class test {
static int x=5;
int y=5;
static { x+=10; }
{y+=10;}
public static void main(String args[ ]) {
System.out.println("x="+x);
x+=20;
test a=new test();
System.out.println("x="+a.x);
System.out.println("y="+a.y);
a.y+=20;
test b=new test();
System.out.println("y="+b.y);
}
static { x=x-5; } 注意
/*
x=10
x=30
y=15
y=15
*/
}
例:静态空间与对象空间的对比
class TalkPlace {
static String talkArea="";
}
public class User {
static int count=0; //类变量
String username;
int age; //实例变量
public User(String name,int yourage) {
username=name;
age=yourage;
}
/* 方法log通过静态变量记录调用它的次数 */
void log( ) {
count++; //直接访问本类的静态变量
System.out.println("you are no "+count+" user");
}
void speak(String words) { /* 向讨论区发言 */
TalkPlace.talkArea += username + "说:"+words+"\n";
}
public static void main(String args[ ]) {
User x1 = new User("张三",20);
x1.log( );
x1.speak("hello");
User x2 = new User("李四",16);
x2.log( );
x2.speak("good morning");
x1.speak("bye");
System.out.println("---讨论区内容如下:");
System.out.println(TalkPlace.talkArea);
}
}
}
static修饰的方法:{
1、用static修饰的方法称为静态方法,也叫类方法
2、在static方法中只能访问类变量和其它static方法
3、在static方法中绝不能直接访问任何归属对象空间的变量或方法
例:public static void clearCount(){
count=0; //访问类变量
age=0; //不允许
} 不能访问其他非静态变量
public class findPrime {
public static boolean prime(int n){
for (int k=2;k<=Math.sqrt(n);k++)
if ( n % k==0)
return false;
return true;
}
1、 public static void main(String args[]) {
for (int m=10;m<=100;m++)
if ( prime(m))
System.out.print(m+" , ");
}
2、 public static void main(String args[]) {
findPrime x=new findPrime();
for (int m=10;m<=100;m++)
if ( x.prime(m) )
System.out.print(m+" , ");
} 如果将prime方法设计为非静态方法
} 访问静态和非静态方法
思考题:
public class Test{
long a[ ] = new long[10];
public static void main ( String args[] ){
System.out.println (a[6]); 出现编译错误,Test x=new Test();System.out.println ( x.a[6]);或static long a[ ] = new long[10];
}
}
}
理解this:{
this ---出现在类的实例方法、初始化代码块、构造方法中,用来代表使用该方法的当前对象的引用。
用this作为前缀,访问当前对象的属性或方法。
1)使用this可以区分当前作用域中同名的不同变量。
private int x, y; // 属性
public Point(int x, int y) { //构造方法
this.x = x;
this.y = y;
}
2)把当前对象引用作为参数传递给另一个方法。
如: p.distance(this);
3)一个构造方法中调用同类的另一个构造方法。
public Point() { this(0,0); }
例:
public class Point {
private int x, y;
public Point(int x, int y) {
this.x = x; this.y = y;
}
public Point() { 无参构造方法
this(0,0); 用this调用本类的另一构造方法
}
public double distance(Point p) {
return Math.sqrt((this.x-p.x)* (x-p.x) + (y-p.y)*(y-p.y));
}
/*以下两个方法在利用上面方法求距离(演示概念)*/
public double distance2(Point p) {
return p.distance(this); //p到当前点的距离
}
public double distance3(Point p) {
return this.distance(p); //调用当前对象另一方法
……
}
}
}
继承意味着什么?什么是变量的隐藏?
1、可以实现方法重写(这样可以实现运行时多态性)。继承允许我们重用代码,它提高了Java应用程序的可重用性。
2、如果子类中定义了与父类同名的属性,在子类中将隐藏来自父类的同名属性变量。
子类构造方法与父类构造方法有何联系?
1、super来调用父类的构造方法,必须是子类构造方法的第1条语句!super.name=aname; 通过super关键字来访问父类中的name属性
2、子类在自己定义构造方法中如果没有用super明确调用父类的构造方法,则在创建对象时,首先自动执行父类的无参构造方法,然后再执行自己定义的构造方法。
注意:如果子类构造函数没有用父类构造方法且父类中无无参构造函数会出现编译出错
例:{
class parent {
String my;
public parent(String x) { my=x; }
}
public class subclass extends parent {
subclass x=new subclass();
}
}
子类this:{
【注意】使用 this 查找匹配的方法时首先在本类查找,找不到时再到其父类和祖先类查找;
使用 super 查找匹配方法时,首先直接到父类查找,如果不存在,则继续到其祖先类逐级往高层查找。
}
多态性:{
1、(编译时多态)同一类中(重载):同一类中允许多个同名方法,通过参数的数量、类型的差异进行区分。编译时确定调用哪个方法。
2、(运行时多态)子类对父类方法的重新定义(方法覆盖):方法名、返回值和参数形态完全一样。在运行时确定调用哪个方法。
方法覆盖有以下问题值得注意:6.2
方法重载与覆盖的区别
1. 重载是同一个类中定义了多个同名的方法,表示方法间的关系,是水平关系;覆盖是子类和父类之间的关系,是垂直关系。
2. 重载是多个方法之间的关系;覆盖是由一个方法或只能由一对方法产生关系。
3. 重载要求参数列表不同;覆盖要求参数列表相同。
4. 重载是根据调用时的实参表与形参表选择方法体;覆盖是根据对象类型来调用方法体。
访问继承的成员:{
(1)继承关系中方法的继承与父类属性隐藏{
class parent{
int x=100;
void m() {
System.out.println(x);
}
}
public class child extends parent{
int x=200;
public static void main(String[] args) {
child a=new child();
a.m();
System.out.println(a.x);
}
}
运行结果:
100
200
}
(2)继承关系中方法的覆盖{
class parent{
int x=100;
void m() {
System.out.println(x);
}
}
public class child extends parent{
int x=200;
void m() {
System.out.println("x="+x);
}
public static void main(String[] args) {
child a=new child();
a.m();
System.out.println(a.x);
}
}
运行结果:
x=200
200
}
(3)父类引用子类对象{
class parent{
int x=100;
void m() {
System.out.println(x);
}
public class child extends parent{
int x=200;
void m() {
System.out.println("x="+x);
}
public static void main(String[] args) {
parent a=new child();
a.m();
System.out.println(a.x);
}
}
运行结果:
x=200
100
}
} 重要,调用的方法是子类方法,属性是父类属性
}
}
访问继承的成员(重要){
class SuperShow {
int y = 8; // 父类SuperShow的y属性
int m = 2;
void show() { //父类SuperShow的show方法
System.out.println("sup.show,y="+y);
}
}
public class ExtendShow extends SuperShow { 每个子类对象有4个属性:y、z、super.y、m
int y = 20; // 子类ExtendShow的y属性
int z = 1;
void show() { // 子类ExtendShow的show方法
System.out.println("ext. show,y="+y);
}
public static void main(String args[]) {
ExtendShow b = new ExtendShow();
SuperShow a = b;
System.out.println("ext.y=" + b.y); 20
System.out.println("sup.y=" + a.y); 8
b.show(); y=20
a.show(); y=20
System.out.println("z="+b.z+",m="+b.m); z=1,m=2
}
}
运行结果:
ext.y=20
sup.y=8
ext. show,y=20
ext. show,y=20
z=1,m=2
} //调用的方法是子类方法,属性是父类属性
例:{
例1:
class Test5 {
int k = 8;
public void doSome() {
System.out.println("k1="+k);
}
}
class Sub extends Test5 {
int k = 66;
public void doSome() {
k=k-2;
System.out.println("k2="+k);
}
public static void main(String args []) {
Test5 obj = new Sub();
obj.doSome();
System.out.println("k3="+obj.k);
}
}
运行结果:
k2=64
k3=8
思考:
(1)将obj定义为子类引用变量如何?(Test5->Sub)
运行结果:
k2=64
k3=64
(2) 将子类的doSome()方法删除又如何?
k1=8
k3=8
例2:
class exSuper {
public void func(String p, String s) {
System.out.println(p);
}
}
public class test extends exSuper {
public void func(String p, String s) {
System.out.println(p + " : " + s);
}
static public void main(String arg[ ]) {
exSuper e1 = new exSuper( );
e1.func("hello1", "hi1");
exSuper e2 = new test();
e2.func("hello2", "hi2");
}
}
运行结果:
hello1
hello2 : hi2
}
Object类:{
● public boolean equals(Object obj) :
//该方法本意用于比较两个对象的封装的数据是否相等;而比较运算符“==”在比较两对象变量时,只有当两个对象引用指向同一对象时才为真值。
在Object类中,equals方法是采用“==”运算进行比较(地址比较);若表示对象的数据比较,要重写equals()方法;
● public String toString(): 该方法返回对象的字符串描述;
● public final Class getClass(): 返回对象的所属类;
● protected void finalize(): 该方法Java垃圾回收程序在删除对象前自动执行。
{
public class Point {
private int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public boolean equals(Point p) {
return (x == p.x && y == p.y);
}
public String toString() {
return "点:" + x + "," + y;
}
public static void main(String arg[]) {
Point x=new Point(4,3);
System.out.println("x="+x);
System.out.println( x.equals(new Point(4,3)) );
}
}
运行结果:
x=点:4,3
true
【思考】
1、观察有无toString()方法时程序运行结果的变化。
无toString()运行结果:
x=Point@404b9385
true
2、观察有无equals(Point p)方法程序运行结果的变化。
无equals(Point p)运行结果:
x=点:4,3 (没有重写equals方法则是引用的比较)
false
}
{
public class IsEqual {
int x;
public IsEqual(int x1) {
x=x1;
}
public static void main(String a[ ]) {
IsEqual m1=new IsEqual(4);
IsEqual m2=new IsEqual(4);
IsEqual m3=m2;
m3.x=6; //注释后呢?
System.out.println("m1=m2 is "+(m1==m2));
System.out.println("m2=m3 is "+(m2==m3));
System.out.println("m1.x==m2.x is "+(m1.x==m2.x));
System.out.println("m1.equals(m2)="+m1.equals(m2));
}
}
运行结果:
m1=m2 is false
m2=m3 is true
m1.x==m2.x is false
m1.equals(m2)=false
m3.x=6; //注释后呢?
运行结果:
m1=m2 is false
m2=m3 is true
m1.x==m2.x is true
m1.equals(m2)=false
}
}
访问控制修饰符:{
同一类中 同一包中 不同包的子类中 其他
private Yes
默认 Yes Yes
protected Yes Yes Yes
public Yes Yes Yes Yes
}
final修饰符:{
● final作为类修饰符 ----最终类 (不能有子类)
● 用final修饰方法 ----不能被子类重新定义
● 用final定义常量 (必须被初始化) ----只能赋值一次
【注意】 如果将引用类型的变量标记为final,那么该变量固定指向一个对象,但可以改变对象内的属性值。 final意味着不能改变,到此为止!
{
public final class test {
public static int totalNumber=5;
public final int id; //error 与普通属性变量不同的是,系统不会给常量赋默认初值.
public int weight;
public test(int weight) {
id=totalNumber++;
this.weight=weight;
}
public static void main(String args[ ]) {
final test t=new test(5);
t.weight=t.weight+2;
t=new test(4); 不允许
t.id++; 不允许
}
}
}
}
对象引用赋值转换:{
1. 允许将子类对象赋值给父类引用 。
2. 将父类引用赋值给子类变量时要进行强制转换,强制转换在编译时总是认可的,但运行时的情况取决于对象的值。
1. Object m = new String("123"); // 允许,父类变量引用子类对象
2. String y = m; // 不允许
3. String y = (String) m; // 强制转换,编译允许,且运行没问题
4. Integer p = (Integer) m; // 强制转换,编译允许,但运行时出错
Integer p = Integer.parse((String) m);
{
public class test{
static void m(double x) {
System.out.println("m(double):" + x);
}
static void m(Object obj) {
System.out.println("m(Object):" + obj );
}
public static void main (String args[]) {
m("hello");
m(5);
}
}
运行结果:
m(Object):hello
m(double):5.0
}
}
public String toString() { 父类toString
return "点:" + x + ","+ y;
}
public String toString() { 子类重写toString
return super.toString() + "颜色: " +c; super代表父类对象的引用,用super调用父类成员
}
public void display(){
System.out.print("学号::"+No);
System.out.print(" 姓名::"+Name);
System.out.println(" 年龄::"+Age);
}
public String toString(){
return "学号::"+No+" 姓名::"+Name+" 年龄::"+Age;
}
String的特点:
1.为不可变对象,一旦被创建就不能修改它的值;
2.String类是final类型不可被继承;
StringBuffer的特点:
1.它是一个可变的对象,当你需要修改其内容的时候,可以通过调用其方法进行修改。
2.不能通过赋值符号对他进行赋值.。
3.字符串连接操作中StringBuffer的效率要比String高
比较字符串:
String值比较:{
int compareTo(String anotherString)
boolean equals(Object anObject) 重写equals方法,是值比较
{
{ String s1="Hello!World";
String s2="Hello!World";
boolean b1=s1.equals(s2); true
boolean b2=(s1==s2); true,Java存储优化策略,字符串常量只存储一份
}
{ String s1="Hello!World";
String s2=new String("Hello!World"); 创建一个新字符串
boolean b1=s1.equals(s2); true
boolean b2=(s1==s2); false
}
}
boolean equalsIgnoreCase(String anotherString)}
引用比较:“==”
StringBuffer:继承的Object的equals方法,引用比较
split分离字符串:{
格式:public String[] split(String regex) ;
str="boo:and:foo:bye";str.split(":")的结果为:{ "boo", "and", "foo" , "bye" }
注意,参数串代表一个正则表达式的匹配模式,分隔符如果是+、*等符号时,要进行转义处理,例如分隔符为“+”,要写成"\\+"的正则式。
String x= "1+2+4+5+8"; x.split(" \\+ ")的结果为{" 1 ", " 2 ", " 4 ", " 5 ", " 8" }
应用:
String str = "Java is an Object Oriented programming language";
String[] str2 = str.split(" "); //以空格为分隔符分离字符串
}
写程序的运行结果{
public class Foo {
public static void main (String [ ] args) {
StringBuffer a = new StringBuffer("A");
StringBuffer b = new StringBuffer("B");
operate(a,b);
System.out.println(a + "," +b);
}
static void operate (StringBuffer x, StringBuffer y) {
x.append(y);
y = x;
}
}
运行结果:AB,B
public class Foo {
public static void main (String [ ] args) {
String a = new String("A");
String b = new String("B");
operate(a,b);
System.out.println(a + "," +b);
}
static void operate (String x, String y) {
x=x+y;
y = x;
}
}
运行结果:A,B}
4. 基本类类型和包装类有什么关系?包装类和基本数据类型之间有什么区别?
1、声明方式不同
基本类型不适用new关键字,而包装类型需要使用new关键字来在堆中分配存储空间;
2、存储方式及位置不同
基本类型是直接将变量值存储在堆栈中,而包装类型是将对象放在堆中,然后通过引用来使用;
3、初始值不同
基本类型的初始值如int为0,boolean为false,而包装类型的初始值为null
4、使用方式不同
基本类型直接赋值直接使用就好,而包装类型在集合如Collection、Map时会使用到。
5、包装类都是继承Number 接口实现Compareble 接口的
包装类优点:
提供了一系列实用的方法
集合不允许存放基本数据类型数据,存放数字时,要用包装类型
包装类缺点:
由于每个值分别包装在对象中,所以ArrayList<Integer>的效率远远低于int[]数组。(应该用其构造小型集合,其原因是程序员操作的方便性要比执行效率更加重要)
补充:
1、int 类型不能赋值为null(默认值为0),包装类型Integer可以为null(默认值为null)
2、当int中的数值 与 integer 中的数值一致的时候, 使用 “==” 进行比较,结果为true
3、如果两个都是new的Integer相比较也是相等的
5. 为什么要使用包装类?
我们知道Java是一个面相对象的编程语言,基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,
就出现了包装类型(如我们在使用集合类型Collection时就一定要使用包装类型而非基本类型),它相当于将基本类型“包装起来”,
使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。
另外,当需要往ArrayList,HashMap中放东西时,像int,double这种基本类型是放不进去的,
因为容器都是装object的,这是就需要这些基本类型的包装器类了。
1、int转Integer
int i = 0;
Integer ii = new Integer(i);
2、Integer转int
Integer ii = new Integer(0);
int i = ii.intValue();
https://www.yuque.com/shaonian-8joxb/pvi3zw/qipn34#qbimZ
抽象类abstract通过继承实现extends
格式:abstract class 类名称 {
成员变量;
方法(){……} //一般方法
abstract 方法(); //抽象方法
}
abstract class Shape { //定义抽象类
abstract public double area(); //抽象方法
}
class Triangle extends Shape { //定义三角型
private double a, b, c;
public Triangle(double a, double b, double c) {
this.a = a;
this.b = b;
this.c = c;
}
public double area(){
double p = (a + b +c) / 2;
return Math.sqrt(p * (p - a) * (p- b) * (p- c));
}
}
● 在抽象类中可以包含一般方法和抽象方法。
● 抽象类表示的是一个抽象概念,不能被实例化为对象。
● 抽象类具体应用时需要继承。
● 继承后抽象类的方法都必须全部实现。
接口interface通过implements实现
格式:[public] interface 接口名 [extends 父接口名列表] {
[public] [static] [final] 域类型 域名 = 常量值 ;
[public] [abstract] 返回值 方法名(参数列表) [throw 异常列表];//别忘了默认也是这些修饰!
}
interface Copyable {
//[public] Object copy ();默认为public
Object copy ();
}
class Book implements Copyable {
String book_name; // 书名
String book_id; // 书号
public Book(String name ,String id) {
book_name = name;
book_id = id;
}
public Object copy () { //public 一定要!
//这里是否可为Book类型?返回值为子类Book时,可改为Book
return new Book(book_name , book_id);
}
//实现接口的类要将接口带来的抽象方法覆盖!
…
public String toString(){
return super.toString()+" ,书名:"+book_name+",书号="+book_id;
}
}
● 声明接口可给出访问控制符;
● 一个接口还可以继承多个父接口,父接口间用逗号分隔。
● 系统默认接口中所有属性的修饰都是public static final;
● 系统默认接口中所有方法的修饰都是public abstract。
● ● ● 一个类可以实现多个接口。在类的声明部分用implements关键字声明该类将要实现的接口,接口间用逗号分隔;
● 如果实现某接口的类不是抽象类,则该类必须实现指定接口的所有抽象方法;
● ● ● 接口的抽象方法的访问限制符默认为 public,在实现时要在方法头中显式地加上public修饰。
1、的输入输出类:
InputStream OutputStream 面向字节,处理非文本文件
Reader Writer 面向字符
File
2、步骤:
1. 创建流对象
2. 用方法从流输入数据
3. close( )关闭流
3、面向字节{
public int read() :读一个字节
1.
FileInputStream infile = new FileInputStream(args[0]);
int byteRead = infile.read(); 以字节为单位访问
while (byteRead!=-1) {
System.out.print((char)byteRead);
byteRead = infile.read();
}
2.
FileInputStream infile = new FileInputStream(args[0]); 从命令行获取要显示的文件名
BufferedInputStream buin=new BufferedInputStream(infile); 创建输入流
byte[] buffer=new byte[64];
int byteRead = buin.read(buffer);
while (byteRead!=-1)
{ //判断是否读到文件的末尾
String str=new String(buffer,0,byteRead); 读取的字节转换为字符
System.out.print(str);
//System.out.print((char)byteRead);
byteRead = buin.read(buffer); read()方法读到文件结尾返回-1,读取文件时一个一个字节读入
}
buin.close();
输出:
1.
FileOutputStream file = new FileOutputStream("x.dat"); 创建一个文件输出流,文件不存在则自动生成
DataOutputStream out=new DataOutputStream(file); 对FileOutputStream包装,创建一个DataOutputStream流,利用该流向文件写入各种类型的数据
out.writeInt(n); DataOutputStream的writeInt方法,写入整数
out.close();
}
4、面向字符{
1.
LineNumberReader in=new LineNumberReader(new FileReader("AddLineNo.java")); 从一个文本文件中读取数据加上行号后显示
String x= in.readLine(); 利用LineNumberReader的readLine()方法从文件逐行读取,末尾返回null
2.
FileReader in = new FileReader("test13_4.java"); (单个字符读)
int charRead = in.read();
System.out.print((char) charRead);
3.
BufferedReader in = new BufferedReader(new FileReader("test13_4.java"));
String x = in.readLine();
输出
1.
FileWriter out=new FileWriter("charset.txt ");
for(int i=32;i<126;i++)
//.write(i); 输出乱码
out.write(Integer.toString(i)); 整型数字转换为字符串
读入并加上行号输出:{
FileReader file= new FileReader("AddLineNo.java");
FileWriter out=new FileWriter("target.txt");
LineNumberReader in=new LineNumberReader(file);
while (true)
{
String x= in.readLine();
if (x == null)
break;
else
out.write(in.getLineNumber()+":"+x+"\r\n");
}
out.close();
}
}
5、随机文件读写{
BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); 输入框输入
String s=in.readLine();
RandomAccessFile out=new RandomAccessFile(“java.log”,”rw”);
out.seek(myFile.length()); //将指针定到文件尾
out.writeBytes(s+”\n”); //写入数据
out.close();
}
6、对象串行化 ObjectOutputStream && ObjectInputStream {
1、写入文件
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("storedate.dat"));
out.writeObject(new Date());
out.writeObject("hello world");
System.out.println("写入完毕");
2、读文件并显示
ObjectInputStream in=new ObjectInputStream(new FileInputStream("storedate.dat"));
Date current=(Date)in.readObject();
System.out.println("日期:"+current);
String str=(String)in.readObject();
System.out.println("字符串:"+str);
}