JAVA——集合(四)

集合知识汇总

1:String类:字符串(重点)

(1)多个字符组成的一个序列,叫字符串。
生活中很多数据的描述都采用的是字符串的。而且我们还会对其进行操作。
所以,java就提供了这样的一个类供我们使用。

(2)创建字符串对象
A:String():无参构造
**举例:
String s = new String();
s = “hello”;
sop(s);

B:String(byte[] bys):传一个字节数组作为参数 *
**举例
byte[] bys = {97,98,99,100,101};
String s = new String(bys);
sop(s);

C:String(byte[] bys,int index,int length):把字节数组的一部分转换成一个字符串 *
**举例
byte[] bys = {97,98,99,100,101};
String s = new String(bys,1,2);
sop(s);

D:String(char[] chs):传一个字符数组作为参数 *
**举例
char[] chs = {‘a’,’b’,’c’,’d’,’e’};
String s = new String(chs);
sop(s);

E:String(char[] chs,int index,int length):把字符数组的一部分转换成一个字符串 *
**举例
char[] chs = {‘a’,’b’,’c’,’d’,’e’};
String s = new String(chs,1,2);
sop(s);

F:String(String str):把一个字符串传递过来作为参数
char[] chs = {‘a’,’b’,’c’,’d’,’e’};
String ss = new String(s);
sop(ss);

G:直接把字符串常量赋值给字符串引用对象(最常用) *
**举例
String s = “hello”;
sop(s);

(3)面试题
A:请问String s = new String(“hello”);创建了几个对象。
两个。一个”hello”字符串对象,在方法区的常量池;一个s对象,在栈内存。

B:请写出下面的结果
String s1 = new String(“abc”);
Strign s2 = new String(“abc”);
String s3 = “abc”;
String s4 = “abc”;

sop(s1== s2); //false
sop(s1 == s3); //false
sop(s3 == s4); //true

C:字符串对象一旦被创建就不能被改变。
指的是字符串常量值不改变

(4)字符串中各种功能的方法
A:判断
**** boolean equals(Object anObject):判断两个字符串的内容是否相同,复写了Object的方法
**** boolean equalsIgnoreCase(String anotherString):判断两个字符串的内容是否相同,
不区分大小写
**** boolean contains(String s):判断一个字符串中是否包含另一个字符串
注意:判断字符串是否包含特殊字符.直接表示为str.contains(".")
boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
boolean startsWith(String suffix):测试此字符串是否以指定的前缀开始
boolean isEmpty():测试字符串是否为空

B:获取
***** int length():返回此字符串的长度
***** char charAt(int index):返回指定索引处的 char值
***** int indexOf(int ch):返回指定字符在此字符串中第一次出现处的索引。
int indexOf(int ch, int fromIndex):返回在此字符串中第一次出现指定字符处的索引,
从指定的索引开始搜索。
int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引。
int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次
出现处的索引,从指定的索引开始。
*** int lastIndexOf(int ch):返回指定字符在此字符串中最后一次出现处的索引。
int lastIndexOf(int ch, int fromIndex)
返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引。
int lastIndexOf(String str, int fromIndex)
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
***** String substring(int beginIndex) (注意:该方法substring的String是小写!!!)
返回一个新的字符串,它是此字符串的一个子字符串。
String substring(int beginIndex, int endIndex) (注意该方法的String是小写!!!)
返回一个新字符串,它是此字符串的一个子字符串,包含头不包含尾。

C:转换
***** byte[] getBytes():(很常用!)从字符串到字节数组的方法
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
将字符从此字符串复制到目标字符数组。
***** char[] toCharArray():(很常用!)从字符串到字符数组的方法
**** static String copyValueOf(char[] data)
返回指定数组中表示该字符序列的 String。
static String copyValueOf(char[] data, int offset, int count)
返回指定数组中表示该字符序列的 String。
***** static String valueOf(数据类型):把该数据类型的数据转换成字符串。
*** String toLowerCase():把字符串转换成小写
String toUpperCase():把字符串转换成大写
*** 字符串的连接
String concat(String str):将指定字符串连接到此字符串的结尾。

