案例:迭代器遍历方式
public static void main(String[] args) { Collection c = new ArrayList(); c.add("java"); c.add("scala"); c.add("hadoop"); //遍历集合 Iterator it = c.iterator(); while(it.hasNext()) { String s =(String) it.next(); System.out.PRintln(s); }}特点:
有序(存储顺序和取出顺序一致),可重复。特有遍历:由size()和get()结合
List list = new ArrayList();list.add("java");list.add("scala");list.add("hadoop");//遍历集合Iterator it = list.iterator();while(it.hasNext()) { String s =(String) it.next(); System.out.println(s);}for(int x=0; x<list.size(); x++) { String s =(String) list.get(x); System.out.println(s);}常见数据结构
ArrayXxx:底层数据结构是数组,查询快,增删慢LinkedXxx:底层数据结构是链表,查询慢,增删快HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序List的子类特点
ArrayList 底层数据结构是数组,查询快,增删慢。 线程不安全,效率高。Vector(几乎不用) 底层数据结构是数组,查询快,增删慢。 线程安全,效率低。LinkedList 底层数据结构是链表,查询慢,增删快。 线程不安全,效率高。 有特有功能: a:添加 addFirst() addLast() b:删除 removeFirst() removeLast() c:获取 getFirst() getLast()特点
无序,唯一(由hashCode()和equals()保证)HashSet
A:底层数据结构是哈希表(是一个元素为链表的数组) B:哈希表底层依赖两个方法:hashCode()和equals() 执行顺序: 首先比较哈希值是否相同 相同:继续执行equals()方法 返回true:元素重复了,不添加 返回false:直接把元素添加到集合 不同:就直接把元素添加到集合TreeSet集合
A:底层数据结构是红黑树(是一个自平衡的二叉树)B:保证元素的排序方式 a:自然排序(元素具备比较性) 让元素所属的类实现Comparable接口 b:比较器排序(集合具备比较性) 让集合构造方法接收Comparator的实现类对象Collection集合总结
Collection |--List 有序,可重复 |--ArrayList 底层数据结构是数组,查询快,增删慢。 线程不安全,效率高 |--Vector 底层数据结构是数组,查询快,增删慢。 线程安全,效率低 |--LinkedList 底层数据结构是链表,查询慢,增删快。 线程不安全,效率高 |--Set 无序,唯一 |--HashSet 底层数据结构是哈希表。 唯一性 依赖两个方法:hashCode()和equals() 开发中自动生成这两个方法即可 |--LinkedHashSet 底层数据结构是链表和哈希表 由链表保证元素有序 由哈希表保证元素唯一 |--TreeSet 底层数据结构是红黑树 排序: 自然排序 比较器排序 唯一性: 根据比较的返回值是否是0来决定Collection集合使用谁?
唯一吗? 是:Set 排序吗? 是:TreeSet 否:HashSet 否:List 要安全吗? 是:Vector(几乎不用) 否:ArrayList或者LinkedList 查询多:ArrayList 增删多:LinkedList是一种把明确类型的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型
特点:
1. 把运行时期的问题提前到了编译期间2. 避免了强制类型转换3. 优化了程序设计,解决了黄色警告线问题,让程序更安全高级通配符
? 表示任意的类型都是可以的? extends E 向下限定,E及其子类? super E 向上限定,E极其父类遍历:
// JDK7的新特性:泛型推断。// ArrayList<Student> array = new ArrayList<>();// 不建议ArrayList<Student> array = new ArrayList<Student>();Student s1 = new Student("java", 40);Student s2 = new Student("scala", 10);Student s3 = new Student("hadoop", 5);array.add(s1);array.add(s2);array.add(s3);// 遍历Iterator<Student> it = array.iterator();while (it.hasNext()) { Student s = it.next();}for (int x = 0; x < array.size(); x++) { Student s = array.get(x);}格式:
for(数据类型 变量名 : 数组或者Collection集合的对象) { 使用该变量即可,该变量其实就是数组或者集合中的元素。}好处
简化了数组和集合的遍历弊端
增强for循环的目标不能为null。建议在使用前,先判断是否为null。示例:
HashSet<Integer> ts = new HashSet<Integer>();while (ts.size() < 10) { ts.add(ts.size());}for (Integer i : ts) { System.out.println(i);}案例:获取10个1至20的随机数,要求随机数不能重复
public static void main(String[] args) { // 创建随机数对象 Random r = new Random(); // 创建一个Set集合 HashSet<Integer> ts = new HashSet<Integer>(); // 判断集合的长度是不是小于10 while (ts.size() < 10) { int num = r.nextInt(20) + 1; ts.add(num); } // 遍历Set集合 for (Integer i : ts) { System.out.println(i); }}案例:”aababcabcdabcde”,获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)
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); }新闻热点
疑难解答