Java-集合(set,map)

集合体系图 Java-集合(set,map) set集合存储的元素是无序的,不可以重复的 HashSet<String> sh = new HashSet<>(); sh.add("a"); sh.add("b"); sh.add("c"); sh.add("c"); System.out.println(sh);   Java-集合(set,map)   HashSet存储自定义对象保证元素唯一性 重写hashCode()和equal()方法 自动生成这两种方法即可   HashSet如何保证元素唯一性的原理 Java-集合(set,map) /* * 为什么是31? * 1,31是质数 * 2,31既不大也不小 * 3,31是2的五次方-1 */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) //调用的对象和传入的对象是同一个对象 return true; //直接返回true if (obj == null) //传入的对象为null return false; //返回false if (getClass() != obj.getClass()) //判断两个对象的字节码文件是否是同一个 return false; //如果不是直接返回false Person other = (Person) obj; //向下转型 if (age != other.age) //调用对象的年龄不等于传入对象的年龄 return false; //返回false if (name == null) { //调用对象的姓名为null if (other.name != null) //传入对象的姓名不为null return false; //返回false } else if (!name.equals(other.name)) //调用对象的姓名不等于传入对象的姓名 return false; return true; }     LinkedHashSet的特点 底层是链表实现的,是set集合中唯一一个能保证怎么存怎么取的集合对象 因为是HashSet的子类,所以也是保证元素唯一的,与HashSet的原理一样 /* * 获取10个1到20的随机数,要求随机数不能重复,并把最终结果输出到控制台 * 1,用Random生成随机数 * 2,要求不能重复,所以我们使用HashSet * 3,需要10个数,则集合的size小于10就可以继续存放,>=10就不能再存储 * 4,用Random类中的nextInt(n)方法获取1到20的随机数,并把他们保存在集合中 * 5,遍历HashSet */ public class Demo1 { public static void main(String[] args) { Random r = new Random(); HashSet<Integer> hs = new HashSet<>(); while(hs.size()<10) { int num = r.nextInt(20)+1; hs.add(num); } for (Integer integer : hs) { System.out.println(integer); } } }   /* * 将集合中的重复元素去掉 */ public class Test2 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("b"); list.add("a"); list.add("c"); getSingle(list); System.out.println(list); } public static void getSingle(List<String> list) { LinkedHashSet<String> lhs = new LinkedHashSet<>(); // lhs.addAll(list); String[] arr = (String[]) list.toArray(new String[0]); for (String c : arr) { lhs.add(c);//去重 } list.clear();//清空原集合中的内容 list.addAll(lhs);//把去重后的元素加入到list中 } }   TreeSet TreeSet集合是用来对元素进行排序的,同样也可以保证元素的唯一
  • 当compareTo方法返回 0 的时候,集合中只有一个元素;
  • 当compareTo方法返回 正数 的时候,集合会怎么存怎么取;
  • 当compareTo方法返回 负数 的时候,集合中会倒序存储。
Java-集合(set,map)   当compareTo方法返回 this.age-o.age时 Java-集合(set,map)   TreeSet<Person> ts = new TreeSet<>(); ts.add(new Person("张珊",22)); ts.add(new Person("杨振",23)); ts.add(new Person("安琪",23)); ts.add(new Person("盼盼",25)); ts.add(new Person("张珊",22)); System.out.println(ts);   @Override public int compareTo(Person o) { int num=this.age-o.age; //年龄是比较的主要条件 return num==0?this.name.compareTo(o.name):num; //姓名是次要条件 }   Java-集合(set,map)   @Override public int compareTo(Person o) { int length = this.name.length()-o.name.length(); //比较长度为主要条件 int num = length== 0 ? this.name.compareTo(o.name):length; //比较内容为次要条件 return num==0?this.age-o.age:num; //比较年龄也为次要条件 } 存储Integer类型的元素并遍历 TreeSet<Integer> ts = new TreeSet<>(); ts.add(1); ts.add(3); ts.add(3); ts.add(1); ts.add(2); ts.add(1); System.out.println(ts);   Java-集合(set,map)     TreeSet保证元素唯一和比较器排序的原理 class CompareByLen implements Comparator<String>{ @Override public int compare(String s1, String s2) { //按照字符串的长度进行比较 int num=s1.length()-s2.length(); //长度为主要条件 return num==0?s1.compareTo(s2):num; //内容为次要条件 } }   TreeSet<String> ts = new TreeSet<>(new CompareByLen());//CompareByLen c = new CompareByLen(); ts.add("aaaaaa"); ts.add("bbbb"); ts.add("cc"); ts.add("csca"); ts.add("vfda"); System.out.println(ts);   Java-集合(set,map)   TreeSet原理 1.特点 Treeset是用来排序的,可以指定一个顺序,对象存入之后会按照指定的顺序排列。 2使用方式 a.自然顺序(Comparable) TreeSet类的add()方法中会把存入的对象提升为Conparable类型 调用对象的compareT0()方法和集合中的对象比较 根据compare T0()方法返回的结果进行存储 b.比较器顺序(Comparator) 创建TreeSet的时候可以制定一个Comparator 如果传入了 comparator的子类对象,那么TreeSet就会按照比较a中的顺序排序 add()方法内部会自动a用comparator接口中compare ()方法排序 调用的对象是compare方法的第一个参数集台中的对象是compare方法的第二个参数 c. 两种方式的区别 TreeSet构造函数什么都不传,默认按照类中Comparable的顺序(没有就报classcastException) TreeSet如果传入comparator.优先按照comparator   eg : 在一个集合中存储了无序并且重复的字符串,定义一个方法,让其有序,而且还不能重复 import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.TreeSet; /* * 在一个集合中存储了无序并且重复的字符串,定义一个方法,让其有序,而且还不能重复 */ public class Test3 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("aaa"); list.add("ccc"); list.add("ddd"); list.add("ffffffff"); list.add("heima"); list.add("itcast"); list.add("aaa"); list.add("aaa"); sort(list); System.out.println(list); } /* * 定义方法进行排序并保留重复 * 1,创建TreeSet集合对象,因为String本身具备比较功能,但是重复不会保留,所以我们要使用比较器 * 2,将list集合所有的元素添加到TreeSet集合中,对其排序,保留重复 * 3,清空list集合 * 4,将TreeSet排好序的元素添加到list中 */ public static void sort(List<String> list) { TreeSet<String> ts = new TreeSet<>(new Comparator<String>() { @Override public int compare(String s1, String s2) { int num=s1.compareTo(s2); return num==0?1:num; } }); ts.addAll(list); list.clear(); list.addAll(ts); } }     Map集合 A:Map接口概述 查看API可以知道: * 将键映射到值的对象 * 一个映射不能包含重复的键 * 每个键最多只能映射到一个值 B:Map接口和Collection接口的不同 * Map是双列的,Collection是单列的 * Map的键唯一,Collection的子体系Set是唯一的 * Map集合的数据结构值针对键有效,跟值无关;Collection集合的数据结构是针对元素有效   HashSet与HashMap,都是双列集合,只不过HashSet将value隐藏不显示。   Map集合的功能概述 * a:添加功能 * V put(K key,V value):添加元素。 * 如果键是第一次存储,就直接存储元素,返回null * 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值 * b:删除功能 * void clear():移除所有的键值对元素 * V remove(Object key):根据键删除键值对元素,并把值返回 * c:判断功能 * boolean containsKey(Object key):判断集合是否包含指定的键 * boolean containsValue(Object value):判断集合是否包含指定的值 * boolean isEmpty():判断集合是否为空 * d:获取功能 * Set<Map.Entry<K,V>> entrySet(): * V get(Object key):根据键获取值 * Set<K> keySet():获取集合中所有键的集合 * Collection<V> values():获取集合中所有值的集合 * e:长度功能 * int size():返回集合中的键值对的个数   Map集合的遍历之键找值
  1. 获取所有键的集合
  2. 遍历键的集合,获取到每一个键
  3. 根据键找值
Set<String> setKey = map.keySet(); Iterator it = setKey.iterator(); while(it.hasNext()) { String key = (String) it.next(); Integer i = map.get(key); System.out.println(key+"="+i);} 或 for(Entry<String,Integer> en : hm.entrySet()) { System.out.println(en.getKey() + "=" + en.getValue()); } Map集合的遍历之键值对对象找键和值
  1. 获取所有键值对对象的集合
  2. 遍历键值对对象的集合,获取到每一个键值对对象
  3. 根据键值对对象找键和值
Set<Map.Entry<String, Integer>> en = map.entrySet(); Iterator<Map.Entry<String, Integer>> it = en.iterator(); while(it.hasNext()) { Map.Entry<String, Integer> m = it.next(); String key = m.getKey(); Integer value = m.getValue(); ystem.out.println(key+"="+value);} 或 for(Map.Entry<String, Integer> e : map.entrySet()) { System.out.println(e.getKey()+"="+e.getValue()); }   LinkedHashMap 底层是链表,实现的可以保证怎么存就怎么取   HashMap和Hashtable的区别 1. Hashtable是JDK1.0版本出现的,是线程安全的,效率低 HashMap是JDK1.2版本出现的,是线程不安全的,效率高 2. Hashtable不可以存储null键和null值 HashMap可以存储null键和null值   Collections工具类的概述和常见方法讲解 针对集合操作的工具类 Collections成员方法
  • public static <T> void sort(List<T> list) //排序
  • public static <T> int binarySearch(List<?> list,T key) //二分查找
  • public static <T> T max(Collection<?> coll) //根据默认排序找出最大值
  • public static void reverse(List<?> list) //反转
  • public static void shuffle(List<?> list) //随机置换,洗牌
    泛型固定上边界 class World { } class Person extends World { } class Teacher extends Person { }   Java-集合(set,map)   泛型固定下边界 Java-集合(set,map)     类型区别 HashMap 最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null(多条会覆盖);允许多条记录的值为 Null。非同步的。 TreeMap 能够把它保存的记录根据键(key)排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。  Hashtable 与 HashMap类似,不同的是:key和value的值均不允许为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。  LinkedHashMap 保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。    三种遍历总结
  1. 增强for循环使用方便,但性能较差,不适合处理超大量级的数据。
  2. 迭代器的遍历速度要比增强for循环快很多,是增强for循环的2倍左右。
  3. 使用entrySet遍历的速度要比keySet快很多,是keySet的1.5倍左右。
  常用API
clear() 从 Map 中删除所有映射
remove(Object key) 从 Map 中删除键和关联的值
put(Object key, Object value) 将指定值与指定键相关联
putAll(Map t) 将指定 Map 中的所有映射复制到此 map
entrySet() 返回 Map 中所包含映射的 Set 视图。Set 中的每个元素都是一个 Map.Entry 对象,可以使用 getKey() 和 getValue() 方法(还有一个 setValue() 方法)访问后者的键元素和值元素
keySet() 返回 Map 中所包含键的 Set 视图。删除 Set 中的元素还将删除 Map 中相应的映射(键和值)
values() 返回 map 中所包含值的 Collection 视图。删除 Collection 中的元素还将删除 Map 中相应的映射(键和值)
get(Object key) 返回与指定键关联的值
containsKey(Object key) 如果 Map 包含指定键的映射,则返回 true
containsValue(Object value) 如果此 Map 将一个或多个键映射到指定值,则返回 true
isEmpty() 如果 Map 不包含键-值映射,则返回 true
size() 返回 Map 中的键-值映射的数目
 

上一篇:set集合 hashset treeset


下一篇:LeetCode【寻找第3大的数字】