D:替换
String replace(char oldChar, char newChar):用新字符替换旧字符(替换所有)
String replace(String target, String replacement):用新的子串换旧串

E:分割
String[] split(String regex):根据指定的字符串把一个字符串分割成一个字符串数组

F:
String trim():去除字符串的前后空格

G:
int compareTo(String anotherString)
按字典顺序比较两个字符串。
int compareToIgnoreCase(String str)
按字典顺序比较两个字符串,不考虑大小写。

(5)练习
1:模拟登录,给三次机会,并提示还有几次.
默认的用户名和密码为admin。 区分大小写。
自己从键盘输入用户名和密码。

2:给定一个字符串统计,统计大写字母,小写字母,数字出现的个数.
***注意:不包括特殊字符
从键盘输入一个不包含特殊字符的字符串(只有26个字母和0-9组成)。

3:给定一个字符串,把它变成首字母大写,其他字母小写的字符串.
从键盘输入一个字符串,全部26个字母组成的。

4:子串在整串中出现的次数。
也就是说:获取一个字符串中,指定的字串在该字符串中出现的次数.
例如:
“nbasdnbafllgnbahjnbakqqqqlnba” 在这个字符串中,多有个nba.

5:对字符串中字符进行自然顺序排序。
“basckd”–>“abcdks”

先留做思考内容:

6:两个字符串的最大相同子串。
两个字符串的最大相同子串。
比如:
“sadabcdfghjkl”
werabcdtyu"

2:StringBuffer
(1)字符串的缓冲区,是一个容器。
(2)它和String的区别
它是缓冲区可变长度的。
(3)构造方法
StringBuffer() 构造一个其中不带字符的字符串缓冲区,初始容量为 16 个字符。
StringBuffer(int num) 构造一个不带字符,但具有指定初始容量的字符串缓冲区。
StringBuffer(String str) 构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。
(4)常用方法
A:增加数据
**append :添加各种类型的数据
**insert : 在容器指定位置插入各种类型的数据。

B:删除数据
**deleteCharAt : 删除指定位置的字符
**delete 还可以用于清空StringBuffer的缓冲区

C:替换
**replace

D:获取
**charAt

E:长度和容量
**length() 元素的个数
**capacity 元素的理论值

F:获取元素的位置
**indexOf
**lastIndexOf

G:截取
**substring(int start)
**substring(int start,int end)

H:反转
**reverse

(5)字符串和StringBuffer的转换
String–>StringBuffer通过构造:
如:StringBuffer sb = new StringBuffer(String str)
StringBuffer–String通过toString方法
如:StringBuffer sb = new StringBuffer();
sb.toString();

3:StringBuilder
和StringBuffer的功能是一样的,但是有区别:
StringBuffer(JDK1.0)是线程安全的。
StringBuilder(JDK1.5)不保证线程安全。

一般来说,我们写的程序都是单线程的,所以,用StringBuilder,效率高。

JDK版本的升级原则:
A:提高效率
B:提高安全性
C:简化书写

4:基本数据类型的对象包装类
(1)为了更方便的操作每个基本数据类型,java对其提供了很多的属性和方法供我们使用。

(2)用途:
**将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能操作该数据。
**常用的操作之一:用于基本数据类型与字符串之间的转换。
A:方便操作
B:用于和字符串进行相互转换

(3)基本数据类型和对象类型的对应
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character

(4)构造方法

字段摘要:
static int MAX_VALUE 值为 2^31-1 的常量,它表示 int 类型能够表示的最大值
static int MIN_VALUE 值为 -2^31 的常量,它表示 int 类型能够表示的最小值
static Class TYPE 表示基本类型int的Class 实例

Integer(int value) 构造一个新分配的Integer对象,它表示指定的int值。
Inreger(String s) 注意:s必须是纯数字的字符串。否则会有异常NumberFormatException

