黑马程序员——集合基础(二)

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、Map集合

1Map集合概念:对应于Collection的单列集合,Map为双列集合,存储的每个元素均为键值对。可以通过键找到该建对应的值。

Map(映射)是一种把键对象和值对象进行映射的集合,它的每一个元素都包含一对键对象和值对象,而值对象仍可以是Map类型,依此类推,这样就形成了多级映射。向Map集合中加入元素时,必须提供一对键对象和值对象

Map集合无法返回对应的迭代器,其内容需要调用方法进行访问。

2主要格式:

Map<k,v>

key - 此映射所维护的键的类型

value - 映射值的类型

3Map的遍历方式

假设有一个HashMap集合,存储的键和值都是String类型。名称叫hm

A:根据键找值

a:获取所有键的集合

b:遍历键的集合,获取到每一个键

c:根据键找值

代码体现:
Set<String> set = hm.keySet();
for(String key : set) {
	String value = hm.get(key);
	System.out.println(key+"---"+value);
}

B:根据键值对对象找键和值

a:获取所有键值对对象的集合

b:遍历键值对对象的集合,获取到每一个键值对对象

c:根据键值对对象获取键和值

代码体现:
Set<Map.Entry<String,String>> set = hm.entrySet();
for(Map.Entry<String,String> me : set) {
	String key  = me.getKey();
	String value = me.getValue();
System.out.println(key+"---"+value);
}


4主要子类:

A) HashMap:底层为哈希表结构的Map集合。

B) Hashtable:底层为哈希表结构的Map集合。

C) TreeMap:对键进行排序,排序原理与TreeSet相同的Map集合。

D) LinkedHashMap:可预知顺序的HashMap集合

 

AHashMap :底层为哈希表的双列集合。对键进行唯一约束,放入相同键时,新的 值会将旧的值覆盖。是最常用的Map集合。

1特点:线程不安全,速度快,允许存放null键,null值。 

2主要方法

a、添加

public V put(K key, V value) 

public void putAll(Map<? extends K,? extends V> m)

b、删除

public V remove(Object key) 

public void clear()

c、判断

public boolean isEmpty()

public boolean containsKey(Object key)

public boolean containsValue(Object value)

d、获取

public V get(Object key)

public int size()

 

public Set<K> keySet() 返回此映射中所包含的键的 Set 视图

public Collection<V> values() 返回此映射所包含的值的 Collection 视图

public Set<Map.Entry<K,V>> entrySet() 返回此映射所包含的映射关系的 Set 视图

3Map.Entry :键值对映射关系

主要方法

K getKey() 返回与此项对应的键

V getValue() 返回与此项对应的值

V setValue(V value) 用指定的值替换与此项对应的值

int hashCode()返回此映射项的哈希码值

示例1:使用集合进行分类
/*
 * 北京总部
 * 	-JAVAEE班:5个
 * 	-JAVASE班:8个
 * 上海分校
 * 	-JAVAEE:4个
 * 	-JAVASE:7个
 */
package cn.itcast;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;

public class Test2 {

	// HashMap<String, ArrayList<MyClass>>
	public static void main(String[] args) {

		HashMap<String, ArrayList<MyClass>> hashMap = new HashMap<String, ArrayList<MyClass>>();
		
		String s = "北京总部";
		ArrayList<MyClass> bj = new ArrayList<MyClass>();
		bj.add(new MyClass("JAVAEE",5));
		bj.add(new MyClass("JAVASE",8));

		String s2 = "上海分校";
		ArrayList<MyClass> sh = new ArrayList<MyClass>();
		sh.add(new MyClass("JAVAEE",4));
		sh.add(new MyClass("JAVASE",7));
		
		hashMap.put(s, bj);
		hashMap.put(s2, sh);

		Set<Entry<String,ArrayList<MyClass>>> entrySet = hashMap.entrySet();
		
		for (Entry<String, ArrayList<MyClass>> entry : entrySet) {
			String schoolKey = entry.getKey();
			System.out.println(schoolKey);
			ArrayList<MyClass> value = entry.getValue();
			for (MyClass myClass : value) {
				System.out.println(myClass);
			}
		}
	}
}

package cn.itcast;

public class MyClass {

	private String className;
	private int number;
	
	public MyClass() {
		super();
	}
	public MyClass(String className, int number) {
		super();
		this.className = className;
		this.number = number;
	}
	
	@Override
	public String toString() {
		return "MyClass [className=" + className + ", number=" + number + "]";
	}
	
	public String getClassName() {
		return className;
	}
	public void setClassName(String className) {
		this.className = className;
	}
	public int getNumber() {
		return number;
	}
	public void setNumber(int number) {
		this.number = number;
	}
}
示例2:"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数,打印结果:a(1)c(2).....
package important;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/*
思路:
1,将字符串转换成字符数组,因为要对每一个字母进行操作
2,定义一个map集合,因为打印结果的字母有顺序,所以使用TreeMap集合
3,遍历字符数组,
	将每一个字母作为键去查map集合,如果返回null,将该字母和1存入到map集合中
	如果返回不是null,说明该字母在map集合已经存在并有对应次数,那么就获取该次数并进行自增,然后将该字母和自增后的
	次数存入到map集合中,覆盖掉原来键所对应的值
4,将map集合中的数据变成指定的字符串形式返回
*/
public class CharCount {

