集合
解决什么类型的数据用什么结构存储
一、Java集合框架概述
- 一方面,面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储。
- 另一方面,使用Array存储对象方面具有一些弊端,而Java集合就像一个容器,可以动态地把多个对象的引用放入容器中。
数组在内存存储方面的特点:
1.数组初始化后,长度确定了;
2. 数组声明的类型,就决定了进行元素初始化的类型。
数组在存储数据方面的弊端:
1.数组初始化后,长度不可变,不便于扩展;
2.数组中提供的属性和方法少,不便于进行增删改的操作,且效率不高,同时无法直接获取存储元素的个数;
3.数组存储的数据是有序的、可重复的,存储数据的特点单一。对于无序、不可重复的需求不能满足;
4.获取数组中实际元素的个数的需求,数组没有现成的属性或方法可用。
- Java集合类可以用于存储数量不等的多个对象,还可以保存具有映射关系的关联数组。
二、集合框架
Collection接口:单列集合,用来存储一个一个对象
- list接口:存储有序的、可重复的数据,“动态”数组(不用考虑最大长度超不超的问题,代替数组)
(ArrayList、Linkedlist、Vector) - set接口:存储无序的、不可重复的数据,类似数学中的“集合”
(HashSet、LinkedHashSet、TreeSet)
Map接口:双列集合,用来存储一对(key-value)数据
(HashMap、LinkedHashMap、TreeMap、Hashtable、Properties)
三、Collection接口
1.Collection中常用方法示例:
public class CollectionTest{
@Test
public void test1(){
Collection coll=new ArrayList();
//1.add(Object e)将元素e添加到集合coll中
coll.add('AA');
coll.add('BB');
coll.add(123);//自动装箱
coll.add(new Date());
//2.size()获取添加的元素的个数
System.out.println(colll.size());//4
//3.addAll(Collection coll1)将coll1集合中的元素添加到当前集合中
Collection coll1=new ArrayList();
coll1.add(456);
coll1.add("CC");
coll.addAll(coll1);
System.out.println(coll1);
//4.clear()清空集合中的元素
coll.clear();
//5.isEmpty()判断当前集合是否为空
System.out.println(coll.isEmpty());//true
//6.cotains(Object obj)判断当前集合中是否包含该obj
coll1.add(123);
coll1.add(456);
coll1.add(new String("Tom"));
coll1.add(false);
coll1.add(new Person("Jerry"),20);//添加自定义类
System.out.println(coll.contains(123));//true
System.out.println(coll.contains(new String("Tom")));//true,判断的内容是否相等,实际上调用的equals方法(String包装类重写过该方法)
System.out.println(coll.contains(new Person("Jerry"),20));//false,自定Person类未重写equals方法
** 结论:向Collection接口的实现类的对象中添加数据obj时,要求obj所在类重写equals()方法 **
7.//containsAll(Collection coll)判断形参coll中的所有元素是否都存在于当前集合中
Collection coll1=Arrays.asList(123,456);//返回的List类型是Collection的子接口
System.out.println(coll.containsAll(coll1));//true
}
}
@test
public void test2(){
Collection coll=new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Tom"));
coll.add(new Person("Jerry"),20);
coll.add(false);
//8.remove(Object obj)移除集合中的元素(先判断其中有没有该元素)
coll.remove(new Person{name='Jerry',age=20});
System.out.println(coll);//[123,456,Tom,false]
//9.removeAll(Collection coll1)从当前集合中移除coll1中所有元素(类似做差集)
Collection coll=Arrays.asList(123,456);
coll.removeAll(coll1);
System.out.println(coll);//[Tom,false]
@test
public void test3(){
Collection coll=new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Tom"));
coll.add(new Person("Jerry"),20);
coll.add(false);
//10.retainAll(Collection coll1);获取当前集合和coll1
集合的交集,并返回给当前集合(类似交集)
Collection coll1=Arrays.asList(123,456,789);
coll.retainAll(coll1);
System.out.println(coll);//[123,456]
//11.equals(Object obj)比较当前集合和形参是否相等
Collection coll1=new ArrayList();
coll1.add(456);
coll1.add(123);
coll1.add(new String("Tom"));
coll1.add(new Person("Jerry"),20);
coll1.add(false);
System.out.println(coll.equals(coll1));//false(ArrayList实现List接口,存储需要有序)
//12.hashCode()返回当前对象的哈希值
System.out.println(coll.hashCode());
//13.toArray()集合——>数组
Object[] arr=coll.toArray();
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
//拓展:asList()数组——>集合 调用Arrays的静态方法
List<String> list1=Arrays.asList(new String[]{"AA","BB","CC"});
System.out.println(List1);
List list2=Arrays.asList(new int[]{123,456});
System.out.println(list2.size());//1(会当做一个元素)
List list3=Arrays.asList(new Interger[]{123,456});
System.out.println(list3.size());//2(得用包装类)
2.使用Iterator接口遍历集合元素
- GOF给迭代器模式的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需要暴露该对象的内部细节。迭代器模式,就是为容器而生,类似于“公交车上的售票员”、“火车上的乘务员”。
- Collection接口继承了java.lang.Iterable接口,该接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个ierator()方法,用以返回一个实现了Iterator接口的对象。
- Iterator仅用于遍历集合,Iterator本身并不提供继承对象的能力。如果需要创建Iterator对象,则必须有一个被迭代的集合。
- 集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
Iterator接口的方法:
//14.iterator()返回Iterator接口的实例,用于遍历集合元素。
@test
public void test4(){
Collection coll=new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Tom"));
coll.add(new Person("Jerry"),20);
coll.add(false);
Iterator iterator=coll.iterator();
//方式一:
System.out.println(iterator.next());//123
System.out.println(iterator.next());//456
System.out.println(iterator.next());//Tom
System.out.println(iterator.next());//Person{name='Jerry',age=20}
System.out.println(iterator.next());//false
System.out.println(iterator.next());//报异常:NosuchElemenException(没有第六个元素)
//方式二:
for(int i=0;i<coll.size();i++){
System.out.println(iterator.next())
}
//方式三:(推荐)hasNext()与next()一起使用
while(iterator.hasNext()){
System.out.println(iterator.next())
}
//错误写法:每次调用iterator()都会返回一个迭代器对象
while(coll.iterator().hasNext()){
System.out.println(coll.iterator().next());
//输出一直是第一个元素
//Iterator中remove()方法
//删除集合中的"Tom"元素
Iterator iterator=coll.iterator();
while(iterator.hasNext()){
Object obj=iterator.next();
if("Tom".equals(obj)){
iterator.remove();
}
}
//遍历该集合看还有没有"Tom"
Iterator iterator=coll.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next())
}
foreach循环遍历集合或数组
//遍历集合
@Test
public void test4(){
Collection coll=new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Tom"));
coll.add(new Person("Jerry"),20);
coll.add(false);
//for(集合元素的类型 局部变量:集合对象)
//内部仍然调用了迭代器
for(Object obj:coll){
System.out.println(obj);
}
}
//遍历数组
@Test
public void test5(){
int[] arr=new int[]{1,2,3,4,5,6};
for(int i:arr){
System.out.println(i);
}
}
3.List接口
ArrayList/LinkedList/Vetor的比较
三个类都实现了List接口,存储数据的特点相同:存储有序、可重复的数据
ArrayList:作为List接口的主要实现类。线程不安全,但效率高;底层用Object[] elementData存储
LinkedList:对于频繁的插入、删除操作,使用此类效率比ArrayList高;底层使用双向链表存储
Vetor:作为List接口的古老实现类。线程安全,效率低;底层用Object[] elementData存储
1.ArrayList源码分析:
(1)jdk7情况下:
ArrayList list =new ArrayList();//底层创建了长度为10的Object[]数组elementData
list.add(123);//相当于elementData[0]=new Interger(123);
....
list.add(11);//如果此次的添加导致底层elementData数组容量不够,则扩容,默认情况下,扩容为原来容量的1.5倍,同时将原有数组中的数据复制到新的数组中。故线程不安全
结论:为了避免扩容,建议开发中使用带参的构造器:
ArrayList list=new ArrayList(int capacity);
(2)jdk8情况下:
ArrayList list =new ArrayList();//底层Object[] elementData初始化为{},并没有长度为10的数组
list.add(123);//第一次调用add()时,底层才创建了长度为10的数组,并将数据123添加到elementData[0]
...
后续的添加与扩容操作与jdk7一致
小结:jdk7中的ArrayList对象的创建类似于单例的饿汉式,而jdk8中ArrayList对象的创建类似于单例的饿汉式,延迟了数组的创建,节省内存。
2.LinkedList源码分析:
ArrayList list =new ArrayList();//内部声明了Node类型的firt和last属性,默认值为null
list.add(123);//第一次调用add()时,将123封装到Node中,创建了Node对象(双向链表结点)
List除了从Collection集合继承的方法外,List集合里添加了一些根据索引来操作集合元素的方法。(由于Collection接口中包含Set接口,是无序的,所以索引的操作单独在List接口中添加)
3.List接口常用方法:
public class ListTest{
@Test
public void test1{
ArrayList list=new ArrayList;
list.add(123);
list.add(456);
list.add("AA");
list.add(new Person("Tom","12"));
list.add(456);
//1.add(int index,Object ele)在index位置插入ele元素
list.add(1,"BB");
System.out.println(list);
//"BB"被插入到123和456之间
//2.addAll(int index,Collection ele)从index位置开始将ele中所有元素添加到原集合
List list1=Arrays.asList(1,2,3);
list.addAll(list1);//如果用add()则会把list1当一个元素加入原集合,用size()则会输出7
System.out.println(list.size());//9
//3.Object get(int index)获取指定index位置的元素
System.out.println(list.get(0));//123
//4.int indexOf(Object obj)返回obj在当前集合中首次出现的位置,没有返回-1;
System.out.println(list.indexOf(456));
//5.int lastIndexOf(Object obj)返回obj在当前集合中末次出现的位置
//6.Object remove(int index)移除指定index位置的元素,并返回此元素(与Collection中的方法重载,可以按照对象删也可以按照索引删)
Object obj =list.remove(0);
System.out.println(obj);//返回删除位置的元素123
//7.Object set(int index,Object ele)设置指定index位置的元素为ele
list.set(1,"CC")
System.out.println(list);//将索引为1的元素改成CC
//8.List subList(int fromIndex,int toIndex)返回从fromIndex到toIndex位置的左闭右开子集合
System.out.println(list.sublist(2,4));
}
}
常用方法总结:
增:add(Object obj)
删::emove(int index)/remove(Object obj)
改:set(int index,Object ele)
查:get(int index)
插:add(int index,Object ele)
长度:size()
遍历:1.Iterator迭代器方式2.增强for循环3.普通循环
4.Set接口(开发中用的少)
HashSet/LinkedHashSet/TreeSet比较
三个类都实现了Set接口,存储数据的特点相同:存储无序、不可重复的数据(类似集合)
HashSet:作为Set接口的主要实现类;线程不安全;可以存储null值
LinkedHashSet:作为HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历(并非有序)
TreeSet:可以按照添加对象的指定属性进行排序(用到Comparator和Comparable接口)
1.HashSet/LinkedHashSet详解
- Set接口中没有额外定义新的方法,使用的都是Collection中声明过的方法。
- 向Set中添加的数据,其所在的类一定要重写hashCode()和equals()方法,重写的方法尽可能保持一致性:即相等的对象必须具有相等的散列码。
- 无序性:不等同于随机性。以HashSet为例,存储的数据在底层并非按照数组索引的顺序添加,而是根据数据的哈希值决定。
- 不可重复性:保证添加的元素按照equals()判断时,不能返回true,即相同的元素只能添加一个。
添加元素的过程:(HashSet为例)
我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,再通过某种算法计算出在HashSet数组中的存放位置(索引位置),判断数组此位置上是否已经有元素:
若没其他元素,则元素a添加成功
若有其他元素,则比较两者的hash值,若不同则添加成功;若相同则进而调用元素a所在类的equals()方法,一样则添加失败,否则成功。
public class SetTest{
@Test
public void test1{
Set set=new HashSet();//若用LinkedHashSet(),则输出顺序与添加顺序一致,但并非有序
Set.add(123);
Set.add(123);//重复数据在输出中不显示
Set.add(456);
Set.add("AA");
Set.add("CC");
Set.add(new Person("Tom","12"));
Set.add(129);
Iterator iterator=set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
//输出与输入顺序不一致,存储无序的
}
}
@Test
public void test2{
Set set=new LinkedHashSet();
Set.add(123);
Set.add(456);
Set.add("AA");
Set.add("CC");
Set.add(new Person("Tom","12"));
Set.add(129);
Iterator iterator=set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
//输出与输入顺序一致,存储仍是无序的,
//但是在添加数据的同时,还为每个数据添加了两个地址,
//记录前后两个数据,所以可以保持输出顺序一致。
//对于频繁的遍历操作,其效率高于HashSet
}
}
}
2.TreeSet详解
- 向TreeSet中添加的数据,要求是相同类的对象。
- 两种排序方式:自然排序和定制排序
- 自然排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是equals()方法
- 定制排序中,比较两个对象是否相同的标准为:compare()返回0,不再是equals()
@Test
public void test2{
TreeSet set=new TreeSet();
//失败,不能添加不同类的对象
//Set.add(123);
//Set.add(456);
//Set.add("AA");
//Set.add("CC");
//Set.add(new Person("Tom","12"));
//举例一:
TreeSet set=new TreeSet();
set.add(34);
set.add(-34);
set.add(43);
set.add(11);
set.add(8);
Iterator iterator=set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
//输出为从小到大顺序
}
//举例二:
TreeSet set=new TreeSet();
set.add(new User("Tom","12"));
set.add(new User("Jerry","32"));
set.add(new User("Mike","2"));
set.add(new User("Jack","33"));
//User类需要实现comparable接口,重写compareTo()方法
Iterator iterator=set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
//输出按照重写的compareTo()方法进行排序
}
//举例三:
TreeSet set=new TreeSet(new Comparator(){
//按照年龄从小到大排序
@Overrride
public int compare(Object o1,Object o1){
if(o1 instanceof User&&o2 instanceof User){
User u1=(User)o1;
User u2=(User)o2;
return Integer.compare(u1.getAge(),u2.getAge())
}else{
throw new RuntimeEception("输入的数据类型不匹配");
}
}
});
set.add(new User("Tom","12"));
set.add(new User("Jerry","32"));
set.add(new User("Mike","2"));
set.add(new User("Jack","33"));
Iterator iterator=set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
//输出按照重写的compareTo()方法进行排序
}
}
四、Map接口
1.Map主要实现类
Map:双列数据,存储kay-value对的数据。类似于函数
|----|----HashMap:作为Map的主要实现类;线程不安全的,效率高;可以存储null的key和value。
|----|----|----LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历(在原有HashMap底层结构基础上,添加了一对指针,指向前后元素)对于频繁的遍历操作,此类执行效率高于HashMap。
|----|----TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序和定制排序。(底层使用红黑树) |----|----Hashtable:作为古老的实现类;线程安全的,效率低;不能存储null的key和value。
|----|----|----Properites:常用来处理配置文件;key和value都是String类型HashMap的底层:数组+链表(jdk7之前)
数组+链表+红黑树(jdk8)
2.Map结构的理解
- Map中的key:无序的、不可重复的,使用Set存储所以的key([以hashMap为例]则key所在的自定义类要重写equals()和hashCode()方法)
- Map中的value:无序的、可重复的,使用Collection存储所有value(则value所在的自定义类要重写equals())
- 一个键值对:key-value构成了一个Entry对象
- Map中的entry:无序的、不可重复的,使用Set存储所有的entry
3.底层实现原理
(1)HashMap的底层实现原理
(面试高频)
jdk7中
HashMap map=new HashMap()
//在实例化以后,底层创建了长度为16的一维数组Entry[]
table …(已经执行了多次put)…
map.put(key1,value1)
//首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry数组中的存放位置。
如果此位置上的数据为空,此时的key1-value1添加成功----情况1
如果此位置上的数据不为空(意味着此位置上存在一个或多个数据,以链表形式),则要比较key1和已经存在的一个或多个数据的哈希值
|----如果key1的哈希值与已经存在的数据(key2-value2)的哈希值都不同,此时key1-value1添加成功----情况2
|----如果key1的哈希值和已经存在的某一个数据的哈希值相同,则继续比较:调用key1所在类的equal()方法:
|---- |---- 如果equal()返回false:此时key1-value1添加成功----情况3
|---- |---- 如果equal()返回ture:使用value1替换value2(添加了修改原本value)
补充:关于情况2和情况3:此时key1-value1和原来的数据以链表的方式存储
在不断的添加过程中,会涉及到扩容问题,当超出临界值时(且要存放的位置非空时),默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来。
jdk8相较于jdk7在底层实现方面的不同:
1.new HashMap():底层没有创建一个长度为16的数组
2.jdk8底层的数组是:Node[],而非Entry[]
3.首次调用put()方法时,底层创建长度为16的数组
4.jdk8中底层结构:数组+链表+红黑树,七上八下
当数组的某一个索引位置上的元素以链表形式存在的数据个数>8且当前数组的长度>64时,此时此索引位置上的所有数据改为用红黑树存储
(2)LinkedHashMap0底层实现原理(了解)
LinkedHashMap是HashMap的子类,之所以输出顺序与输入顺序一致是因为将父类中的内部类Node改成了Entry并且在中间添加了before,after属性,可以标明前后元素。
public class SetTest{
@Test
public void test1{
Map map=new HashMap();
map.put(null,null);
//可以存储null值
Map map=new LinkedHashMap();
map.put(123,"aa");
map.put(345,"bb");
map.put(12,"cc");
System.out.print(map);
//LinkedHashMap输出的序列为输入的序列
}
}
4.Map接口中的常用方法
(以HashMap为例)
public class MapTest{
@Test
public void test1(){
//1.Object put()添加
Map map=new HashMap();
map.put("AA",123);
map.put(45,123);
map.put("BB",56);
//将AA==123,修改成AA==87
map.put("AA",87);
System.out.println(map);
//输出{AA=87,BB=56,45=123}
//2.void putAll(Map m)将m中所有的key-value对存放到当前map中
Map map1=new HashMap();
map1.put("CC",123);
map1.put("DD",123);
map.putAll(map1);
System.out.println(map);
//3.Object remove(Object key)
Object value=map.remove("CC");
System.out.println(value);//123
System.out.println(map);//输出{AA=87,BB=56,DD=123,45=123}
//4.void clear()
map.clear();//将map中的元素清除,map对象还在
System.out.println(map);//{/}
System.out.println(map.size());//0
}
@Test
public void test2(){
Map map=new HashMap();
map.put("AA",123);
map.put(45,123);
map.put("BB",56);
//5.Object get(Object key)获取指定key对应的value
System.out.println(map.get(45));//123
//6.boolean containsKey(Object key)/containsValue(Object value)
boolean isExist=map.containsKey("BB");
System.out.println(isExist);//true
boolean isExist=map.containsValue(123);
System.out.println(isExist);//ture,只要找到一个就不会继续找了
//7.boolean isEmpty()
map.clear();
System.out.println(map.isEmpty());//ture
//8.boolean equals(Object obj)判断当前map和参数对象obj是否相等
}
}
由于Map没有iterator方法,但是Set以及Collection有,在第二节Map的结构中可知,Map中的key用Set存储,而value用Collection存储,键值对构成的Entry对象用Set存储,故要想遍历Map中的元素可以获取其Set或Collection集合,再调用iterator方法。
@Test
public void test2(){
Map map=new HashMap();
map.put("AA",123);
map.put(45,123);
map.put("BB",56);
//9.Set keySet()遍历所有key集
Set set=map.keySet()
Iterator iterator=set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
//AA BB 45
}
//10.Collection values()遍历所有的value集
Collection values=map.values();
for(Object obj:values){
System.out.println(obj);
//123 56 123
//与keySet顺序一致
//11.Set entrySet()遍历所有的key-value
//方式一:
Set entrySet=map.entrySet();
Iterator iterator1=entrySet.iterator();
while(iterator1.hasNext()){
Object obj=iterator1.next();
//entrySet集合中的元素都是entry
Map.Entry entry=(Map.Entry) obj;
//调用entry的getKey()和getValue()方法
System.out.println(entry.getKey()+"---->"+entry.getValue());
//AA---->123 BB---->56 45---->123
//方式二:keySet()+value()拼接出
Set keySet=map.keySet();
Iterator iterator2=keySet.iterator();
while(iterator2.hasNext()){
Object key=iterator2.next();
Object value=map.get(key);
System.out.println(key+"---->"+value);
}
}
常用方法总结:
增:put(Object key,Object value)
删::remove(Object key)
改:set(Object key,Object ele)
查:get(Object key)
插:无序所有没有插入操作
长度:size()
遍历:keySet()/values()/entrySet/keySet+values拼接
5.Map其他实现类
1.TreeMap介绍
向TreeMap中添加key-value,要求key必须是由同一个类创建的对象,因为要按照key进行排序:自然排序、定制排序
(不能按照value值排序)
public class TreeMapTest{
@Test
public void test1(){
//自然排序
TreeMap map=new TreeMap();
//自定义User类,User已经继承Comparable接口,重写compareTo()方法
User u1=new User("Tom",23);
User u2=new User("Jerry",32);
User u3=new User("Jack",20);
User u4=new User("Rose",18);
map.put(u1,98);
map.put(u2,89);
map.put(u3,76);
map.put(u4,100);
Set entrySet=map.entrySet();
Iterator iterator=entrySet.iterator();
while(iterator.hasNext()){
Object obj=iterator.next();
Map.Entry entry=(Map.Entry) obj;
System.out.println(entry.getKey()+"---->"+entry.getValue());
//按照名字从小到大顺序输出
}
@Test
public void test1(){
//定制排序
TreeMap map=new TreeMap(new Compartor(){
@Override
public int compare(Object o1,Object o2){
if(o1 instanceof User&&o2 instanceof User){
User u1=(User)o1;
User u2=(User)o2;
return Integer.compare(u1.getAge(),u2.gerAge());
}
throw new RuntimeException("输入的类型不匹配");
}
});
User u1=new User("Tom",23);
User u2=new User("Jerry",32);
User u3=new User("Jack",20);
User u4=new User("Rose",18);
map.put(u1,98);
map.put(u2,89);
map.put(u3,76);
map.put(u4,100);
Set entrySet=map.entrySet();
Iterator iterator=entrySet.iterator();
while(iterator.hasNext()){
Object obj=iterator.next();
Map.Entry entry=(Map.Entry) obj;
System.out.println(entry.getKey()+"---->"+entry.getValue());
//按照年龄大小从小到大输出
}
}
2.Properties介绍
- Properties类是Hashtable的子类,用于处理属性文件
- 由于属性文件里的key、value都是字符串类型,所以Properties里的key和value都是字符串类型
public class PropertiesTest{
public static void main(String[] args){
//在程序中读取配置文件的内容
Properties pros=new Properties();
FileInputStream fis=new FileInputStream("jdbc.properties");//自己创建的jdbc.properties配置文件,内容:name=Tom password=abc123
pros.load(fis);//加载流对应的文件
String name=pros。getProperty("name");
String passward=pros.getProperty("passward");
System.out.println("name="+name+"passward="+passward);
fis.close;
}
}
五、Collections工具类
Collection是一个操作Set、List和Map等集合的工具类
public class CollectionTest{
@Test
public void test1(){
List list =new ArrayList();
list.add(123);
list.add(43);
list.add(765);
list.add(-97);
list.add(0);
System.out.println(list);//[123,43,765,-97,0]
//1.reverse(List)反转集合顺序
Collections.reverse();
System.out.println(list);//[0,-97,765,43,123]
//2.shuffle(List)随机化排序
System.out.println(list);//[43,765,-97,123,0]
//每次随机不一样
//3.sort(List)根据元素的自然排序对指定List集合元素按升序排序
//sort(List,comparator)根据指定的Comparator(定制排序)对List集合元素排序
Collections.sort(list);
System.out.println(list);//[-97,0,43,123,765]
//4.swap(List,int i,int j)将指定list集合中的i处的元素和j进行交换
//5.Object max/min(Collection)根据元素的自然排序,返回给定集合最大/小元素
//Object max/min(Collection,Comparator)根据Comparator(定制排序),返回集合中最大/小元素
//6.int frequency(Collection,Object)返回指定集合中指定元素的出现次数
//7.void copy(List dest,List src)将src中的内容复制到dest中
List list =new ArrayList();
list.add(123);
list.add(43);
list.add(765);
list.add(-97);
list.add(0);
//错误写法
List dest=new ArrayList();
Collections.copy(dest,list);
System.out.println(dest);//报错:Source does not fit in dest
//正确写法
List dest=Arrays.asList(new Object[list.size()]);
//得先造一个和list长度一样的集合dest
System.out.println(dest.size());//和list.size()长度一致
Collections.copy(dest,list);
System.out.println(dest);
//8.boolean replaceAll(List list,Object,Object newVal)使用新值替换List中的旧值
}
}
在开发中,如果需要线程安全,我们一般也不会使用Vetor和Hashtable,而是将ArrayList和HashMap改成线程安全的。
Collections类中提供了多个synchronizedXXX()方法,该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题
public class CollectionTest{
@Test
public void test2(){
List list =new ArrayList();
list.add(123);
list.add(43);
list.add(765);
list.add(-97);
list.add(0);
List list=Collections.synchronizedList(list);
//该list即为线程安全的
}
}