(5)几个常用的方法
Integer.toBinaryString();
以二进制(基数 2)无符号整数形式返回一个整数参数的字符串表示形式。
Integer.toOctalString();
以八进制(基数 8)无符号整数形式返回一个整数参数的字符串表示形式。
Integer.toHexString();
以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式。
static int Integer.parseInt(String s) 将字符串参数作为有符号的十进制整数进行解析,
字符串必须是int型范围内的数字字符串
static int Integer.parseInt(String s,int basic)
使用第二个参数指定的基数,将字符串参数解析为有符号的整数.
字符串必须是int型范围内的数字字符串
short shortValue() 以short类型返回该Integer的值。
int intValue() 以int类型返回该Integer的值。
static Integer valueOf(int num) 返回一个表示指定的 int 值的 Integer 实例。
static Integer valueOf(String s) 返回保存指定的String的值的Integer对象。
static Integer valueOf(String s, int radix)
返回一个Integer对象,该对象中保存了用第二个参数提供的基数进行
解析时从指定的String中提取的值。

(6)类型转换
int – Integer
int num = 20;
A:Integer i = new Integer(num);
B:Integer i = Integer.valueOf(num);
Integer – int
Integer i = new Integer(20);
A:int num = i.intValue();

int – String
int num = 20;
A:String s = String.valueOf(num);
B:String s = “”+num;
C:String s = Integer.toString(num);
String – int
String s = “20”;
A:int num = Integer.parseInt(s);
B:Integer i = new Integer(s);或者Integer i = Integer.valueOf(s);
int num = i.intValue();

6、集合框架:
(1)为什么出现集合类?
面向对象对事物的体现都是以对象的形式,为了方便对多个对象的操作,就对对象进行存储。
集合就是存储对象最常用的一种方式.

(2)数组和集合都是容器,两者有何不同?
**数组长度固定,而集合长度是可变的
**数组值可以存储对象,还可以存储基本数据类型;而集合只能存储对象
**数组存储数据类型是固定的,而集合存储的数据类型不固定

(3)集合类的特点:
集合只能存储对象
集合的长度是可变的
集合可以存储不同类型的对象

(4)集合类框架(重要!!!要分清几种容器间的区别):
**Collection:顶层接口
|—>List:列表,元素是有序的(元素带角标索引),可以有重复元素,可以有null元素。
|—>ArrayList(JDK1.2):底层的数据结构是数组数据结构,特点是查询速度快(因为带角标),
但是增删速度稍慢,因为当元素多时,增删一个元素则所有元素的角标都得改变
线程不同步。默认长度是10,当超过长度时,按50%延长集合长度。
|—>LinkedList(JDK1.2):底层数据结构式链表数据结构(即后面一个元素记录前一个),
特点:查询速度慢,因为每个元素只知道前面一个元素,但增删速度快
因为元素再多,增删一个,只要让其前后的元素重新相连即可
线程是不同步的。
|—>Vector(JDK1.0):底层数据结构是数组数据结构.特点是查询和增删速度都很慢。
默认长度是10,当超过长度时,按100%延长集合长度。
线程同步。
(Vector功能跟ArrayList功能一模一样,已被ArrayList替代)

**List使用注意!
|—>ArrayList:
(1)当往ArrayList里面存入元素没什么要求时,即只要求有序就行时;

(2)当往ArrayList里面存入元素要求不重复时,比如存入学生对象,当同名同姓时
视为同一个人,则不往里面存储。则定义学生对象时,需复写equals方法
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
return false;
Student stu = (Student)obj;
return this.name.equals(stu.name)&&this.age==stu.age;
}

则往ArrayList集合通过add存入学生对象时,集合底层自己会调用学生类的equals方法,
判断重复学生则不存入。
注:对于List集合,无论是add、contains、还是remove方法,判断元素是否相同,
都是通过复写equals方法来判断!

|—>LinkedList
(1)LinkLedist的特有方法:
boolean offerFirst(E e) 在此列表的开头插入指定的元素。
boolean offerLast(E e) 在此列表末尾插入指定的元素。
E peekFirst() 获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
E peekLast() 获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。
E pollFirst() 获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
E pollLast() 获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。