	public static void main(String[] args) {

		String str = "sssdddffff";
		System.out.println(charCount(str));
	}
	public static String charCount(String str) {
//		将字符串转换成字符数组
		char[] charArr = str.toCharArray();
//		定义一个map集合,因为打印结果的字母有顺序,所以使用TreeMap集合
		TreeMap<Character, Integer> treeMap = new TreeMap<Character,Integer>();
		
		int count=0;
		for (int i = 0; i < charArr.length; i++) {
			if(!(charArr[i]>='a' && charArr[i]<='z' || charArr[i]>='A' && charArr[i]<='Z'))
				continue;
			Integer value = treeMap.get(charArr[i]);
			
			if(value!=null)
				count = value;
			count++;
			treeMap.put(charArr[i],count);//直接往集合中存储字符和数字,自动装箱
			
			count = 0;
		}
		StringBuilder sb = new StringBuilder();
		
		Set<Map.Entry<Character,Integer>> entrySet = treeMap.entrySet();
		Iterator<Map.Entry<Character, Integer>> it = entrySet.iterator();
		while (it.hasNext()) {
			Map.Entry<Character,Integer> entry = it.next();
			Character ch = entry.getKey();
			Integer value = entry.getValue();
			sb.append(ch+"("+value+")");
		}
		
		return sb.toString();
	}
}

BHashtable:底层为哈希表的集合,已被HashMap替代。HashtableProperties用于 配置文件的定义和操作,键和值都是字符串,是集合中可以和IO技术相结合的对象

特点:线程安全,速度慢,不允许存放null键,null,命名方式不符合标准大驼峰式

 

CTreeMap:对键进行排序,排序原理与TreeSet相同的Map集合。

排序方式同TreeSet1使键实现Comparable接口,重写compareTo方法2创建集合对象时,传入Comparator对象,重写compare方法

 

二、集合小结

1Collection

AList有序,可重复

ArrayList 数据结构是数组.查找快

LinkedList 数据结构是链表.增删快

Vector 数据结构是数组.都很慢

BSet无序,不可以重复

HashSet 数据结构是哈希表.无序

LinkedHashSet 数据结构是哈希表和链表.

TreeSet 数据结构是二叉树.排序

2Map

HashMap键无序,不可重复,不安全,速度快

LinkedHashMap键有序,不可重复

Hashtable键无序,不可重复,安全,速度慢

TreeMap键排序,不可重复

3企业级开发实际情况:

单列使用ArrayListLinkedListHashSet

双列使用HashMap

4、集合使用技巧
	是否键值对:
		是:Map
			是否排序:
				是:TreeMap
				否:HashMap
			不知道,HashMap
		否:Collection
			是否唯一:
				是:Set
					是否排序:
						是:TreeSet
						否:HashSet
					不知道,HashSet
				否:List
					增删多:LinkedList
					查询多:ArrayList

					不知道,ArrayList
		不知道,用ArrayList

三、数据结构

1数组结构(array)与链表结构(linked)

数组结构增删慢,查找快

链表结构增删快,查找慢

2(stack)与队列(queue)

栈结构先进后出

堆结构后进先出

3树结构(tree):实现可排序的方式之一

 

四、泛型

1、定义:用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数传递。

2泛型的优点:

a提高程序的安全性

b将运行期问题转移到了编译期

c省去了类型强转的麻烦

d优化了程序设计

3泛型的使用

a直接在指定泛型的地方给出明确的数据类型即可

b在使用泛型后的集合中,迭代器返回时,可以直接返回该种数据类型对象。

c替代了Object类的“任意化”性,避免了程序员必须预知使用时数据类型的情况。

d<>里边什么都不写,叫菱形泛型,即前边是什么类型,后边也是什么类型。

 

4泛型的定义

A泛型类:在类上定义泛型,类中使用该类型

格式:class 类名<T>{使用T}

B泛型方法:在方法上定义泛型,方法内使用泛型,与类无关。

格式:public <T> void method(){使用T}

C泛型接口:在接口上使用泛型。

格式:interface 接口名<T>{}

在类实现接口时明确泛型类型

在类实现接口时仍不明确泛型类型,在创建对象时明确泛型类型

D泛型通配符:<?>可匹配任意一种数据类型

E<?><T>的差别

1通配符修饰的泛型不能直接使用,而<T>可以使用

2通配符修饰相当于声明了一种变量,它可以作为参数在方法中传递,如collectioncontainsAll方法

3使用<?>可以完成类型限定,可参见TreeSet

? extends E  限定类型上限

? super E  限定类型下限

 

四、Arrays数组工具类与Collections集合工具类

ArraysCollections为两种工具类,分别对数组或集合进行了常规动作的操作。日常开发中,出现在该两类的功能应该直接调用,而不应手动自己开发。

例如:asList:将数组变成list集合。

1//如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素

int[] nums = {3,3,4};

System.out.println(Arrays.asList(nums));

2//如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素

Integer[] in = {3,4,5};

System.out.println(Arrays.asList(in));

3、如果将数组变成集合后,不可以使用集合的增删方法,因为数组的长度是固定的

 

五、静态导入和可变参数

1静态导入:导入该类中的所有的静态成员,则该成员可以直接使用。

格式: import static ...静态成员;

2可变参数:即参数可变。

A格式:方法名(参数类型… 参数名) ·

可变参数的本质是一个数组,会将传入的多个参数转成一个数组,而参数名就是数组引用

B注意:

可变参数与数组类型不能重载,因为二者本质上是一样的

可变参数必须放在最后




 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值