------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
Map
Map集合:该集合存储键值对,一对一对往里存,而且要保证键的唯一性;
HashTable:底层是哈希表数据结构,不可以存入null键null值。该集合时线程同步的。Jdk1.0 效率低
HashMap:底层是哈希表数据结构,允许使用null值和null键,该集合是不同步的。将HashTable替代,jdk1.2 效率高
TreeMap 底层是二叉树数据结构,线程不同步,可以用于给Map集合中的键进行排序
其实Set底层就是使用了Map集合
Map中常用方法:
1、添加
V put(K key,V value);//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值,并put方法会返回被覆盖的值。
void putAll(Map <? extends K,? extends V> m);//添加一个集合
2、删除
clear();//清空
V remove(Object key);//删除指定键值对
3、判断
containsKey(Objectkey);//判断键是否存在
containsValue(Objectvalue)//判断值是否存在
isEmpty();//判断是否为空
4、获取
V get(Object key);//通过键获取对应的值
size();//获取集合的长度
Collection<V>value();//获取Map集合中所以得值,返回一个Collection集合
还有两个取出方法,接下来会逐个讲解:
Set<Map.Entry<K,V>>entrySet();
Set<K> keySet();
注:HashMap集合可以通过get()方法的返回值来判断一个键是否存在,通过返回null来判断。
Map取出元素的第一种方式:
import java.util.*;
public class MapDemo {
public static void main(String[] args) {
//定义一个Map集合
Map<Integer,String> map = new HashMap<Integer,String>();
//添加元素
map.put(1, "aaa");
map.put(2, "bbb");
map.put(3, "ccc");
map.put(4, "ddd");
//取出键值的Set视图
Set<Integer> set = map.keySet();
//迭代
Iterator<Integer> it = set.iterator();
while(it.hasNext()){
Integer key = it.next();
String value = map.get(key);
System.out.println(key+"="+value);
}
}
}
Map取出元素的第二种方式:
import java.util.HashMap;
import java.util.Map;
import java.util.*;
public class MapDemo2 {
public static void main(String[] args) {
//定义一个Map集合
Map<Integer,String> map = new HashMap<Integer,String>();
//添加元素
map.put(1, "aaa");
map.put(2, "bbb");
map.put(3, "ccc");
map.put(4, "ddd");
//得到存有Map中映射关系的Set视图
Set<Map.Entry<Integer, String>> sme = map.entrySet();
//迭代
Iterator<Map.Entry<Integer, String>> it = sme.iterator();
while(it.hasNext()){
Map.Entry<Integer, String> me = it.next();
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+"="+value);
}
}
}
练习:统一每个字母在一串字符串中出现的次数
/*统计字符串中每个字母出现的次数
* 思路:1,将字符串转换成字符数组,因为要对每一个字母进行操作
* 2,定义一个Map集合,因为打印结果的字母有顺序,所以使用TreeMap集合
* 3,遍历字符数组
* 将每一个字母作为键去查Map集合
* 如果返回null ,将该字母和1存入到map集合中
* 如果返回不是null,说明该字母在map集合已经存在并有对应次数
* 那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到map集合中,覆盖原有键所对应的次数
* 4,将map集合中数据变成指定的字符串形式返回
* */
import java.util.*;
public class MapDemo3 {
public static void main(String[] args) {
//测试
String str = "jdsljfweonvlnlj";
str = count(str);
System.out.println(str);
}
public static String count(String str){
//定义一个StringBuilder
StringBuilder sb = new StringBuilder();
//定义一个Map
TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
//将传入的字符串转化为数组
char[] ch = str.toCharArray();
//查看数组中的每个元素是否是Map的键值,如果是将此键值的值加1然后讲这对键和键值继续存入Map 集合中
//如果不是,将此元素当做键一当做值存入Map集合中
for(int i = 0 ; i < ch.length; i++){
if(tm.get(ch[i]) == null){
tm.put(ch[i], 1);
}else{
int value = tm.get(ch[i]);
value++;
tm.put(ch[i],value);
}
}
//迭代Map集合,并将其化为指定的字符串形式返回
Set<Character> set = tm.keySet();
Iterator<Character> it = set.iterator();
while(it.hasNext()){
Character key = it.next();
Integer value = tm.get(key);
sb.append(key+"("+value+")");
}
return sb.toString();
}
}
练习二:
/*
* 有学校czbk 学校中包括两个班级jyb 和 yrb 每个班级包括学生,学号和姓名*/
import java.util.*;
public class MapDemo5 {
public static void main(String[] args) {
//学校集合czbk
HashMap<String,HashMap<Integer,String>> czbk = new HashMap<String,HashMap<Integer,String>>();
//班级yrb集合
HashMap<Integer,String> yrb = new HashMap<Integer,String>();
//班级jyb集合
HashMap<Integer,String> jyb = new HashMap<Integer,String>();
//添加元素
yrb.put(111, "lis1");
yrb.put(222, "lis2");
yrb.put(333, "lis3");
jyb.put(444, "wang4");
jyb.put(555, "wang5");
jyb.put(666, "wang6");
czbk.put("yrb", yrb);
czbk.put("jyb", jyb);
print(czbk);
}
//打印集合
public static void print(HashMap<String,HashMap<Integer,String>> czbk){
//获取学校的键值set视图
Set<String> set = czbk.keySet();
//迭代
Iterator<String> it = set.iterator();
while(it.hasNext()){
String key = it.next();
System.out.println(key);
HashMap<Integer,String> value = czbk.get(key);
//打印班级名称
Set<Integer> set_2 = value.keySet();
//迭代
Iterator<Integer> it_2 = set_2.iterator();
while(it_2.hasNext()){
Integer key_2 = it_2.next();
String value_2 = value.get(key_2);
System.out.println("学号: "+key_2+"姓名:+ "+value_2);
}
}
}
}
Collection:一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java类口中有很多
具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。
练习:Collections中的二分查找和sort方法:
代码:
import java.util.*;
public class CollectionsDemo {
//测试类
public static void main(String[] args) {
ArrayList<String> alist = new ArrayList<String>();
alist.add("aaaa");
alist.add("bbb");
alist.add("cc");
alist.add("d");
Collections.sort(alist, new Cmp_1());
int index = binarySearch(alist,"bbb",new Cmp_1());
System.out.println(alist);
System.out.println(index);
}
//Collections的二分查找的实现原理
public static int binarySearch(ArrayList<String> alist,String key,Comparator<String> cmp){
int max = alist.size()-1,min = 0,mid;
while(min<= max){
mid = (max + min)>>1;
int num =cmp.compare(alist.get(mid), key);
if(num > 0)
max = mid -1;
else if(num < 0)
min = mid+1;
else return mid;
}
return -min-1;
}
}
//自定义的比较器
class Cmp_1 implements Comparator<String>{
@Override
public int compare(String arg0, String arg1) {
int num = new Integer(arg0.length()).compareTo(new Integer(arg1.length()));
if(num == 0)
return arg0.compareTo(arg1);
return num;
}
}
Arrays 数组工具类
此类包含用来操作数组(比如排序和搜索)的各种方法。此类还包含一个允许将数组作为列表来查看的静态工厂。
方法:将数组转换为集合
把数组转换为集合有什么好处?
可以使用集合的思想和方法来操作数组中的元素。
注意:将数组变成集合,不可以使用集合的增删方法。因为数组的长度是固定的。
如果增删,那么会抛出UnsupportOperationException
如果数组中的元素都是对象,那么变成集合时,数组汇总的元素就直接转成集合中的元素。如果数组中的元素都是基
本数据类型,那么会将该数组作为集合中的元素存在。
Arrays常用方法:
static <T> List<T> asList(T... a) //返回一个指定数组支持的固定大小的列表
示例代码:
Integer[] it = {1,2,3,4,5,6};
List<Integer> al = Arrays.asList(it);
al.contains(2);//判断是否包含某个元素
al.get(2);//获取指定角标值
al.indexOf(3);//获取某个元素第一次出现的
al.isEmpty();//判断集合是否为空
al.iterator();//返回集合的迭代器
al.set(2, 2);//设置某个角标的值
al.size();//返回集合的元素数
al.subList(2, 4);//截取子集合
static int binarySerach(int[] a, int key) 使用二分查找法来搜索指定的int型数组,已获得指定的值
static int binarySearch(int[] a , int fromIndex,int toIndex,int key )使用二分搜索法来搜索指定的int型数组的范围,以获
取指定的值
static int[] copyOf(int [] original, int newLength)复制指定的数组,截取或用0填充(如有必要),以使副本具有指定的
长度
static int[] copyOfRange(int[] original, int form , int to )将指定数组的指定范围复制到一个新数组
static void fill(int[] a , int val )将指定的int值分配给指定int型数组的每个元素
static void fill(int[] a ,int fromIndex, int toIndex, int val)将指定的int值分配给指定int型数组指定范围中的每个元素
static void sort(int[] a )对指定int型数组按升序进行排序
static void sort(int[] a ,int formIndex,int toIndex)对指定int型数组的指定范围按数组升序进行排序
static String toString(int[] a )返回指定数组内容的字符串表现形式
将集合转换成数组:
为什么要将集合变为数组?
为了限定对元素的操作,不需要进行增删了。
在上述方法中,当指定类型的数组长度小于集合的size,那么该方法内会创建一个新的数组,长度为集合的size。当
指定类型的数组长度大于了集合的size,就不会创建新数组,而是使用传递进来的数组。
<T> T[] toArray(T[] a ) 返回包含此Collection中所有元素的数组。返回数组的运行时类型与指定数组的运行时类型相
同。
示例代码:
<span style="font-size:18px;"> ArrayList<Integer> al = new ArrayList<Integer>();
al.add(1);
al.add(2);
al.add(3);
al.add(4);
al.add(5);
al.add(6);
al.add(7);
Integer[] a =al.toArray(new Integer[0]);
for(int i = 0; i < a.length; i++){
System.out.print(a[i]+" ");
}
</span>
增强for循环
实现Iterable接口允许对象成为“foreach”语句的目标
格式:
for(数据类型 变量名: 被遍历的集合(Collection)或数组)
{
}
对集合进行遍历:只能获取集合元素,但是不能对集合进行操作。迭代器除了遍历,还可以进行remove集合中的元
素的动作。如果是用ListIterator,还可以在遍历过程中对集合进行增删改查的动作。
传统for和高级for有什么区别:
高级for 有一个局限性,必须由被遍历的目标,传统for 可以没有。
建议在遍历数组的时候,还是希望使用传统for,因为传统for可以定义脚标。
示例代码:
ArrayList<Integer> al = new ArrayList<Integer>();
al.add(1);
al.add(2);
al.add(3);
al.add(4);
al.add(5);
al.add(6);
al.add(7);
//增强for遍历集合
for(Integer i : al){
System.out.print(i+" ");
}
System.out.println();
Integer[] a =al.toArray(new Integer[0]);
//增强for遍历数组
for(Integer i : a){
System.out.print(i+" ");
}
System.out.println();
//传统for遍历数组
for(int i = 0; i < a.length; i++){
System.out.print(a[i]+" ");
}
Map使用增强for迭代:
HashMap<Integer,String> hm = new HashMap<Integer,String>();
hm.put(1, "java01");
hm.put(2, "java02");
hm.put(3, "java03");
hm.put(4, "java04");
Set<Integer> keySet = hm.keySet();
for(Integer i : keySet){
String value = hm.get(i);
System.out.println(i+":::"+value);
}
可变参数:
可变参数:Java1.5增加的新特性。可变参数适用于参数个数不确定,类型确定的情况,Java把可变参数当做数组处
理。注意:可变参数必须位于参数的最后一项。当可变参数
个数多于一个时,必须有一个不是最后一项,所以只支持一个可变参数。因为参数个数不定,所以当其后面还有相同
类型参数时,Java无法区分传入的参数属于前一个可变参数还是后边的参数,所以只能让可变参数位于最后一项。
其实可变参数就是数组参数的简写形式。不用每一次都手动的建立数组对象。只要将要操作的元素作为参数传递即
可。隐式将这些参数封装成了数组。
<span style="font-size:18px;">public class Demo3 {
public static void main(String[] args) {
//传入参数
show(1,2,3,4,5,6,7);
System.out.println();
//传入数组
int[] arr = {1,2,3,4,5,6,7,8};
show(arr);
}
//可变参数
public static void show(int... arr){
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i]+" ");
}
}
}
</span>
态导入可以使被导入的静态变量和静态方法在当前类直接可见,使用这些静态成员无需再给出它们的类名
例如:import staticjava.util.Arrays.*;
注意:当类名重名时,需要指定具体的包名。
当方法重名时,指定具备所属的对象或者类。