(2)通过LinkLedist的特有方法,可以实现某些数据特殊方式的存取,比如堆栈和队列。
一般情况下,使用哪种List接口下的实现类呢?
如果要求增删快,考虑使用LinkedList
如果要求查询快,考虑使用ArrayList
如果要求线程安全,考虑使用Vector。

|—>Set:集合,元素是无序的(因为没有索引),元素不可以重复。可以有null元素。
|—>HashSet(JDK1.2):底层数据结构是哈希表、存取速度快、元素唯一、线程不同步。
保证性元素唯一的原理:
先判断元素的hashCode值是否相同,再判断两元素的equals方法是否为true
(往HashSet里面存的自定义元素要复写hashCode和equals方法,
以保证元素的唯一性!)
|—>TreeSet:底层数据结构式二叉树。可以对Set集合中的元素进行排序。元素有序、线程不同步。
保证元素唯一性的依据:compareTo方法return 0
TreeSet排序的第一种方式:让元素自身具备比较性,比如八种基本数据类型或则字符串,
实现Compareble接口,覆盖compareTo方法,
此方式是元素的自然顺序
TreeSet排序的第一种方式:当元素自身不具备比较性(比如存储学生对象时)或者具备的
比较性不是我们所需要的比较性时(比如想字符串的长度排序),
此时就需要让集合自身具备自定义的比较性。
那如何让集合自身具备比较性呢?可在集合初始化时,
就让集合具备比较方式。即定义一个类,
实现Comparator接口,覆盖compare方法。

**Set集合使用注意事项:
(1)HashSet:
通过new的方式往HashSet里面存的元素的hashCode都不同,但通常我们定义对象,
比如学生对象时,虽然是new的两个学生对象,但是当他们name和age一样时,我们认为是
同一个对象,所以为了保证元素的唯一性,我们通常在往HashSet集合里面存储元素时,
在定义对象的类中通常复写hashCode和equals方法。

          public int hashCode()
              {
            return name.hashCode()+age*39;
              }
              public boolean equals(Object obj)
              {
            if(!(obj instanceof Student))
                return false;
            Student stu = (Student)obj;
            return this.name.equals(stu.name)&&this.age==stu.age;
              }

HashSet是如何保证元素唯一性的呢?
**如果两元素的hashCode值不同,则不会调用equals方法
**如果两元素的hashCode值相同,则继续判断equals是否返回true;
**hashCode和equals方法虽然定义在自定义对象类里面,但不是我们手动调用
而是往HashSet集合里面存储元素的时候,集合底层自己调用hashCode和equals
它自己拿对象去判断,自己判断两元素是否是同一个元素。

(2)TreeSet:
TreeSet要求往里面存的元素具备比较性,否则会报错。
TreeSet排序的第一种方式:让元素自身具备比较性
定义对象类,实现Compareble接口,复写compareTo方法,此方式是元素的自然顺序

              class Student implements Comparable
              {
                private String name;
                private int age;
                public Student(String name,int age)
                {
                    this.name=name;
                    this.age=age;
                }
                public String getName()
                {
                    return name;
                }
                public int getAge()
                {
                    return age;
                }
                public int compareTo(Object obj)
                {
                    if(!(obj instanceof Student))
                        throw new RuntimeException("不是学生对象!");
                    Student stu = (Student)obj;
                    int num = this.age-stu.age;
                    if(num==0)
                        return this.name.compareTo(stu.name);
                    return num;
                }
              }

