----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
一、Set集合
1、什么是Set集合?
Set是Collection的一种,即Set是Collection的子接口。
2、Set有什么特性:
1.它不要求顺序,无重复元素
2.没索引
3、Set有五种实现类:
1.HashSet 2.TreeSet 3.LinkedHashSet
4、HashSet TreeSet LinkedHashSet它们分别有什么特征?
HashSet特征:
1.它的底层是用hash表数据结构,线程不同步,无序,高效。
2.HashSet集合保证了元素的唯一性:通过元素的HasCode方法和equals方法完成的。
3.当元素的HashCode值相同时,才继续判断元素的equals值是否是否为true。如果为true,那么视为相同元素,不存储。如果为false,那么存储。
4.如果HashCode不同,那么不比较equas方法,直接存储,从而直接提高对象比较的速度。
HashCode实例:
import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class ComparableDemo { /** * @param args */ public static void main(String[] args) { 创建一个Set集合的引用指向HashSet的对象 Set se = new HashSet(); //实例化1 Person p1 = new Person("ZhangSan", 23, "male"); //实例化2 Person p2 = new Person("LiSi", 32, "female"); //实例化3 Person p3 = new Person("WangWu", 28, "male"); //实例化4 Person p4 = new Person("ZhaoLiu", 23, "female"); //实例化5 Person p5 = new Person("ZhangSan", 23, "male"); //将实例化对象添加进集合中 se.add(p1); se.add(p2); se.add(p3); se.add(p4); se.add(p5); //迭代集合中的元素 Iterator<Person> it = se.iterator(); //判断集合中是否存在元素 while (it.hasNext()) { //迭代下一个元素 Person per = it.next(); //打印元素 System.out.println(per); } } } package SetDemo; //创建一个实体类 public class Person { private String name; private int age; private String sex; public Person(String name, int age, String sex) { super(); this.name = name; this.age = age; this.sex = sex; } public Person() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } // 重写Object的tostring方法 @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]"; } // Object的hashCode方法 @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((sex == null) ? 0 : sex.hashCode()); return result; } // 重写Objet的equasl方法 @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (sex == null) { if (other.sex != null) return false; } else if (!sex.equals(other.sex)) return false; return true; } } 结果为: Person [name=WangWu, age=28, sex=male] Person [name=LiSi, age=32, sex=female] Person [name=ZhaoLiu, age=23, sex=female] Person [name=ZhangSan, age=23, sex=male]
总结:hasHSet,底层是哈希表的数据结构,使用了HasCode和equals方法保证了元素的唯一性。
LinkedHashSet特征:
1.LinkedHashSet是HashSet的子类,底层也是使用了哈希表的数据结构。
2.它的数据是有序的,只不过它迭代的顺序是添加的顺序,因为它底层用链表来记录添加元素的顺序。迭代时,再使用添加时顺序迭代。
LinkedHashSet实例:
public class ComparableDemo { /** * @param args */ public static void main(String[] args) { // 创建一个Set集合的引用指向LinkedHashSet的对象 Set se = new LinkedHashSet(); // 实例化1 Person p1 = new Person("ZhangSan", 23, "male"); // 实例化2 Person p2 = new Person("LiSi", 32, "female"); // 实例化3 Person p3 = new Person("WangWu", 28, "male"); // 实例化4 Person p4 = new Person("ZhaoLiu", 23, "female"); // 实例化5 Person p5 = new Person("ZhangSan", 23, "male"); // 将实例化对象添加进集合中 se.add(p1); se.add(p2); se.add(p3); se.add(p4); se.add(p5); // 迭代集合中的元素 Iterator<Person> it = se.iterator(); // 判断集合中是否存在元素 while (it.hasNext()) { // 迭代下一个元素 Person per = it.next(); // 打印元素 System.out.println(per); } } } 结果为: Person [name=ZhangSan, age=23, sex=male] Person [name=LiSi, age=32, sex=female] Person [name=WangWu, age=28, sex=male] Person [name=ZhaoLiu, age=23, sex=female]
总结:LinkedHashSet集合是有序的,它结果的顺序是你添加元素的顺序,因为它底层用链表记录了添加元素的顺序。
TreeSet特征:
1.它的元素是有序的,无重复元素。它的线程是不安全的
2.它底层使用了二叉树的数据结构。
3.二叉树的原理:
1.它添加的第一个元素时根节点。
2.再添加第二个元素时,与根节点进行比较,如果比根节点大,那么就放在根节点的右侧的子节点位置,如果比根节点小,那么就放在根节点的左侧子节点的位置,如果相等,那么就添加失败。
3.添加第三个元素时,先与根节点进行比较,如果比根小,再与根的左侧比较,比它小放在它的左侧子节点,比它大放在它的右侧子节点。相等的话,添加失败。
如果比根答,再与根的右侧比较,比它大放在它的右侧子节点,比它小放在它的左侧子节点。相等的话,添加失败。
4.遍历二叉树的原则:先遍历左,然后当前,最后是右。
5.TreeSet有序的原则:(1)TreeSet有比较器,那么使用比较器来比较元素 (2)TreeSet没有比较器,实现Comparable接口,让它具有自然顺序。
TreeSet实例:
import java.util.Comparator; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; public class ComparableDemo { /** * @param args */ public static void main(String[] args) { Comparator<Person> my = new Mycompare(); // 创建一个Set集合的引用 Set<Person> se = new TreeSet<Person>(my); // 实例化1 Person p1 = new Person("ZhangSan", 23, "male"); // 实例化2 Person p2 = new Person("LiSi", 32, "female"); // 实例化3 Person p3 = new Person("WangWu", 28, "male"); // 实例化4 Person p4 = new Person("ZhaoLiu", 23, "female"); // 实例化5 Person p5 = new Person("ZhangSan", 23, "male"); // 将实例化对象添加进集合中 se.add(p1); se.add(p2); se.add(p3); se.add(p4); se.add(p5); // 迭代集合中的元素 Iterator<Person> it = se.iterator(); // 判断集合中是否存在元素 while (it.hasNext()) { // 迭代下一个元素 Person per = it.next(); // 打印元素 System.out.println(per); } } } class Mycompare implements Comparator<Person> { @Override public int compare(Person o1, Person o2) { // 从年龄开始比较 int age = o1.getAge() - o2.getAge(); if (age != 0) { return age; } // 如果年龄相等,从性别比较 String o1sex = o1.getSex(); String o2sex = o2.getSex(); // 如果o1性别为男 if (o1sex.equals("male")) { // 和如果o2性别为女,返回1,男大 if (o2sex.equals("female")) { return -1; } } else { // 否则o2的性别为男时,o2比o1大 if (o2sex.equals("male")) { return 1; } } return o1.getName().compareTo(o2.getName()); } } 结果: Person [name=ZhangSan, age=23, sex=male] Person [name=ZhaoLiu, age=23, sex=female] Person [name=WangWu, age=28, sex=male] Person [name=LiSi, age=32, sex=female]
总结:在进行比较时,如果判断元素不唯一,比如,同姓名,同年龄,才视为同一个人。在判断时,需要分主要条件和次要条件,当主要条件相同时,再判断次要条件,按照次要条件排序。
二、Map集合
1、什么是Map集合?
Map是双列集合,它是以Entry属性的键值对(Key.Value)的对象存在的。
2、Map有什么特性?
1.它是双列集合,Key键不能重复,Value值可以重复。
3、Map有五种实现类。
他们分别是:HashMap、TreeMap、HashTable、properties、LinkedHashMap、
HashMap特征:
1.它的底层是用哈希表的数据结构
2.因为它的底层使用的是哈希表,所以它必须重写HashCode和equals方法。
3.线程不同步的。可以存储null键,null值
HashMap实例:
import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; public class MapDemo { /* * 统计候选人票数是一个道理 所有投票人把自己心中的人选提交上来。 * * 张三把所有选票上的名字读一次,即循环遍历所有选票,并获取名字。 李四听到张三念一个,就在纸上找这个名字是否已经存在,如果存在,那么把票数+1 * 如果不存在,那么把这个名字写上,在票数上写1。 */ public static void main(String[] args) { // 创建后候选人 String s1 = "ZhanSan LiSi LiSi ZhanSan WangWu LiSi LiSi ZhanSan 张国荣"; // 将返回的map创建成一个新的map集合 Map<String, Integer> mp = fun(s1); // 将map集合转换为Set集合 Set<Map.Entry<String, Integer>> entryset = mp.entrySet(); // 遍历map集合 for (Entry<String, Integer> s2 : entryset) { // 获取键 String key = s2.getKey(); // 获取值 Integer vlaue = s2.getValue(); // 将键和值打印 System.out.println(key + "::" + vlaue); } } public static Map fun(String s1) { // 创建一个Map集合Map<String(候选人名字), Integer(票数)> Map<String, Integer> mp = new HashMap<String, Integer>(); // 把参数字符串分隔成字符串数组;String[] names=s.split(" "); String[] names = s1.split(" "); // 循环遍历这个names for (int i = 0; i < names.length; i++) { int tokce = 1; // 判断mp中是否包含这个名字 if (mp.containsKey(names[i])) { // 如果存在,获取票数(获取值),给值+1 tokce = mp.get(names[i]) + 1; } mp.put(names[i], tokce); } return mp; } } 结果为: WangWu::1 张国荣::1 ZhanSan::3 LiSi::4
总结:Map自身没有遍历的方法,必须将其转换为Set集合然后遍历,转换的方法有两种:keySet();entrySet()
TreeMap特征:
1.它的底层是用二叉树结构
2.有序!使用键类型的自然顺序,或者TreeMap的比较器排序;
多重Map集合实例:
import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; public class MapDemo2 { /** * @param args */ public static void main(String[] args) { // 创建一个大map中泛型左边类型的小map Map<String, String> gmsz = new LinkedHashMap<String, String>(); // 创建大map中泛型的右边类型的小map Map<String, String> hjfw = new LinkedHashMap<String, String>(); // 创建大map Map<String, Map<String, String>> mj = new LinkedHashMap<String, Map<String, String>>(); // 向左边类型map添加元素 gmsz.put("光明左使", "杨逍"); gmsz.put("光明右使", "范遥"); // 往右边类型map添加元素 hjfw.put("紫衫龙王", "黛绮丝"); hjfw.put("白眉鹰王", "殷天正"); hjfw.put("金毛狮王", "谢逊"); hjfw.put("青翼蝠王", "韦一笑"); mj.put("光明使者", gmsz); mj.put("护教法王", hjfw); // 将大的map转换成set集合 Set<String> keyset = mj.keySet(); /* * Iterator<String> it = keyset.iterator(); * * while (it.hasNext()) { String s1 = it.next(); Map<String, String> key * = mj.get(s1); System.out.println(key); } */ // 使用高级for迭代set集合 for (String st : keyset) { // 通过map的get方法获取键,返回右边小map的集合类型 Map<String, String> st2 = mj.get(st); //将其打印 System.out.println(st2); } } } 结果: {光明左使=杨逍, 光明右使=范遥} {紫衫龙王=黛绮丝, 白眉鹰王=殷天正, 金毛狮王=谢逊, 青翼蝠王=韦一笑}
总结:Map集合主要是以键值对的形式存在,Entry就是键值对对象,Map结果都是以{}表示的,和list、set的不同。遍历Set的两种方法。KeySet和entrySet。KeySet中遍历的返回的是Value值的类型,entrySet中遍历返回的是Entry对象的返回值类型
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------