集合与集合框架
-------android培训、java培训、期待与您交流!----------
内容: String、字符串缓冲区(StringBuffer、StringBuilder)、基本数据类型包装类、
集合Collection(列表List、集Set)与映射Map(双列集合)、泛型
1、String类
String字符串是一个特殊的对象,不属于数据类型(八种基本、三种引用)。
特点:
因为String对象是不可变的,存在于字符串池(常量池之一),所以可以共享。
初始化格式(常见前两种):
String s1 =“abcd”;
String s2 = new String(“abc”);
Strings3 = new String(“ab”+“cd”);
注意:
s2 :内存中创建2个对象:new关键字、“abcd”;
s3 :内存中创建4个对象:”ab”、”cd”,以及两者组合”abcd”与其new的对象。
解析:
“abc”
new关键字
区别:一个是字符串池引用,一个是内存地址。速度*问内存较快,但它是在内存中创建了对象。
注意:
String类中方法:
boolean anObj
)
char
int
char[ ]
int
boolean
String[] split(String reg);
String
String char
数组参数的字符串表示形式;
2.1、StringBuffer(字符串缓冲区/字符序列)
特点:
1、是可变长度的(数据)容器;
2、可以直接操作多个数据类型;
3、StringBuffer可以对容器中字符串内容进行增删改查(CURD);
【Create创建、Update修改、Read查找、Delete删除】
3、最终会通过toString方法变成字符串;
4、很多方法与String相同,而字符串的组成原理就是通过该类实现的;
StringBuffer类中方法:
.append(Object
.insert(intoffset,
Objectobj)
:将 Object
参数插入到此字符序列指定位置中;
.toString()
.lastIndexOf(String
2.2、StringBuilder(也属于字符串缓冲区)
特点:
1、简易替换StringBuffer的字符串缓冲区;
2、与StringBuffer具有相同的操作功能(方法),但不支持多线程(同步);
3、因为不需要执行同步,所以在多数实现中比StringBuffer速度快;
4、如果可行,建议优先采用此方法(多用于字符串缓冲区被单线程使用,很普遍);
5、StringBuilder类方法基本上与StringBuffer相同(详见java.lang.StringBuilder类)。
2.3、字符串与字符串容器:
String
StringBuffer
(字符串缓冲区,可对其中字符序列进行添加、删除等)
StringBuilder: 简易替换StringBuffer,可变字符序列,但不支持同步;
(推荐优先使用StringBuilder,因为不执行同步,在单线程中执行速度快,且拥有相同功能)
3.1、基本数据类型对象包装类:
Java中一切皆对象,但是基本数据类型却不能算是对象,也就无法通过类/方法来操作基本数据类型值。因此为了方便操作基本数据类型值,将其封装成对象,在对象中定义更多的功能方法操作该数据,而用于描述该对象的类就称为基本数据类型对象包装类。
基本数据类型
byte
short
int
long
float
double
char
boolean
PS: 实际上,Java中还存在另外一种基本类型void,它也有对应的包装类java.lang.Void,不过我们无法直接对其进行操作。
最常用的作用: 用于基本数据类型与字符串之间的转换;
1、基本数据类型(包装类)转成字符串:
2、字符串转成基本数据类型:
例如:
int
parseInt(
String
int
示例1:
示例2:
(文件等中基本上都是字符(或字节),应用:将字符串转换成基本数据类型参与运算等)
基本数据类型包装类可通过方法来转换数值的进制(进制转换):
A、十进制转成其他进制:
B、其他进制转成十进制:
例: 如果radix为2,则str为二进制的数,将提取str中的二进制数并转换成十进制数;
注意: 当str不属于该进制的数会抛出异常。
3.2、JDK1.5新特性———自动装箱、自动拆箱:
随着基本数据类型包装类的出现,Java提供自动装箱与拆箱功能;
示例:
Integer x = 4;
x = x + 2;
//x+2: x进行自动拆箱,变成int类型,和2进行加法运算,再将两者和进行装箱赋给x。
注意:
例:
Integer b = 127;
因为a和b指向了同一个Integer对象;
因为当数组在byte范围内,对于新特性,如果该数值已经存在,则不会再开辟新的空间(享元模式)。
(注意:如果a、b数值大于127,则两者不相等,因为new新建了Integer的对象,所以两者地址值不同)
4、集合类:
A、集合类概述:
Java中对事物的体现都是以对象的形式(即一切皆对象),所以在Java中对数据的操作其实就是对对象的操作或存储,而集合就是存储对象的一种方式。
B、数组和集合的区别:
数组可存储基本数据类型与对象,但数组长度固定(初始化时指定);
集合只能存储对象,集合长度是可变,集合可以存储不同类型的对象。
集合框架图:
特点:查询速度很快。但是增删稍慢。线程不同步。
特点:增删速度很快,查询稍慢。线程不同步。
Collection集合方法详见java.util包中的类。
1、添加:
2、删除:
3、判断:
isEmpty( );
4、获取:
//格式:Iteratorit = al.iterator();
5、获取交集:
6,集合变数组:
注意:
2、集合中存储的都是对象的引用(地址)。
【Collection各子类特点简要】
5、List(列表):可存放重复元素,元素存取是有序的(带角标)。
取出List集合中元素的方式:
遍历集合,获取集合中全部元素的方法:Iterator迭代器(仅删除、获取功能);
Collection共性方法:
示例:
Iterator it =cl.iterator();
while(it.hasNext()){
}
节省内存书写方式:
for(Iterator it =l.iterator();it.hasNext(); ){
} //for循环中创建Iterator对象,而循环结束后jvm会擦除该对象在内存中占用的空间。
PS: List列表由于拥有脚标,可使用特有的列表迭代器(ListIterator)。
ListIterator类中提供方法可对List列表进行遍历同时对元素增删改;
6、Set(集):不可以存放重复元素(元素唯一性),元素存取是无序的。
HashSet:线程不安全,存取速度快。
TreeSet:线程不安全,可以对Set集合中的元素进行排序。
TreeSet排序两种方式:
1、让元素自身具备比较性:
这种方式也成为元素的自然顺序,或者叫做默认顺序。
2、给存储元素的容器TreeSet等添加比较器;
用于:
要求创建实现Comparator接口覆盖compare方法的比较器(类)。
注意: 两者同时存在时,优先使用比较器排序方式。
Collection集合与子类的使用与特点简要: (个人观点)
7、Map映射:
Map集合:该集合存储键值对。一对一对往里存。而且要保证键的唯一性。
I、Map
【注意: Set类是基于Map实现的,由Map的键值(只保留唯一的键)转变而成。】
所以他们具有共性:
1、HashMap的键Key、HashSet元素都是通过hashCode、equals来保证键/元素的唯一性;
2、TreeMap的键、TreeSet元素都是通过compareTo或compare方法来保证元素唯一性和实现集、映射容器的排序功能;
Map与Collection的区别:
1、Map与Collection在集合框架中属并列存在
2、Map属于双列集合(键=值);而Collection(List和Set)是单列集合。
3、Map存储元素使用put(键,值)方法,Collection使用add()方法;
4、Map集合中键要保证唯一性,对应Set集中元素(唯一性);
5、Map集合没有直接取出元素的方法,需要先转成Set集合,再通过迭代获取元素。
II、接口Map<K,V>的共性方法:
Map<?
extends K, ? extends
V>
1、添加:
putAll(Map<? extends K,? extendsV> m)
2、删除:
remove(Object key)
3、判断:
isEmpty()
4、获取:
Collection<V>
Set<K>
Set<Map.Entry<K,V>>
嵌套类:
(staticinterface)Map.Entry<K,V>
注解: Entry是一个接口,它是Map接口中的一个内部接口;
Map子类的特有方法:
1、HashMap同HashSet相同,没有特有方法,同Map接口方法一致。
2、TreeMap同TreeSet相同,因为自动排序功能,具有以下特有方法:
TreeMap特有方法:
1、获取(比较性质):
E
E
E
E
Map.Entry<K,V>
lastEntry()
higherEntry(K key)
lowerEntry(K key)
2、删除返回:
Map.Entry<K,V>
pollLastEntry()
提取/转换 :
SortedMap<K,V>
NavigableMap<K,V>
descendingMap()
NavigableSet<K>
descendingKeySet()
3、获取比较器:
Comparator<? SuperK>
【更多详见API中java.util.TreeMap类】
4、注意: 调用方法代码多有类似,可按规律记忆:
返回存储对象
例如: E
III、Map集合的取出方式:
Map集合不能直接取出键值对,只能通过转换成Set集合,通过Set迭代器获取。
两种间接取出方式:
将map集合中的映射关系存入到Set集合中,存放为数据类型Map.Entry<k,v>。
再调用Set集合迭代器获取映射关系,通过Map.Entry<k,v>方法获取键、值。
理解:
接口Map.Entry
源码,参考理解:
interface Map{
public static interface Entry{
}}
//因此方法二可解释为往Set集合中存储的是实现Map.Entry的子类对象。
IV、扩展理解:
Map映射的存储格式是:Map<? extends
K, ? extends
V>;
例如:
扩展理解、使用:
虽然Map多用于配置文件的属性键值对等,但也能用来实现一对多(集合)等。
(例如学校属性: 学校名——学校, 学校中:不同班级——相同学号的不同学生对象等)
———————————————泛型————————————————
八、泛型:
(它使程序运行时可能出现的问题,提前在编译时出现,在程序中添加限制(泛型))
例如:
原因:
2、泛型通配符:
【在API文档中可看到以下符号——泛型通配符,解析帮助理解。】
(通常用于定义方法参数,表示不明确接收集合等的元素的具体类型,将参数集合的数据类型定义为“?”,即可接收任意数据类型的集合,但也就不能调用与具体数据类型相关的方法。)
【在向方法等传递集合时指定数据类型,可在方法中调用涉及具体数据类型的方法,但建议在方法多处使用到相关数据类型时使用,例:返回值类型、接收参数、调用具体数据类型的方法】
例: 比较器:
例如: Student继承Person,要比较Student对象,则可传入Person或Student;
注意:
而实际应用时在创建类/方法(自定义比较器、集合等)时才可添加/使用这些通配符,即表示调用该方法时也是要指定方法操作的数据类型。
3、泛型类、泛型方法:
A、泛型类的泛型字符 与泛型方法的字符相同,那么它们指向同一个泛型;
B、泛型方法间的泛型字符是相互独立,即使相同,也指向不同泛型(数据类型);
C、静态泛型方法不能与泛型类的泛型字符指向同一个泛型。
创建泛型类、泛型方法的格式:
class Student<T>{
}
在方法的修饰符之后、返回值之前的添加<T>,表示在该方法新建自己的泛型T。
【该泛型T仅在该方法有效,即使与泛型类上的同名也是调用本方法上的。】
解释:
1、泛型类上定义<T>,表示本类中同名泛型字符的方法默认调用此泛型T;
2、如果泛型方法上自己定义了<T>,则调用自己的泛型,相对泛型类独立;
3、静态泛型方法必须要自行定义<T>,因为静态泛型方法不能访问类(非静态)上的泛型。
4、非泛型类(或与泛型类泛型字符不同)的泛型方法也必须要自定义泛型(<T>等),如果有使用到泛型的话。