一:集合转成数组。
Collection接口中有一个toArray方法。可以完成。
importjava.util.*;
class CollectionToArray{
public static void main(String[] args) {
ArrayList<String> al = newArrayList<String>();
al.add("haha");
al.add("hehe");
al.add("heihei");
String[] arr = al.toArray(newString[al.size()]);//将集合变成数组。
给toArray方法传递指定类型的数组。
长度该怎么定义呢?
当指定的长度小于集合的长度,该方法内部会自动创建一个该类型的新数组长度和集合长度一致 。用于存储集合中的元素。
如果指定的数组长度大于集合的长度,那么该方法就不会创建新数组。而是使用传递进来的数组,存储完集合的元素后,其他的未存储的位置为null。
所以在定义数组是,最好定义长度和集合长度相同的数组。这样就不用创建新数组了; 而且也不会出现空位为null 。
将集合变成数组有什么用呢?
其实是限定了对元素的增删操作。
二:JDK1.5版本以后的新特性:
Collection就有了一个父接口Iterable;该接口的出现封装了iterator方法。并提供了一个增强for循环。
格式:
for( 元素类型 变量: 数组或者Collection集合)
{
}
增强for循环和传统for循环有什么不同呢?
增强for循环,使用时,必须要有被遍历的目标。
而且只能遍历数组和Collection集合。简化了迭代。
传统for循环,它的应用更为普遍。
注意:建议遍历数组还是使用传统for循环,可以通过指针对数组元素进行操作。
这个升级是注重,简化书写。
importjava.util.*;
class ForeachDemo{
public static void main(String[] args) {
ArrayList<String> al = newArrayList<String>();
al.add("haha");
al.add("hehe");
al.add("heihei");
for(String s : al)//高级for循环一般只用于遍历。不对元素进行操作。
{
System.out.println(s);
}
/*
Iterator<String> it =al.iterator();//迭代器具备在迭代过程中对元素的操作, 比如 remove //通过ListIterator具备在迭代过程中对元素进行增删改查。
while(it.hasNext()){
System.out.println(it.next());
}
*/
int[] arr = {5,1,6,7};
for(int i : arr){
//System.out.println("i="+i);
i = 10;//并不会改变数组中的元素。
}
System.out.println(Arrays.toString(arr));
//要对map集合进行遍历,可以使用foreach循环吗?不可以直接使用。但是可以间接使用。
//但是可以将map集合转成set结合,在使用foreach循环。
HashMap<String,String> hm = new/*Linked*/HashMap<String,String>();
hm.put("01","lisi1");
hm.put("03","lisi3");
hm.put("04","lisi4");
hm.put("02","lisi2");
Set<String> keySet = hm.keySet();
for(String s : keySet){
System.out.println("key:"+s+"::"+hm.get(s));
}
for(Map.Entry<String,String> me :hm.entrySet()){
String key = me.getKey();
String value = me.getValue();
System.out.println(key+"-------"+value);
}
}
}
三:集合框架中的另一个顶层接口Map
A:Map集合特点:
1,是一个双列集合,Collection是单列集合。
2,Map一次存一对元素,同时键值对的形式。键和值有对应关系。
Collection是一次存一个元素。
3,Map集合必须要保证集合中键的唯一性。
Collection 是单身汗,Map集合存的是夫妻。
B:Map集合中常见的功能:
1,添加。
V put(k ,v):将k和v作为元素存储如map集合,当存入了相同的k时,新的值会覆盖原来的值,并返回原来的值。
void putAll(map);
2,删除。
clear();
v remove(k):按照键删除,返回被删除的键对应的值。
3,判断。
boolean containsKey(Object key)
boolean containsValue(Objectvalue);
boolean isEmpty();
4,获取。
int size():获取map集合的元素个数。
v get(k): 通过键获取值。还可以作为判断某一个键是否存在的依据。
Collection values():获取map集合中所有的值。
Set keySet():获取map集合中所有的键。
Set entrySet():获取的是键值的映射的关系。将映射关系封装成对象存入到了Set集合。
C:Map集合居然没有迭代器:是的,迭代器是Collection集合具备的。
Map集合的取出元素的原理:就是将Map集合先转成Set集合,再进行迭代。
Map
|--Hashtable:底层是哈希表数据结构。是同步的。不允许null作为键,null作为值。
|--Properties:用于配置文件的定义和操作,使用频率非常高,同时键和值都是字符串。是集合中可以和IO技术相结合的对象。 到了IO在学习它的特有和IO相关的功能。
|--HashMap:底层也是哈希表数据结构。是不同步的。允许null作为键,null作为值。替代了Hashtable.
|--LinkedHashMap: 可以保证HashMap集合有序。存入的顺序和取出的顺序一致。
|--TreeMap:可以用来对Map集合中的键进行排序.
例子1:
import java.util.*;
class HashMapDemo{
public static void main(String[] args) {
//存储学号和姓名
HashMap<Integer,String> hm = newHashMap<Integer,String>();
//添加元素,键值对。
hm.put(1,"zhangsan");
//System.out.println(hm.put(3,"lisi"));
hm.put(2,"wangwu");
hm.put(6,"zhaoliu");
hm.put(4,"zhouqi");
//System.out.println(hm.put(3,"haha"));
//获取。
//System.out.println("hm.get(3):"+hm.get(3));
//删除。
System.out.println(hm.remove(6));
//hm.clear();
//判断。
System.out.println(hm.containsKey(1));
System.out.println(hm);
}
}
例子2:
import java.util.*;
class HashMapDemo2{
public static void main(String[] args) {
//存储学号和姓名
HashMap<Integer,String> hm = newHashMap<Integer,String>();
hm.put(1,"zhangsan");
hm.put(3,"lisi");
hm.put(2,"wangwu");
hm.put(6,"zhaoliu");
hm.put(4,"zhouqi");
//如何获取集合中所有元素呢?
1,获取所有的键,在通过对所有的键进行遍历,在遍历中通过get方法获取每一个键的对应的值。
使用 Map集合中 keySet方法:获取Map集合中键的集合。
Set<Integer> keySet = hm.keySet();
//对set集合进行迭代器。
Iterator<Integer> it =keySet.iterator();
while(it.hasNext()){
Integer i = it.next();
String s = hm.get(i);
System.out.println(i+"::"+s);
}
2,将Map集合中的键值关系取出,并封装成一个键值关系对象。再存储到一个set集合中。
键值映射关系封装对象后的数据类型是:Map.Entry
Entry无非就是一个Map接口中的内部静态接口。
作为一个键值关系对象的数据类型存在。
使用entrySet获取map集合中的所有键值。
Set<Map.Entry<Integer,String>>entrySet = hm.entrySet();
Iterator<Map.Entry<Integer,String>>it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<Integer,String> me =it.next();
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+"::::"+value);
}
}
}
四:JDK1.5后新特性:可变参数:
当一个函数操作的参数类型一致,但是参数个数不一致的时候,可以定义成该类型的数组参数。
这样,使用者,就可以把元素封装成一个数组。在进行传递即可。
我们发现,还要new一个数组,也麻烦。所以jdk1.5以后出现了新特性。
就是可变参数,在指定数据类型的后面加上三个点 ,其实就是一个数组类型的参数,
区别:
以前定义一个int[] 类型的参数,调用必须要定义好一个数组,才往里传递 。
而现在定义一个int... 类型的参数,调用者,直接往该函数中传递元素即可。
在运行时,自动会将这些实际参数封装到一个该类型的数组当中;也就是调用省去了封装数组的步骤,变简单了。
这个升级也是简化书写。
注意:如果函数上有多个参数,可变参数一定要定义在参数列表最后面。
否则编译失败。
public static void method(int... arr,int a)// 这个定义是错误的。
public static voidshow(int... arr)//可变参数。其实arr就是一个数组类型的参数。
{
for(int i : arr){
System.out.println(i);
}
}
五:JDK.1.5 特性:静态导入。
当方法名称重复时,必须指定所属的类名。
importjava.util.*;//简化类名的书写。
import staticjava.util.Collections.*;//导入了一个类中的所有静态成员.
import staticjava.util.Arrays.*;
import staticjava.lang.System.*;
classStaticImportDemo {
public static voidmain(String[] args) {
ArrayList<Integer> al = newArrayList<Integer>();
al.add(1);
al.add(4);
al.add(6);
al.add(2);
sort(al);
System.out.println(al);
int index = binarySearch(al,4);
System.out.println("index="+index);
int[] arr = {4,1,6};
sort(arr);
System.out.println(Arrays.toString(arr));
out.println("haha");
}
}