1.list接口中常用的特有方法
package cn.jxufe.java.chapter7; import java.util.ArrayList; import java.util.List; /* * List接口派系, 继承Collection接口 * 下面有很多实现类 * List接口特点: 有序,索引,可以重复元素 * 实现类, ArrayList, LinkedList * * List接口中的抽象方法,有一部分方法和他的父接口Collection是一样 * List接口的自己特有的方法, 带有索引的功能 */ public class TestList01 { public static void main(String[] args) { // TODO Auto-generated method stub function(); System.out.println(); function_1(); System.out.println(); function_2(); } /* * E set(int index, E) * 修改指定索引上的元素 * 返回被修改之前的元素 */ public static void function_2() { List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); list.add(4); System.out.println(list); Integer i = list.set(0, 5); System.out.println(i); System.out.println(list); } /* * add(int index, E) 将元素插入到列表的指定索引上 带有索引的操作,防止越界问题 * java.lang.IndexOutOfBoundsException * ArrayIndexOutOfBoundsException * StringIndexOutOfBoundsException */ public static void function() { List<String> list = new ArrayList<String>(); list.add("abc1"); list.add("abc2"); list.add("abc3"); list.add("abc4"); System.out.println(list); list.add(1, "itcast"); System.out.println(list); } /* * E remove(int index) 移除指定索引上的元素 返回被删除之前的元素 */ public static void function_1() { List<Double> list = new ArrayList<Double>(); list.add(1.1); list.add(1.2); list.add(1.3); list.add(1.4); System.out.println(list); Double d = list.remove(0); System.out.println(d); System.out.println(list); } }
2.Iterator的并发修改异常
package cn.jxufe.java.chapter7; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Test02IteratorException { /* * 迭代器的并发修改异常 java.util.ConcurrentModificationException * 就是在遍历的过程中,使用了集合方法修改了集合的长度,不允许的 */ public static void main(String[] args) { // TODO Auto-generated method stub List<String> list = new ArrayList<String>(); list.add("abc1"); list.add("abc2"); list.add("abc3"); list.add("abc4"); // 对集合使用迭代器进行获取,获取时候判断集合中是否存在 "abc3"对象 // 如果有,添加一个元素 "ABC3" Iterator<String> it = list.iterator(); while (it.hasNext()) { String s = it.next(); // 对获取出的元素s,进行判断,是不是有"abc3" if (s.equals("abc3")) { list.add("ABC3"); } System.out.println(s); } } }
3.LinkedList集合(单向链表)
LinkedList集合数据存储的结构是链表结构。方便元素添加、删除的集合。实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了大量首尾操作的方法。
package cn.jxufe.java.chapter7; import java.util.LinkedList; public class Test03LinkedList { public static void main(String[] args) { // TODO Auto-generated method stub function(); System.out.println(); function_1(); System.out.println(); function_2(); System.out.println(); function_3(); } /* * addFirst(E) 添加到链表的开头 * addLast(E) 添加到链表的结尾 */ public static void function() { LinkedList<String> link = new LinkedList<String>(); link.addLast("heima"); link.add("abc"); link.add("bcd"); link.addFirst("itcast"); System.out.println(link); } public static void function_1() { LinkedList<String> link = new LinkedList<String>(); link.addLast("a"); link.addLast("b"); link.addLast("c"); link.addLast("d"); link.addFirst("1"); link.addFirst("2"); link.addFirst("3"); System.out.println(link); } /* * E getFirst() 获取链表的开头 * E getLast() 获取链表的结尾 */ public static void function_2() { LinkedList<String> link = new LinkedList<String>(); link.add("1"); link.add("2"); link.add("3"); link.add("4"); System.out.println(link); if (!link.isEmpty()) { String first = link.getFirst(); String last = link.getLast(); System.out.println(first); System.out.println(last); } } /* * E removeFirst() 移除并返回链表的开头 * E removeLast() 移除并返回链表的结尾 */ public static void function_3() { LinkedList<String> link = new LinkedList<String>(); link.add("1"); link.add("2"); link.add("3"); link.add("4"); System.out.println(link); String first = link.removeFirst(); String last = link.removeLast(); System.out.println(first); System.out.println(last); System.out.println(link); } }
4.Vector集合(基本被ArrayList取代了)
Vector集合数据存储的结构是数组结构,为JDK中最早提供的集合。Vector中提供了一个独特的取出方式,就是枚举Enumeration,它其实就是早期的迭代器。此接口Enumeration的功能与 Iterator 接口的功能是类似的。Vector集合已被ArrayList替代。枚举Enumeration已被迭代器Iterator替代。
Vector集合对ArrayList集合使用的对比:
5.set集合
学习Collection接口时,记得Collection中可以存放重复元素,也可以不存放重复元素,那么我们知道List中是可以存放重复元素的。那么不重复元素给哪里存放呢?那就是Set接口,它里面的集合,所存储的元素就是不重复的。
set集合取出元素的方式:迭代器和增强for,没有索引,因为是无序的。
5.1HashSet
package cn.jxufe.java.chapter7; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /* * Set接口,特点不重复元素,没索引 * * Set接口的实现类,HashSet (哈希表) * 特点: 无序集合,存储和取出的顺序不同,没有索引,不存储重复元素 * 代码的编写上,和ArrayList完全一致 */ public class Test04HashSet { public static void main(String[] args) { // TODO Auto-generated method stub Set<String> set = new HashSet<String>(); set.add("cn"); set.add("heima"); set.add("java"); set.add("java"); set.add("itcast"); Iterator<String> it = set.iterator(); while (it.hasNext()) { System.out.println(it.next()); } System.out.println("=============="); for (String s : set) { System.out.println(s); } } }
package cn.jxufe.java.chapter7; import java.util.HashSet; import java.util.Set; public class Test05HashSet { public static void main(String[] args) { Set<String> set1 = new HashSet<>(); // 添加元素 set1.add("London"); set1.add("nanchang"); set1.add("xuzhou"); set1.add("beijing"); System.out.println("set1 is " + set1); System.out.println(set1.size() + " elements in set1"); // 删除元素 set1.remove("London"); System.out.println(" set1 is " + set1); System.out.println(set1.size() + " elements in set1"); Set<String> set2 = new HashSet<>(); set2.add("london"); set2.add("guangzhou"); set2.add("shanghai"); System.out.println(" set2 is " + set2); System.out.println("is Taipei in set2? " + set2.contains("Taipei")); System.out.println("is shanghai in set2? " + set2.contains("shanghai")); // addAll set1.addAll(set2); System.out.println("now set1 is " + set1); // removeAll set1.removeAll(set2); System.out.println("now set1 is " + set1); set1.add("london"); // retainAll set1.retainAll(set2); System.out.println(set1); } }
5.2string类的hash值
5.3hash表的存储过程
5.4重写hashcode
package cn.jxufe.java.chapter7; import java.util.HashSet; public class Test06HashSet { public static void main(String[] args) { // TODO Auto-generated method stub // 将Person对象中的姓名,年龄,相同数据,看作同一个对象 // 判断对象是否重复,依赖对象自己的方法 hashCode,equals HashSet<Person> setPerson = new HashSet<Person>(); setPerson.add(new Person("a", 11)); setPerson.add(new Person("b", 10)); setPerson.add(new Person("b", 10)); setPerson.add(new Person("c", 25)); setPerson.add(new Person("d", 19)); setPerson.add(new Person("e", 17)); System.out.println(setPerson); } } class Person { private String name; private int age; public Person(String name, int age) { // TODO Auto-generated constructor stub this.name = name; this.age = age; } 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; } @Override public String toString() { // TODO Auto-generated method stub return name + ".." + age; } }
如果不重写hashcode发现加入了两个person对象b..10,因为他们的名字和年龄相同,假如现在把名字和年龄相同的对象看成一个对象,那么set如何存储呢?
我们需要重写hashcode方法和equals方法。
package cn.jxufe.java.chapter7; import java.util.HashSet; public class Test06HashSet { public static void main(String[] args) { // TODO Auto-generated method stub // 将Person对象中的姓名,年龄,相同数据,看作同一个对象 // 判断对象是否重复,依赖对象自己的方法 hashCode,equals HashSet<Person> setPerson = new HashSet<Person>(); setPerson.add(new Person("a", 11)); setPerson.add(new Person("b", 10)); setPerson.add(new Person("b", 10)); setPerson.add(new Person("c", 25)); setPerson.add(new Person("d", 19)); setPerson.add(new Person("e", 17)); System.out.println(setPerson); } } class Person { private String name; private int age; public Person(String name, int age) { // TODO Auto-generated constructor stub this.name = name; this.age = age; } 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; } @Override public String toString() { // TODO Auto-generated method stub return name + ".." + age; } @Override public int hashCode() { // TODO Auto-generated method stub return name.hashCode() + age * 55; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (obj instanceof Person) { Person p = (Person) obj; return name.equals(p.name) && age == p.age; } return false; } }
eclipse也可以直接生成重写的hashcode和equals方法。
5.5LinkedHashSet
package cn.jxufe.java.chapter7; import java.util.LinkedHashSet; import java.util.Set; public class Test07LinkedHashSet { public static void main(String[] args) { // TODO Auto-generated method stub Set<String> set = new LinkedHashSet<>(); set.add("nanjing"); set.add("beijing"); set.add("dongjing"); set.add("shanghai"); set.add("xuzhou"); System.out.println(set); for (String e : set) { System.out.print(e + " "); } } }
5.6TreeSet
package cn.jxufe.java.chapter7; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; public class Test08TreeSet { public static void main(String[] args) { // TODO Auto-generated method stub Set<String> set = new HashSet<>(); set.add("nanjing"); set.add("beijing"); set.add("dongjing"); set.add("shanghai"); set.add("xuzhou"); System.out.println(set); TreeSet<String> treeSet = new TreeSet<>(set); System.out.println("sorted tree set " + treeSet); // 排序的set System.out.println("first(): " + treeSet.first());// 返回第一个元素 System.out.println("last(): " + treeSet.last());// 返回最后一个元素 System.out.println("headSet: "dongjing" " + treeSet.headSet("nanjing"));// 返回dongjing之前的那些元素 System.out.println("lower:"N" " + treeSet.lower("nanjing"));// 返回小于N的最大的元素 System.out.println("higher:"N" " + treeSet.higher("nanjing"));// 返回大于N的最小的元素 System.out.println("floor:"N" " + treeSet.floor("nanjing"));// 返回小于等于nanjing的最大的元素 System.out.println("ceiling:"N" " + treeSet.ceiling("nanjing"));// 返回大于等于nanjing的最小的元素 System.out.println("pollfirst: " + treeSet.pollFirst());// 删除第一个元素 System.out.println("pollLast: " + treeSet.pollLast());// 删除最后一个元素 System.out.println(treeSet); } }