TreeSet排序的第一种方式:让集合具备比较性
当元素自身不具备比较性(比如存储学生对象时)或者具备的
比较性不是我们所需要的比较性时(比如想字符串的长度排序),
此时就需要让集合自身具备自定义的比较性。
那如何让集合自身具备比较性呢?可在集合初始化时,
就让集合具备比较方式。即定义一个类,
实现Comparator接口,覆盖compare方法。

             class StringLengthComparator implements Comparator
             {
                public int compare(Object obj1,Object obj2)
                {
                    String s1 = (String)obj1;
                    String s2 = (String)obj2;
                    int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
                    if(num==0)
                        return s1.compareTo(s2);
                    return num;
                }
             }
             class TreeSetTest
             {
                public static void main(String[] args)
                {
                    TreeSet ts = new TreeSet(new StringLengthComparator());
                    ts.add("addfg");
                    ts.add("dfg");
                    ts.add("agtuug");
                    ts.add("vgjkg");
                    sop(ts);
                }
             }

基本数据类型或字符串对象均实现了Comparable接口,故同种类型基本数据间具备比较性,即自然顺序。

**Map:顶层接口,该集合存储的是键值对,而且键是唯一的,Map和Set很像,Set集合底层就是使用了Map集合。
Map集合没有迭代器,要取出元素必须先将Map集合转换成Set集合才能遍历元素
|—>HashTable(JDK1.0):
底层是哈希表数据结构;
不可以使用null键和null值;
用作键的对象必须实现hashCode和equals方法来保证键的唯一性
线程同步,效率低
|—>HashMap(JDK1.2):
底层是哈希表数据结构;
允许使用null键和null值;
线程不同步,效率高;
保证元素唯一性的:
原理:先判断元素的hashCode值是否相同,再判断两元素的equals方法是否为true
(往HashSet里面存的自定义元素要复写hashCode和equals方法,
以保证元素的唯一性!)

    class Student {
        private String name;
        private int age;
        public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public int hashCode(){
            return name.hashCode()+age*34;
        }
        @Override
        public boolean equals(Object obj){

            if(!(obj instanceof Student))
                return false;
            Student stu = (Student)obj;
            return this.name.equals(stu.name)&&this.age==stu.age;
        }
        
    public class HashMapDemo1 {
        public static void main(String[] args) {
            Map<Student , String> hmap = new HashMap<Student , String>();
            hmap.put(new Student("001",20), "beijing");
            hmap.put(new Student("002",25), "hebei");
            hmap.put(new Student("003",50), "hainan");
            hmap.put(new Student("001",20), "beijing");

            System.out.println(hmap.size());
            Set<Student> keySet = hmap.keySet();
            Iterator<Student> it = keySet.iterator();
            while(it.hasNext()){
                Student stu = it.next();
                String addr = hmap.get(stu);
                System.out.println(stu.getName()+".."+stu.getAge()+"::"+addr);
            }   
        }   
    }   

|—>TreeMap(JDK1.0):
底层是二叉树结构;
允许使用null键和null值;
线程不同步;
可以给Map集合中的键进行排序.
TreeMap排序的第一种方式:让元素自身具备比较性,比如八种基本数据类型或则字符串,
实现Compareble接口,覆盖compareTo方法,
此方式是元素的自然顺序
TreeMap排序的第一种方式:当元素自身不具备比较性(比如存储学生对象时)或者具备的
比较性不是我们所需要的比较性时(比如想字符串的长度排序),
此时就需要让集合自身具备自定义的比较性。
那如何让集合自身具备比较性呢?可在集合初始化时,
就让集合具备比较方式。即定义一个类,
实现Comparator接口,覆盖compare方法。

    class Student implements Comparable<Student>{
        private String name;
        private int age;
        public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public int compareTo(Student stu) {
            int num = new   Integer(this.age).compareTo(new Integer(stu.age));
            if(num==0)
                return this.name.compareTo(stu.name);
            return num;
        }           
    }

    public class HashMapDemo1 {
        public static void main(String[] args) {

            Map<Student , String> tmap = new TreeMap<Student , String>();
            tmap.put(new Student("001",20), "beijing");
            tmap.put(new Student("002",25), "hebei");
            tmap.put(new Student("003",50), "hainan");
            tmap.put(new Student("001",20), "beijing");

            System.out.println(tmap.size());
            Set<Student> keySet1 = tmap.keySet();
            Iterator<Student> it1 = keySet1.iterator();
            while(it1.hasNext()){
                Student stu = it1.next();
                String addr = tmap.get(stu);
                System.out.println(stu.getName()+".."+stu.getAge()+"::"+addr);      
            }
        }
    }

**Iterator:对collection进行迭代的迭代器.迭代器取代了Enumeration。
迭代器和枚举的区别:
迭代器允许调用者利用定义良好的语义在迭代期间从迭代器所指向的collection移除元素
方法名称得到了改进,简化书写
**LisIterator:系列表迭代器,允许程序员按任一方向遍历列表、迭代期间修改列表
**Comparable:此接口强行对实现它的每个类的对象进行整体自然排序。使元素具备比较性
**Comparator:强行对某个对象collection进行整体排序的比较函数,使集合具备比较性
**Collections:此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。
**Arrays:此类包含用来操作数组(比如排序和搜索)的各种静态方法

7、集合类各容器方法:
**接口Collection方法摘要(没有构造方法)

a)添加:
i. boolean add(E e)
j. boolean addAll(Collection c)

