------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、Map集合
1、Map集合概念:对应于Collection的单列集合,Map为双列集合,存储的每个元素均为键值对。可以通过键找到该建对应的值。
Map(映射)是一种把键对象和值对象进行映射的集合,它的每一个元素都包含一对键对象和值对象,而值对象仍可以是Map类型,依此类推,这样就形成了多级映射。向Map集合中加入元素时,必须提供一对键对象和值对象
Map集合无法返回对应的迭代器,其内容需要调用方法进行访问。
2、主要格式:
Map<k,v>
key - 此映射所维护的键的类型
value - 映射值的类型
3、Map的遍历方式
假设有一个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集合
A、HashMap :底层为哈希表的双列集合。对键进行唯一约束,放入相同键时,新的 值会将旧的值覆盖。是最常用的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 视图
3、Map.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();
}
}
B、Hashtable:底层为哈希表的集合,已被HashMap替代。Hashtable的Properties用于 配置文件的定义和操作,键和值都是字符串,是集合中可以和IO技术相结合的对象
特点:线程安全,速度慢,不允许存放null键,null值,命名方式不符合标准大驼峰式
C、TreeMap:对键进行排序,排序原理与TreeSet相同的Map集合。
排序方式同TreeSet:1、使键实现Comparable接口,重写compareTo方法,2、创建集合对象时,传入Comparator对象,重写compare方法
二、集合小结
1、Collection
A、List有序,可重复
ArrayList 数据结构是数组.查找快
LinkedList 数据结构是链表.增删快
Vector 数据结构是数组.都很慢
B、Set无序,不可以重复
HashSet 数据结构是哈希表.无序
LinkedHashSet 数据结构是哈希表和链表.
TreeSet 数据结构是二叉树.排序
2、Map
HashMap键无序,不可重复,不安全,速度快
LinkedHashMap键有序,不可重复
Hashtable键无序,不可重复,安全,速度慢
TreeMap键排序,不可重复
3、企业级开发实际情况:
单列使用ArrayList、LinkedList、HashSet
双列使用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、通配符修饰相当于声明了一种变量,它可以作为参数在方法中传递,如collection的containsAll方法
3、使用<?>可以完成类型限定,可参见TreeSet
? extends E 限定类型上限
? super E 限定类型下限
四、Arrays数组工具类与Collections集合工具类
Arrays与Collections为两种工具类,分别对数组或集合进行了常规动作的操作。日常开发中,出现在该两类的功能应该直接调用,而不应手动自己开发。
例如: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、注意:
可变参数与数组类型不能重载,因为二者本质上是一样的
可变参数必须放在最后