黑马程序员———集合2以及部分1.5新特性

------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.*;

注意:当类名重名时,需要指定具体的包名。

当方法重名时,指定具备所属的对象或者类。

 

 

 



 

 


 

 

 

 

 

 

 

 

 

 

 




 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值