java-day27
目录
3、基本类型和包装类型之间的自动装箱和拆箱(jdk1.5以后)
4、Integer类的静态内部类IntegerCache[缓存机制]
实例
1、常规实现
package com.zzb.day27;
//迭代器接口
public interface Iterator{
boolean hasNext();
String next();
}
class StringIterator implements Iterator{
//要和一个仓库捆绑起来,还要知道迭代器访问的位置
private Repository rep;
private int index = -1;
public StringIterator(Repository rep){
this.rep = rep;
}
public boolean hasNext(){
index++;
if(index<rep.size()){
return true;
}else
return false;
}
//获取当前索引数据
public String next(){
return rep.get(index);
}
}
package com.zzb.day27;
import java.util.Arrays;
//仓库类型
public interface Repository{
//往仓库中添加数据
void add(String data);
//返回当前仓库中已经存放了多少数据
int size();
//返回针对当前仓库的迭代器
//这个迭代器可以帮我们从仓库中取出一个个数据
Iterator getIterator();
String get(int index);
}
class StringRepository implements Repository{
//数组,用来保存数据
private String[] db;
//当前仓库存放数据的数量
private int size;
//当前类中,初始化数组使用的默认长度
private static final int DEFAULT_ARRAY_LENGTH = 5;
public StringRepository(){
db = new String[DEFAULT_ARRAY_LENGTH];
}
public void add(String data){
//仓库容量已满,要进行扩展
if(size==maxLength()){
System.out.println("当前仓库已满,不能再存数据");
db = Arrays.copyOf(db,maxLength()*2);
}
db[size++] = data;
}
public int size(){
return this.size;
}
public Iterator getIterator(){
return new StringIterator(this);
}
private int maxLength(){
return db.length;
}
public String get(int index){
return db[index];
}
}
2、用内部类实现
package com.zzb.day27;
//迭代器接口
public interface Iterator{
boolean hasNext();
String next();
}
package com.zzb.day27;
import java.util.Arrays;
import java.util.Arrays;
//仓库类型
public interface Repository{
//往仓库中添加数据
void add(String data);
//返回当前仓库中已经存放了多少数据
int size();
//返回针对当前仓库的迭代器
//这个迭代器可以帮我们从仓库中取出一个个数据
Iterator getIterator();
}
class StringRepository implements Repository{
//数组,用来保存数据
private String[] db;
//当前仓库存放数据的数量
private int size;
//当前类中,初始化数组使用的默认长度
private static final int DEFAULT_ARRAY_LENGTH = 5;
public StringRepository(){
db = new String[DEFAULT_ARRAY_LENGTH];
}
public void add(String data){
//仓库容量已满,要进行扩展
if(size==maxLength()){
System.out.println("当前仓库已满,要扩展");
db = Arrays.copyOf(db,maxLength()*2);
}
db[size++] = data;
}
public int size(){
return this.size;
}
public Iterator getIterator(){
return new It();
}
private int maxLength(){
return db.length;
}
private class It implements Iterator{
private int index = -1;
public boolean hasNext(){
index++;
if(index<size){
return true;
}
else return false;
}
//获取当前索引数据
public String next(){
return db[index];
}
}
}
测试类
package com.zzb.day27;
//一个仓库类型
//一个迭代器类型
public class RepositoryTest{
public static void main(String[] args){
Repository rep = new StringRepository();
rep.add("hello1");
rep.add("hello2");
rep.add("hello3");
rep.add("hello4");
rep.add("hello5");
rep.add("hello6");
rep.add("hello7");
rep.add("hello8");
rep.add("hello9");
int size = rep.size();
System.out.println("size = "+size);
Iterator it = rep.getIterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
包装类型
在java中, 有八种基本的数据类型,这八种基本类型只能表示一些最简单的数字,这些数字最小的在内存中占8位,最大占64位。这些都是简单的数字,不是对象,所以也不能用来调用方法或者属性。
在java的API中,对这八种基本类型,又专门提供了类类型,目的就是为了分别把这八种基本类型的数据,包装成对应的类类型,这时候就变成对象了,就可以调用方法了或者访问属性了。
基本类型 | 包装类型 |
---|---|
boolean | Boolean |
byte | Byte |
short | Short |
char | Character |
int | Integer |
long | Long |
float | Float |
double | Double |
1、这些包装类型都在java.lang下
可以直接使用不需要导入
2、这些包装类型都定义了相关属性和方法
包装类的使用
public class WrapperClass{
public static void main(String [] args){
WrapperClass q = new WrapperClass();
q.test1();
}
public void test1(){
int i = 10;
Integer o = new Integer(i);
System.out.println(o.toString(o));
System.out.println(o.toString(o,2));
System.out.println(o.toString(o,8));
System.out.println(o.toString(o,16));
}
}
3、基本类型和包装类型之间的自动装箱和拆箱(jdk1.5以后)
老版本
//int-----> Integer
Integer i = new Integer(1);
//Integer----->int
int j = i.intValue();
新版本
//int-----> Integer
Integer o = 1;
System.out.println(o);
//Integer----->int
int i= o;
System.out.println(i);
4、Integer类的静态内部类IntegerCache[缓存机制]
这静态内部类的作用是帮Integer类,把一些常用的数字所包装成的对象给缓存起来。[-128,127]
private static class IntegerCache{
static final int low = -128;
static final int high;
static final Integer[] cache;
static {
int i = 127;
String str = VM.getSavedProperty
("java.lang.Integer.IntegerCache.high");
if (str != null) {
try {
int j = Integer.parseInt(str);
j = Math.max(j, 127);
i = Math.min(j, 2147483518);
} catch (NumberFormatException numberFormatException) {}
}
high = i;
cache = new Integer[high - -128 + 1];
byte b = -128;
for (byte b1 = 0; b1 < cache.length; b1++) {
cache[b1] = new Integer(b++);
}
assert high >= 127;
}
}
public static Integer valueOf(int paramInt) {
if (paramInt >= -128 && paramInt <= IntegerCache.high)
return IntegerCache.cache[paramInt + 128];
return new Integer(paramInt);
}
5、一些容易出错的地方
pub1ic void test1(int i){}
public void test2(Integer i){}
public void test3(long i){}
public void test4(Long i){}
main :
t. test1(1);//编译通过int i = 1; 正常赋值
t.test2(1);//编译通过Integer i = 1; 自动装箱
t.test3(1);//编译通过1ong i = 1; 隐式类型转换
t. test4(1);//编译报错Long i = 1; int和Long之间没有任何关系
t.test4(1L)//编译通过 自动装箱
== 和 equals方法的区别
==
能用在基本类型数据之间,也可以用作引用类型的对象之间
如果是俩个基本类型数字相比, == 比较是基本类型的俩个数值是否相等 如果是俩个引用类型的变量相比,==比较是俩个引用所指向对象的内存地址值是否相等 另外,==是java中的基本的操作符,我们无法改变==号的默认的比较方式。
equals
只能用在俩个引用类型的对象之间,这个方法是0bject中定义的,所以对象直接或间接继承object 类之后,都可以使用这个继承过来的equals方法。
在0bject中,equals方 法默认实现是这样的:
public boolean equals(bject obj) {
return (this == obj);
}
那么就是意味着,如果调用的equlas方法是从父类0bject中继承过来的(没有重写),那么这比较也是借助于==来比较俩个引用所指向的对象的内存地址值是否相等。
如果我们想通过自己的方法重新定义两个对象相等值的判断,我们在子类中可以重写equals方法。
实例
编写一个学生类,有id、name、age属性,创建俩个学生对象比较,它们是否相等,使用==号进行比较,使用从父类Object继承过来方法equals比较,使用自己重写后的equals进行比较。分别观察几种方式比较后的结果有什么不同。
public class Test{
public static void main(String[] args){
Student s1 = new Student(001L,"zs",12);
Student s2 = new Student(001L,"zs",12);
System.out.println(s1.equals(s2));
}
}
class Student{
private long id;
private String name;
private int age;
public Student(){
}
public Student(long id,String name,int age){
this.id = id;
this.name = name;
this.age = age;
}
public boolean equals(Student s){
return (this.id == s.id)&&
this.name.equals(s.name)&&
(this.age == s.age);
}
}