除Collection集合外,JAVA还有另一大体系集合,Map集合,相较于Collection集合,Map集合存储元素方式不同,该集合具有key(键)-value(值)映射关系,存储的元素是成对存在的对象,而key值不允许重复。
1.map和Collection集合一样都是一个接口
2.map集合包括3个实现类(HashMap,Hashtable,TreeSet)Hashtable用的很少 ,其中HashMap包含一个子类LinkedHashMap
3.HashTable --线程安全,不太常用 TreeMap---key值按一定的顺序排序 ,添加或获取元素时性能较HashMap慢因为需求维护内部的红黑树,用于保证key值的顺序
LinkedHashMap 他继承HashMap。
LinkedHashMap是有序的,且默认为插入顺序。 当我们希望有顺序地去存储key-value时,就需要使用LinkedHashMap了
首先我们来看看HashMap,该集合是Map集合典型的实现类,也是我们现在使用最多的他和HasSet 相同,都使用了Hash算法,我们可以用HashCode, 在通过equals()方法比较两个元素的内容
HasHCode 和 equals()方法 在实体类中右击找到source点击找到HasHCode 和 equals()就可以自动生成
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
上面就说到,Map集合以键值对的方式存储成对的对象,现在就看看它如何存储:
public class MapText {
private Map<String , String> map=new HashMap<String, String>();
@Before
public void setup() {
map.put("1", "zs");
map.put("2", "ls");
map.put("3", "ww");
map.put("4", "zi");
}
}
map集合添加元素使用方法是put(key,value),其中key是不能重复的,而移除元素的remove()方法也是根据key值进行移除
在map集合中我们可以通过键获取所对应的值(代码如下)
//通过键获取值
@Test
public void demol() {
System.out.println(map.get("3"));
}
运行结果;
同样的,Map集合也可以使用增强for循环或是迭代器Iterator进行遍历,但由于Map集合本身的特殊性,可以分成三种方式进行遍历。
第一种迭代器的方式 通过键获取到map集合中的所有值。
@Test
public void demo2() {
Iterator<String> it = map.keySet().iterator();
while(it.hasNext()) {
String key = it.next();
System.out.println(map.get(key));
}
}
运行结果如下
第二种;
@Test
public void demo9() {
Iterator<Entry<String, String>> it = map.entrySet().iterator();
while(it.hasNext()) {
Entry<String, String> entry = it.next();
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
运行结果如下;通过while循环找到键在通过Entry<String, String> entry = it.next();
获取没个键对应的值最后拼接输出;
第三种;
@Test
public void demo10() {
map.forEach((key, val) -> System.out.println(key + ":" +val));
}
运行结果和上图一样;
这样输出方法更简便。
map集合中的TreeMap;
package com.zking.jee02list;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import org.junit.Before;
import org.junit.Test;
import com.zking.jee02list.model.Student;
public class TreeMapTest {
private TreeMap<String,Student> treeMap;
@Before
public void setup() {
treeMap = new TreeMap<String,Student>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
// TODO Auto-generated method stub
// 负数 0 正数
return o1.compareTo(o2);
}
});
treeMap.put("1", new Student(1, "zs"));
treeMap.put("2", new Student(3, "ls"));
treeMap.put("3", new Student(2, "ww"));
treeMap.put("4", new Student(4, "zl"));
}
@Test
public void demo1() {
treeMap.forEach((key, val) -> System.out.println(key + ":" + val));
}
@Test
public void linkedHashMap() {
//有序的
Map<String, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("name1", "josan1");
linkedHashMap.put("name3", "josan3");
linkedHashMap.put("name2", "josan2");
Set<Entry<String, String>> set = linkedHashMap.entrySet();
Iterator<Entry<String, String>> iterator = set.iterator();
while(iterator.hasNext()) {
Entry entry = iterator.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
System.out.println("key:" + key + ",value:" + value);
}
}
}
HashSet集合是无序的,有时需要一个有序的集合,这时可以使用TreeSet.
在使用TreeSet存储对象的时候, add()方法内部就会自动调用compareTo()方法进行比较, 根据比较结果使用二叉树形式进行存储。(TreeSet内部是直接使用TreeMap进行实现的)
package com.zking.jee02list;
import java.util.Comparator;
import java.util.TreeSet;
import org.junit.Test;
import com.zking.jee02list.model.Student;
/**
* HashSet集合是无序的,有时需要一个有序的集合,这时可以使用TreeSet.
* 在使用TreeSet存储对象的时候, add()方法内部就会自动调用compareTo()方法进行比较,
* 根据比较结果使用二叉树形式进行存储。(TreeSet内部是直接使用TreeMap进行实现的)
* @author L
*/
public class TreeSetTest {
//如果保存的是数值型,则按数值排序
@Test
public void demo1() {
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(1);
treeSet.add(5);
treeSet.add(3);
treeSet.add(2);
treeSet.add(4);
treeSet.forEach(t -> System.out.println(t));
}
//如果保存的是字符,则按字符对应的ASCII进行排序
@Test
public void demo2() {
TreeSet<String> ts = new TreeSet<>();
ts.add("a");
ts.add("d");
ts.add("b");
ts.add("c");
ts.forEach(t->System.out.println(t));
}
@Test
public void demo3() {
//如果是自定义的类型,则需要传入比较器,或是在自定义的类中实现比较接口Comparable
TreeSet<Student> ts = new TreeSet<>();
ts.add(new Student(1, "zs"));
ts.add(new Student(3, "li"));
ts.add(new Student(5, "ww"));
ts.add(new Student(2, "zl"));
ts.add(new Student(4, "tq"));
ts.forEach(t->System.out.println(t));
}
}