b)删除:
i. void clear():清空容器
j. boolean remove(Objec object):
k. boolean removeAll(Collection c):

c)判断:
i. boolean contains(Object object):判断是否包含此元素
j. boolean containsAll(Collection c):判断是否包含一堆元素
k. boolean equals(Object object):比较此collection与指定对象是否相等
m. boolean isEmpty():判断是否集合为空

d)获取:
h. Iterator iterator():取出
i. int hashCode():返回此collection的哈希值
j. int size():返回此collection中元素的个数
k. boolean retainAll(Collection c):取交集
m. Object toArray():返回此collection中所有元素的数组
n. T[] toArray(T[] a):返回包含此collection中所有元素的数值。
*****List集合子类及其方法

(1)List接口是Collection接口的一个子接口。
(2)List接口中的元素有如下特点(对角标的操作都是特有方法,因为有序):
A:元素有序(存储顺序和取出顺序一致)
B:元素可以重复
(3)List接口中的特有方法
A:add(int index,Object obj):在指定位置加入元素
B:remove(int index):移除指定位置的元素
C:set(int index,Object obj):修改指定位置的元素
D:get(int index):获取指定位置的元素
E:indexOf(Object obj):获取指定元素的位置
F:subList(int start,int end):从一个大的List中截取一个小的List
G:listIterator():返回一个List接口特有的迭代器
(1)、ArrayList:
|—>构造方法摘要:(少用,不是重点)
ArrayList():构造一个初始容量为 10 的空列表。
ArrayList(Collection

public static int add(int x,int ...args) {
            int sum = x;
            for(int arg:args) {
                sum += arg;
            }
            return sum;
        }

**增强for循环代替了迭代器使用的不爽,简化书写
**增强for循环局限性:
    对集合或者数组进行遍历时,只能取元素,不能对集合进行操作

(4)基本数据类型的自动装箱和拆箱
**基本数据类型
byte —> Byte
short —> Short
int —> Integer
long —> Long
float —> Float
double —> Double
char —> Character
boolean —> Boolean
**例子:
**装箱:自动把一个基本数据类型的数据装箱成一个该类型数据的对象引用
Integer i = 3;(jdk1.5之前这样写是不行的,编译报错)
**拆箱:自动把一个基本数据类型的对象引用拆箱成一个基本数据类型的数据,再参与运算
Integer i = 12;
sop(i+4);
**享元模式:

	        Integer num1 = 12;
            Integer num2 = 12;
            System.out.println(num1 == num2);//打印true

            Integer num5 = Integer.valueOf(12);
            Integer num6 = Integer.valueOf(12);
            System.out.println(num5 == num6);//打印true

            Integer num3 = 129;
            Integer num4 = 129;
            System.out.println(num3 == num4);//打印false

为什么前面的返回true而后面的运算返回false呢?
对于基本数据类型的整数,装箱成Integer对象时,如果该数值在一个字节内,(-128~127),
一旦装箱成Integer对象后,就把它缓存到磁里面,当下次,又把该数值封装成Integer对象时
会先看磁里面有没有该对象,有就直接拿出来用,这样就节省了内存空间。因为比较小的整数,
用的频率比较高,就没必要每个对象都分配一个内存空间。
这就是享元模式!比如26个英文字母,10个阿拉伯数字

(5)枚举
**为什么要有枚举?
问题:要定义星期几或性别的变量,该怎么定义?假设用1-7分别表示星期一到星期日,
但有人可能会写成int weekday = 0;或即使使用常量方式也无法阻止意外。

枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。
枚举可以让编译器在编译时就可以控制源程序中填写的非法值,
普通变量的方式在开发阶段无法实现这一目标。
**用普通类如何实现枚举的功能?定义一个Weekday类来模拟实现:
步骤:
*私有化构造方法
*每个元素分别用一个公有的静态成员变量表示(public static final)
*可以有若干公有方法或抽象方法。采用抽象方法定义nextDay就将大量的if.else语句
转移成了一个个独立的类。
**枚举的应用:
举例:定义一个Weekday的枚举。
扩展:枚举类的values,valueOf,name,toString,ordinal等方法
(记住,讲课时要先于自定义方法前介绍,讲课更流畅)
总结:枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象。
例如可以调用WeekDay.SUN.getClass().getName和WeekDay.class.getName()。
**枚举的高级应用:
**枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。
**枚举元素必须位于枚举体中的最开始部分,枚举元素列表的后要有分号与其他成员分隔。
把枚举中的成员方法或变量等放在枚举元素的前面,编译器报告错误。
**带构造方法的枚举
构造方法必须定义成私有的
如果有多个构造方法,该如何选择哪个构造方法?
枚举元素MON和MON()的效果一样,都是调用默认的构造方法。
**带方法的枚举
定义枚举TrafficLamp
实现普通的next方法
实现抽象的next方法:每个元素分别是由枚举类的子类来生成的实例对象,
这些子类采用类似内部类的方式进行定义。增加上表示时间的构造方法
**枚举只有一个成员时,就可以作为一种单例的实现方式。
(6)泛型:
**泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,
编译器编译带类型说明的集合时会去除掉“类型”信息,使程序运行效率不受影响,
对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。
由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,
就可以往某个泛型集合中加入其它类型的数据,例如,用反射得到集合,再调用其add方法即可。
**ArrayList类定义和ArrayList类引用中涉及如下术语:
整个称为ArrayList泛型类型
ArrayList中的E称为类型变量或类型参数
整个ArrayList称为参数化的类型
ArrayList中的Integer称为类型参数的实例或实际类型参数
ArrayList中的<>念着typeof
ArrayList称为原始类型
**参数化类型与原始类型的兼容性:
参数化类型可以引用一个原始类型的对象,编译报告警告,
例如,Collection c = new Vector();//可不可以,不就是编译器一句话的事吗?
原始类型可以引用一个参数化类型的对象,编译报告警告,
例如,Collection c = new Vector();//原来的方法接受一个集合参数,新的类型也要能传进去
**参数化类型不考虑类型参数的继承关系:
Vector v = new Vector(); //错误!///不写没错,写了就是明知故犯
Vector v = new Vector(); //也错误!
编译器不允许创建泛型变量的数组。即在创建数组实例时,
数组的元素不能使用参数化的类型,
例如,下面语句有错误:
Vector vectorList[] = new Vector[10];
**泛型限定:
**限定通配符的上边界:
正确:Vector<? extends Number> x = new Vector();
错误:Vector<? extends Number> x = new Vector();
**限定通配符的下边界:
正确:Vector<? super Integer> x = new Vector();
错误:Vector<? super Integer> x = new Vector();
**提示:
限定通配符总是包括自己。
?只能用作引用,不能用它去给其他变量赋值
Vector<? extends Number> y = new Vector();
Vector x = y;
上面的代码错误,原理与Vector x11 = new Vector();相似,
只能通过强制类型转换方式来赋值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值