集合Set
Set不保存重复元素。Set最常用的用途是测试归属性,可以用来查询某个对象是否在一个Set中,通常会选择HashSet,该实现针对快速查找进行了优化。
Set具有与Collection相同的接口,没有额外的功能,实际上,Set就是一个Collection,只是行为不同。
存放Integer对象的HashSet:
import java.util.*;
public class IntegerSet {
public static void main(String[] args) {
Random rand = new Random();
Set<Integer> chs = new HashSet<>();
for (int i = 0; i < 10000; i++) {
chs.add(rand.nextInt(10));
}
System.out.println(chs);
}
}
结果:
可以看到,0-9之间的10000个随机整数被添加到Set中,可想象每个值都被重复了很多次。但从输出结果来看,每个数只有一个实例出现在结果中。
早期的Java版本出于对速度的追求,对于HashSet的输出没有可辨别的顺序,使用的是散列。而TreeSet将元素存储在红-黑树数据结构中,LinkedHashSet因为查询速度的原因也使用了散列,但看起来使用了链表来维护元素的插入顺序。
如果HashSet中存放的是String对象,结果输出时一般不会排序,如果要对结果进行排序,可采用TreeSet:
import java.util.Set;
import java.util.TreeSet;
public class TestTreeSet {
public static void main(String[] args) {
Set<String> chs = new TreeSet<>();
for (int i = 0; i < 100; i++) {
chs.add("zzz");
chs.add("rrr");
chs.add("aaa");
}
System.out.println(chs);
}
}
结果:
最常见的操作就是使用contains()测试成员归属性,以下展示测试成员归属以及移除元素和元素组操作:
import java.util.*;
public class SetOperations {
public static void main(String[] args) {
Set<String> chs = new HashSet<>();
Collections.addAll(chs,"A,B,C,D,E,F".split(","));
System.out.println("C是否在chs中:"+chs.contains("C"));
System.out.println("H是否在chs中:"+chs.contains("H"));
Set<String> chs2 = new HashSet<>();
Collections.addAll(chs2,"C,D,E".split(","));
System.out.println("chs2是否在chs中:"+chs.containsAll(chs2));
System.out.println("chs:"+chs);
chs.remove("F");
System.out.println("chs移除元素F:"+chs);
chs.removeAll(chs2);
System.out.println("chs移除元素组chs2:"+chs);
}
}
结果:
集合Map
将对象映射到其他对象的能力是解决编程问题的有效办法。以下我们使用Map来检验Random类的随机性,其中键是Random生成的随机数,值是该数出现的次数。
import java.util.*;
public class MapTestRandom {
public static void main(String[] args) {
Random random = new Random();
Map<Integer,Integer> chs = new HashMap<>();
for (int i = 0; i < 1000; i++) {
int r = random.nextInt(10);
Integer count = chs.get(r);
chs.put(r,count == null ? 1 : count+1);
}
System.out.println(chs);
}
}
结果:
从结果来看,Random类生成机制还是比较完美的,分布比较平均。
接下来使用containsKey()和containsValue()方法测试一个Map,查看是否包含某个键或值:
import java.util.*;
public class PetMap {
public static void main(String[] args) {
Map<String,String> petMap = new HashMap<>();
petMap.put("Cat","Kitty");
petMap.put("Dog","Tom");
System.out.println(petMap.containsKey("Cat"));
System.out.println(petMap.containsValue("Tom"));
String chs = petMap.get("Cat");
System.out.println(petMap.containsValue(chs));
}
}
结果:
Map和数组以及其他Collection一样,可以轻松扩展到多个维度,只需创建一个值为Map的Map,能够很容易将集合组合起来快速生成强大的数据结构。假设由几个人,每个人有不同的宠物举例:
import java.util.*;
public class MapOfList {
public static final Map<String,List<String>> chs = new HashMap<>();
static {
chs.put("aaa",Arrays.asList("kitty","Tom","Jerry"));
chs.put("bbb",Arrays.asList("kitty2","Tom2","Jerry2"));
chs.put("ccc",Arrays.asList("kitty3","Tom3","Jerry3"));
}
public static void main(String[] args) {
System.out.println("chs:"+chs.keySet());
System.out.println("Pets:"+chs.values());
System.out.println(chs);
}
}
结果: