集合框架(下)

来源:互联网 发布:淘宝代金券 编辑:程序博客网 时间:2024/05/21 20:28

JDK5的新特性:自动拆装箱,泛型,增强for,静态导入,可变参数,枚举

泛型:是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。参数化类型,把类型当作参数一样的传递。
格式:
  <数据类型>
  此处的数据类型只能是引用类型。
 好处:
  A:把运行时期的问题提前到了编译期间
  B:避免了强制类型转换
  C:优化了程序设计,解决了黄色警告线
泛型一般来说就是在集合中使用
泛型的定义:
 A:定义在类上
 B:定义在方法上
 C:定义在接口上
泛型高级(通配符)
?:任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E:向下限定,E及其子类
? super E:向上限定,E极其父类

增强for:是for循环的一种。
格式:
  for(元素数据类型 变量 : 数组或者Collection集合) {
   使用变量即可,该变量就是元素
    }
好处:简化了数组和集合的遍历。
弊端: 增强for的目标不能为null。
解决增强for目标不能为null
 对增强for的目标先进行不为null的判断,然后在使用。
静态导入:
格式:import static 包名….类名.方法名;
import static java.lang.Math.pow;
可以直接导入到方法的级别
静态导入的注意事项:
  A:方法必须是静态的
  B:如果有多个同名的静态方法,容易不知道使用谁?这个时候要使用,必须加前缀。由此可见,意义不大,所以一般不用,但是要能看懂。
可变参数:定义方法的时候不知道该定义多少个参数
格式:
  修饰符 返回值类型 方法名(数据类型…  变量名){
  }
  注意:
   这里的变量其实是一个数组
   如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个
public static <T> List<T> asList(T... a):把数组转成集合
注意事项:
  虽然可以把数组转成集合,但是集合的长度不能改变。
 Collection
  |--List
   有序(存储顺序和取出顺序一致),可重复
  |--Set
   无序(存储顺序和取出顺序不一致),唯一
HashSet:它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。
注意:虽然Set集合的元素无序,但是,作为集合来说,它肯定有它自己的存储顺序,
而你的顺序恰好和它的存储顺序一致,这代表不了有序,你可以多存储一些数据,就能看到效果。
HashSet:存储字符串并遍历
问题:为什么存储字符串的时候,字符串内容相同的只存储了一个呢?
 通过查看add方法的源码,我们知道这个方法底层依赖 两个方法:hashCode()和equals()。
步骤:
  首先比较哈希值
  如果相同,继续走,比较地址值或者走equals()
  如果不同,就直接添加到集合中 
按照方法的步骤来说: 
  先看hashCode()值是否相同
   相同:继续走equals()方法
    返回true:说明元素重复,就不添加
    返回false:说明元素不重复,就添加到集合
   不同:就直接把元素添加到集合
如果类没有重写这两个方法,默认使用的Object()。一般来说不同相同。
而String类重写了hashCode()和equals()方法,所以,它就可以把内容相同的字符串去掉。只留下一个。
注意了:
  你使用的是HashSet集合,这个集合的底层是哈希表结构。
  而哈希表结构底层依赖:hashCode()和equals()方法。
  如果你认为对象的成员变量值相同即为同一个对象的话,你就应该重写这两个方法。
TreeSet:能够对元素按照某种规则进行排序。
排序有两种方式
A:自然排序
B:比较器排序
TreeSet集合的特点:排序和唯一
通过观察TreeSet的add()方法,我们知道最终要看TreeMap的put()方法。
TreeSet存储自定义对象并保证排序和唯一。
TreeSet集合保证元素排序和唯一性的原理
唯一性:是根据比较的返回是否是0来决定。
排序:
   A:自然排序(元素具备比较性)
   让元素所属的类实现自然排序接口 Comparable重写compareTo()方法
  B:比较器排序(集合具备比较性)
   让集合的构造方法接收一个比较器接口的子类对象 Comparator重写compare()方法
Map集合的特点:
  将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
Map集合和Collection集合的区别?
  Map集合存储元素是成对出现的,Map集合的键是唯一的,值是可重复的。
  Collection集合存储元素是单独出现的,Collection的儿子Set是唯一的,List是可重复的。
注意:
  Map集合的数据结构值针对键有效,跟值无关 
  Collection集合的数据结构是针对元素有效
Map集合的功能概述:
 1:添加功能
  V put(K key,V value):添加元素。修改键对应的值
   如果键是第一次存储,就直接存储元素,返回null
   如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
 2:删除功能
  void clear():移除所有的键值对元素
  V remove(Object key):根据键删除键值对元素,并把值返回
 3:判断功能
  boolean containsKey(Object key):判断集合是否包含指定的键
  boolean containsValue(Object value):判断集合是否包含指定的值
  boolean isEmpty():判断集合是否为空
 4:获取功能
  Set<Map.Entry<K,V>> entrySet():获取集合中键值对关系的集合
  V get(Object key):根据键获取值
  Set<K> keySet():获取集合中所有键的集合
  Collection<V> values():获取集合中所有值的集合
 5:长度功能
  int size():返回集合中的键值对的对数
HashMap:是基于哈希表的Map接口实现。
 哈希表的作用是用来保证键的唯一性的。
TreeMap:是基于红黑树的Map接口的实现。
1:Hashtable和HashMap的区别?
Hashtable:线程安全,效率低。不允许null键和null值
HashMap:线程不安全,效率高。允许null键和null值
2:List,Set,Map等接口是否都继承子Map接口?
List,Set不是继承自Map接口,它们继承自Collection接口
Map接口本身就是一个顶层接口
Collections:是针对集合进行操作的工具类,都是静态方法。
Collection和Collections的区别?
Collection:是单列集合的顶层接口,有子接口List和Set。
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):随机置换
案例一:泛型的简单使用

public class GenericDemo { public static void main(String[] args) {  // 创建  ArrayList<String> array = new ArrayList<String>();  // 添加元素  array.add("hello");  array.add("world");  array.add("java");  // 遍历  Iterator<String> it = array.iterator();  while (it.hasNext()) {   String s = it.next();   System.out.println(s);  } }}



案例二:增强for的简单使用

public class ForDemo { public static void main(String[] args) {  // 定义一个集合  ArrayList<String> array = new ArrayList<String>();  array.add("hello");  array.add("world");  array.add("java");  if (list != null) {   for (String s : list) {    System.out.println(s);   }  } }}



案例三:HashSet集合存储字符串

public class HashSetDemoOne { public static void main(String[] args) {  // 创建集合对象  HashSet<String> hs = new HashSet<String>();  // 创建并添加元素  hs.add("hello");  hs.add("world");  hs.add("java");  hs.add("world");  // 遍历集合  for (String s : hs) {   System.out.println(s);  } }}



案例四:HashSet集合存储自定义对象

public class HashSetDemoTwo { public static void main(String[] args) {  // 创建集合对象  HashSet<Student> hs = new HashSet<Student>();  // 创建学生对象  Student s1 = new Student("孙权", 27);  Student s2 = new Student("孙权", 27);  Student s3 = new Student("孙尚香", 17);  // 添加元素  hs.add(s1);  hs.add(s2);  hs.add(s3);  // 遍历集合  for (Student s : hs) {   System.out.println(s.getName() + "---" + s.getAge());  } }}public class Student{ ...标准学生类 重写equals和hashCode方法}



案例五:TreeSet类存储自定义对象,按照年龄大小排序,让类自身具有比较功能

<pre class="java" name="code">public class TreeSetDemo2 { public static void main(String[] args) {  // 创建集合对象  TreeSet<Student> ts = new TreeSet<Student>();  // 创建元素  Student s1 = new Student("李傕", 27);  Student s2 = new Student("贾诩", 29);  Student s3 = new Student("郭嘉", 23);  // 添加元素  ts.add(s1);  ts.add(s2);  ts.add(s3);  // 遍历  for (Student s : ts) {   System.out.println(s.getName() + "---" + s.getAge());  } }}public class Student implements Comparable{ ...标准学生类 重写compareTo方法 public int compareTo(Student s) {  int num = this.age - s.age;  int num2 = num == 0 ? this.name.compareTo(s.name) : num;  return num2; }}

案例五:TreeSet类存储自定义对象,按照年龄大小排序,使用比较器

public class TreeSetDemo2 { public static void main(String[] args) {  // 创建集合对象  TreeSet<Student> ts = new TreeSet<Student>(new Comparator(){   public int compare(Student s1, Student s2) {    int num = s1.getName().length() - s2.getName().length();    int num2 = num == 0 ? s1.getName().compareTo(s2.getName()): num;    int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;    return num3;  });  // 创建元素  Student s1 = new Student("李傕", 27);  Student s2 = new Student("贾诩", 29);  Student s3 = new Student("郭嘉", 23);  // 添加元素  ts.add(s1);  ts.add(s2);  ts.add(s3);  // 遍历  for (Student s : ts) {   System.out.println(s.getName() + "---" + s.getAge());  } }}public class Student{ ...标准学生类 }



案例六:练习Map集合中的方法

public class MapDemo { public static void main(String[] args) {  // 创建集合对象  Map<String, String> map = new HashMap<String, String>();  // 添加元素  System.out.println("put:" + map.put("张飞", "马超"));添加元素  map.put("孙策", "太史慈");  map.clear();移除所有的键值对元素  System.out.println("remove:" + map.remove("张飞"));根据键删除键值对元素,并把值返回  System.out.println("containsKey:" + map.containsKey("孙策"));判断集合是否包含指定的键  System.out.println("isEmpty:"+map.isEmpty());判断集合是否为空  System.out.println("size:"+map.size());返回集合中的键值对的对数  System.out.println("get:" + map.get("孙策"));根据键获取值  System.out.println("get:" + map.get("孙坚")); // 返回null  Set<String> set = map.keySet();获取集合中所有键的集合  for (String key : set) {   System.out.println(key);  }  Collection<String> con = map.values();获取集合中所有值的集合  for (String value : con) {   System.out.println(value);  }  Set<Map.Entry<String, String>> set = map.entrySet();// 获取所有键值对对象的集合  for (Map.Entry<String, String> me : set) {// 遍历键值对对象的集合,得到每一个键值对对象   // 根据键值对对象获取键和值   String key = me.getKey();   String value = me.getValue();   System.out.println(key + "---" + value);  }  // 输出集合名称  System.out.println("map:" + map); }}



案例七:HashMap练习

public class HashMapDemo { public static void main(String[] args) {  // 创建集合对象  HashMap<String, String> hm = new HashMap<String, String>();  // 创建元素并添加元素  hm.put("it001", "马云");  hm.put("it003", "马化腾");  hm.put("it004", "乔布斯");  hm.put("it005", "张朝阳");  hm.put("it002", "裘伯君");   hm.put("it001", "比尔盖茨");  // 遍历  Set<String> set = hm.keySet();  for (String key : set) {   String value = hm.get(key);   System.out.println(key + "---" + value);  } }}



案例八:HashMap练习

public class TreeMapDemo { public static void main(String[] args) {  // 创建集合对象  TreeMap<String, String> tm = new TreeMap<String, String>(   new Comparator<Student>() {     @Override     public int compare(Student s1, Student s2) {      // 主要条件      int num = s1.getAge() - s2.getAge();      // 次要条件      int num2 = num == 0 ? s1.getName().compareTo(        s2.getName()) : num;      return num2;     }  );  // 创建元素并添加元素  tm.put("hello", "小乔");  tm.put("world", "大桥");  tm.put("java", "貂蝉");  tm.put("world", "赵雯");  tm.put("javaee", "祝融夫人");  // 遍历集合  Set<String> set = tm.keySet();  for (String key : set) {   String value = tm.get(key);   System.out.println(key + "---" + value);  } }}



案例九:需求 :"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)

分析:  A:定义一个字符串(可以改进为键盘录入)  B:定义一个TreeMap集合   键:Character   值:Integer  C:把字符串转换为字符数组  D:遍历字符数组,得到每一个字符  E:拿刚才得到的字符作为键到集合中去找值,看返回值   是null:说明该键不存在,就把该字符作为键,1作为值存储   不是null:说明该键存在,就把值加1,然后重写存储该键和值    F:定义字符串缓冲区变量   G:遍历集合,得到键和值,进行按照要求拼接  H:把字符串缓冲区转换为字符串输出public class TreeMapDemo { public static void main(String[] args) {  // 定义一个字符串(可以改进为键盘录入)  Scanner sc = new Scanner(System.in);  System.out.println("请输入一个字符串:");  String line = sc.nextLine();  // 定义一个TreeMap集合  TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();  //把字符串转换为字符数组  char[] chs = line.toCharArray();  //遍历字符数组,得到每一个字符  for(char ch : chs){   //拿刚才得到的字符作为键到集合中去找值,看返回值   Integer i =  tm.get(ch);     //是null:说明该键不存在,就把该字符作为键,1作为值存储   if(i == null){    tm.put(ch, 1);   }else {    //不是null:说明该键存在,就把值加1,然后重写存储该键和值    i++;    tm.put(ch,i);   }  }   //定义字符串缓冲区变量  StringBuilder sb=  new StringBuilder();   //遍历集合,得到键和值,进行按照要求拼接  Set<Character> set = tm.keySet();  for(Character key : set){   Integer value = tm.get(key);   sb.append(key).append("(").append(value).append(")");  }   //把字符串缓冲区转换为字符串输出  String result = sb.toString();  System.out.println("result:"+result); }}


 

 

0 0