一、集合:
集合是Java API所提供的一系列类的实例,可以用于动态存放多个对象
为什么要使用集合?数组的长度是固定的,存满了就不能存了。集合可以存储不同类型的对象,而且它的容量可以随着对象数量的增加,自动扩大。
-----------------------------------------------------------------------------------------------------------------------------------
二、List集合
List:存储的对象是有序,可以重复的
功能:除了继承Collection接口提供的功能之外,支持带下标的操作
----------------------------------------------------------------------------------------------------------------------------------
增加方法:
(1)、void add(int index,E element)添加指定的对象到index的位置
(2)、boolean addAll(int index,Collection<? extends E> c)
删除方法:
(1)、E remove(int index) 删除指定位置的对象,并返回次对象
修改方法:
(1)、E set(int index,E element)更换指定位置的对象
查询方法:
(1)、ListIterator<E> listIterator() 返回此列表元素的列表迭代器(按适当顺序)
(2)、ListIterator<E> listIterator(int index) 返回指定位置的对象
(3)、E get(int index) 得到指定位置的对象
注意:在迭代的过程中对集合进行添加,删除,修改,会发生ConcurrentModificationException异常
-----------------------------------------------------------------------------------------------------------------------------------
1、ArrayList:使用的数据结构是数组,线程不安全的,查找速度快,增删速度慢
示例:
1 import java.util.ArrayList; 2 import java.util.Iterator; 3 import java.util.List; 4 5 public class Demo { 6 7 public static void main(String[] args) { 8 List list = new ArrayList(); 9 list.add("你好"); 10 list.add("你好吗?"); 11 list.add("我很好"); 12 System.out.println(list); 13 14 list.add(1, "不是很好"); 15 System.out.println(list); 16 17 // 删除指定下标的元素 18 System.out.println("成功删除:" + list.remove(1)); 19 System.out.println(list); 20 21 // 修改 22 list.set(1, "大家好!!!"); 23 System.out.println(list); 24 25 List sub = list.subList(1, 2); 26 System.out.println(sub); 27 System.out.println(list.get(1)); 28 29 // 遍历集合 30 Iterator it = list.iterator(); 31 while (it.hasNext()) { 32 System.out.println(it.next()); 33 } 34 System.out.println("-------------"); 35 for (Iterator it1 = list.iterator(); it1.hasNext();) { 36 System.out.println(it1.next()); 37 } 38 System.out.println("-------------"); 39 for (Object obj : list) { 40 System.out.println(obj); 41 } 42 System.out.println("-----------"); 43 for (int i = 0; i < list.size(); i++) { 44 System.out.println(list.get(i)); 45 } 46 47 // 清空 48 while (!list.isEmpty()) { 49 list.remove(0); 50 } 51 System.out.println(list.size()); 52 53 } 54 55 }
2、LinkedList:使用的数据结构是链表,线程不安全的,查找速度慢,增删速度快
示例:
1 import java.util.LinkedList; 2 3 public class Demo { 4 public static void main(String[] args) { 5 LinkedList link = new LinkedList(); 6 link.addFirst("001"); 7 link.addFirst("002"); 8 link.addFirst("003"); 9 link.addFirst("004"); 10 11 System.out.println(link); 12 13 System.out.println("getFirst:" + link.getFirst()); 14 System.out.println("get后的集合" + link); 15 System.out.println("peekFirst:" + link.peekFirst()); 16 System.out.println("peek后的集合" + link); 17 System.out.println("pop()" + link.pop()); 18 System.out.println("pop后的集合" + link); 19 20 while (!link.isEmpty()) { 21 System.out.println(link.removeFirst()); 22 } 23 System.out.println("删除后集合中的元素"); 24 System.out.println(link); 25 // 集合中元素为空 26 System.out.println("getFirst:" + link.getFirst());// 抛出NoSuchElementException 27 System.out.println("peekFirst:" + link.peekFirst());// null 28 29 } 30 }
3、Vector:使用的数据结构是数组,线程安全的,查找速度快,增删速度慢,被ArrayList替代了
示例:
1 import java.util.Enumeration; 2 import java.util.Vector; 3 4 public class Demo { 5 /* 6 * Vector:被ArrayList替代 7 * 8 * 效率低,线程安全的 9 */ 10 public static void main(String[] args) { 11 Vector v = new Vector(); 12 v.add("张三"); 13 v.add("李四"); 14 v.add("王五"); 15 for (Object o : v) { 16 System.out.println(o); 17 } 18 19 Enumeration elements = v.elements(); 20 // 遍历 21 while (elements.hasMoreElements()) { 22 Object o = elements.nextElement(); 23 System.out.println(o); 24 } 25 } 26 27 }
-----------------------------------------------------------------------------------------------------------------------------------
三、Set集合
Set:存储的对象是无序的,不可以重复的
------------------------------------------------------------------------------------------------------------------------------------
1、HashSet:底层使用的数据结构是哈希表,线程不安全的
确定唯一性的原理:
1、向集合中添加对象时,会先和集合中已经存在的对象比较哈希值
2、若哈希值不同,则直接添加到集合中
3、若哈希值相同,则再调用equals()方法,此方法返回false时,则将对象添加到集合中,反之不添加
注意:哈希值相同不一定是同一个对象,同一个对象哈希值肯定相同
示例:
1 import java.util.HashSet; 2 import java.util.Iterator; 3 4 public class Demo15 { 5 6 public static void main(String[] args) { 7 HashSet<Person> hs = new HashSet<Person>(); 8 hs.add(new Person("张三", 20)); 9 hs.add(new Person("张三1", 20)); 10 hs.add(new Person("张三2", 20)); 11 hs.add(new Person("张三3", 20)); 12 hs.add(new Person("张三", 20)); 13 14 // 遍历--迭代器 15 Iterator it = hs.iterator(); 16 while (it.hasNext()) { 17 System.out.println(it.next()); 18 } 19 20 } 21 22 static class Person { 23 private String name; 24 private int age; 25 26 public String getName() { 27 return name; 28 } 29 30 public void setName(String name) { 31 this.name = name; 32 } 33 34 public int getAge() { 35 return age; 36 } 37 38 public void setAge(int age) { 39 this.age = age; 40 } 41 42 public Person(String name, int age) { 43 super(); 44 this.name = name; 45 this.age = age; 46 } 47 48 @Override 49 public String toString() { 50 return "Person [name=" + name + ", age=" + age + "]"; 51 } 52 53 @Override 54 public int hashCode() { 55 final int prime = 31; 56 int result = 1; 57 result = prime * result + age; 58 result = prime * result + ((name == null) ? 0 : name.hashCode()); 59 return result; 60 } 61 62 @Override 63 public boolean equals(Object obj) { 64 if (this == obj) 65 return true; 66 if (obj == null) 67 return false; 68 if (getClass() != obj.getClass()) 69 return false; 70 Person other = (Person) obj; 71 if (age != other.age) 72 return false; 73 if (name == null) { 74 if (other.name != null) 75 return false; 76 } else if (!name.equals(other.name)) 77 return false; 78 return true; 79 } 80 81 } 82 }
------------------------------------------------------------------------------------------------------------------------------------
2、TreeSet:底层使用的数据结构是二叉树,线程不安全的
确保唯一性的方式:依据compareTo()或compare()的返回值是否为0
方式1:让存入集合中的对象具备可比较性
(1)、类实现Comparable接口
(2)、实现接口的compareTo(Object o)方法
方式2:让集合具备排序功能
(1)、创建Comparator接口对象,并实现其方法compare(Object o1,Object o2)方法
(2)、在创建TreeSet的构造方法中传入Comparator对象
示例:
1 import java.util.Comparator; 2 import java.util.Set; 3 import java.util.TreeSet; 4 5 /* 6 * TreeSet:底层使用的数据结构是二叉树,线程不安全。会对存入集合的对象进行排序。 7 * 8 * 保证加入集合的对象是可排序的: 9 * 1)让自定义的类实现Comparable接口,int compareTo() 10 * 2 )自定义比较器: 11 * 创建比较器,实现Comparator接口,接口int compare() 12 * 把比较器对象作为参数传递给集合的构造方法 13 * */ 14 public class Demo16 { 15 16 public static void main(String[] args) { 17 /* 18 * Set tree = new TreeSet(); tree.add(13); tree.add(8); tree.add(17); 19 * tree.add(1); tree.add(11); tree.add(15); System.out.println(tree); 20 */ 21 22 Set<Dog> set = new TreeSet<Dog>(); 23 set.add(new Dog("大黄", 3)); 24 set.add(new Dog("大黄1", 2)); 25 set.add(new Dog("大黄2", 1)); 26 set.add(new Dog("大黄9", 6)); 27 set.add(new Dog("大黄4", 6)); 28 System.out.println(set); 29 System.out.println("---------------"); 30 // 创建比较器对象 31 MyCompare mc = new MyCompare(); 32 TreeSet ts = new TreeSet(mc); 33 ts.add(new Dog("大黄1", 3)); 34 ts.add(new Dog("大黄1", 2)); 35 ts.add(new Dog("大黄2", 1)); 36 ts.add(new Dog("大黄9", 6)); 37 38 System.out.println(ts); 39 40 } 41 42 } 43 44 class Dog implements Comparable { 45 private String name; 46 private int age; 47 48 public String getName() { 49 return name; 50 } 51 52 public void setName(String name) { 53 this.name = name; 54 } 55 56 public int getAge() { 57 return age; 58 } 59 60 public void setAge(int age) { 61 this.age = age; 62 } 63 64 public Dog(String name, int age) { 65 super(); 66 this.name = name; 67 this.age = age; 68 } 69 70 public Dog() { 71 super(); 72 } 73 74 @Override 75 public String toString() { 76 return "Dog [name=" + name + ", age=" + age + "]"; 77 } 78 79 @Override 80 public int hashCode() { 81 final int prime = 31; 82 int result = 1; 83 result = prime * result + age; 84 result = prime * result + ((name == null) ? 0 : name.hashCode()); 85 return result; 86 } 87 88 @Override 89 public boolean equals(Object obj) { 90 if (this == obj) 91 return true; 92 if (obj == null) 93 return false; 94 if (getClass() != obj.getClass()) 95 return false; 96 Dog other = (Dog) obj; 97 if (age != other.age) 98 return false; 99 if (name == null) { 100 if (other.name != null) 101 return false; 102 } else if (!name.equals(other.name)) 103 return false; 104 return true; 105 } 106 107 @Override 108 public int compareTo(Object o) { 109 Dog d = (Dog) o; 110 if (this.age < d.age) 111 return -1; 112 else if (this.age > d.age) 113 return 1; 114 else 115 return this.name.compareTo(d.name); // 年龄相同再继续比较姓名 116 } 117 118 } 119 120 // 自定义比较器 121 // 比较名字是否相等,如果名字相同再按照年龄排序 122 class MyCompare implements Comparator { 123 124 @Override 125 public int compare(Object o1, Object o2) { 126 if (!(o1 instanceof Dog)) 127 throw new ClassCastException("类型转换出错"); 128 if (!(o2 instanceof Dog)) 129 throw new ClassCastException("类型转换出错"); 130 Dog d1 = (Dog) o1; 131 Dog d2 = (Dog) o2; 132 int n = d1.getName().compareTo(d2.getName()); 133 return n == 0 ? d1.getAge() - d2.getAge() : n; 134 } 135 }
1 import java.util.Comparator; 2 import java.util.Iterator; 3 import java.util.TreeSet; 4 5 public class Demo18 { 6 public static void main(String[] args) { 7 TreeSet<Person> ts = new TreeSet<Person>(new Comparator<Person>() { 8 9 // 比较年龄,然后在比较姓名 10 @Override 11 public int compare(Person o1, Person o2) { 12 int n = o1.getAge() - o2.getAge(); 13 if (n == 0) { // 年龄相等 14 return o1.getName().compareTo(o2.getName()); // 在比较姓名 15 } 16 return n; 17 } 18 }); 19 ts.add(new Person("张三4", 39)); 20 ts.add(new Person("张三1", 39)); 21 ts.add(new Person("张三2", 19)); 22 ts.add(new Person("张三3", 27)); 23 ts.add(new Person("张三4", 27)); 24 ts.add(new Person("张三4", 27)); 25 26 Iterator<Person> it = ts.iterator(); 27 while (it.hasNext()) { 28 System.out.println(it.next()); 29 } 30 31 } 32 } 33 34 class Person { 35 private String name; 36 private int age; 37 38 public String getName() { 39 return name; 40 } 41 42 public void setName(String name) { 43 this.name = name; 44 } 45 46 public int getAge() { 47 return age; 48 } 49 50 @Override 51 public String toString() { 52 return "Person [name=" + name + ", age=" + age + "]"; 53 } 54 55 public void setAge(int age) { 56 this.age = age; 57 } 58 59 public Person(String name, int age) { 60 super(); 61 this.name = name; 62 this.age = age; 63 } 64 65 }
-----------------------------------------------------------------------------------------------------------------------------------
四、Map
Map:一个单独的接口,存储的是键值对,键不可以重复,无序的
------------------------------------------------------------------------------------------------------------------------------------
特点:
1、创建Comparator接口对象,并实现其方法compare(Object o1,Object o2)方法
2、存入HashMap中的映射对的“键”的类型必须是引用类型(除数组外)
3、所以存入HashMap中的映射对的“键”如果是自定义的类,应该重写hashCode()和equals()方法
4、常用String作为Map的“键”
方法:
1、添加
①V put(K key, V value) //将指定的“键-值”对存入Map中
②void putAll(Map<? extends K,? extends V> m)
2、删除
①void putAll(Map<? extends K,? extends V> m)
②void clear(); //清空Map中的所有“键-值”对。
3、获取
①V get(Object key); //返回指定键所映射的值
②Set<K> keySet(); //返回此Map中包含的键的Set集。
③int size(); //获得些Map中“键-值”对的数量。
④Set<Entry<K, V>> entrySet() 返回此Map的键-值对内容的Set集合
⑤Collection<V> values(); //返回此Map中包含的值的Collection集。值是可重复的.
4、判断
①boolean isEmpty(); //判断此Map中是否有元素。
②boolean containsKey(Object key); //判断此Map是否包含指定键的“键-值”对。
③boolean containsValue(Object value);//判断此Map是否包含指定值的“键-值”对。
------------------------------------------------------------------------------------------------------------------------------------
1、HashMap:保证键唯一的原理和HashSet一样,hashCode(),equals()
2、TreeMap:是根据键来排序的,保证键唯一的原理和TreeSet相同,依据 compareTo()或compare()的返回值是否为0,为0就认为是重复键
------------------------------------------------------------------------------------------------------------------------------------
Map.Entry接口:
Map.Entry是Map中内部定义的一个static接口,专门用来保存key-value的内容
1 Set<Map.Entry<Cat, String>> entrySet = map.entrySet(); 2 Iterator<Map.Entry<Cat, String>> it = entrySet.iterator(); 3 while (it.hasNext()) { 4 Map.Entry<Cat, String> en = it.next(); 5 System.out.println(en.getKey() + "---" + en.getValue()); 6 }
-----------------------------------------------------------------------------------------------------------------------------------
五、Collection接口
说明:是List接口和Set接口的父接口
1、添加方法
(1)、boolean add(Object o) 增加对象到集合中
(2)、boolean addAll(Collection<? extends E> c) 增加所有其它集合中对象
2、删除方法
(1)、boolean remove(Object o) 从集合中删除对象
(2)、boolean removeAll(Collection<?> c) 从集合中删除所有指定集合包含的对象
(3)、void clear() 清空集合
3、判断方法
(1)、boolean contains(Object o) 判断是否集合中是否包含指定对象
(2)、boolean containsAll(Collection<?> c) 判断集合是否包含指定集合中所有对象
(3)、boolean isEmpty() //判断集合是否为空
(4)、boolean equals(Object o) 判断集合是否与某对象相同
4、获取方法
(1)、Iterator<E> iterator() //获取集合中的对象
(2)、int size() //获取集合中对象的个数
5、转换方法
(1)、 Object[] toArray() 将集合转换成数组
示例:
1 import java.util.ArrayList; 2 import java.util.Collection; 3 import java.util.Iterator; 4 5 public class Demo3 { 6 /* 7 * 遍历集合:---Iterator迭代器,判断是否存在下一个元素(hasNext()),如果存在,取出(next()) Iterator接口 8 */ 9 public static void main(String[] args) { 10 Collection col = new ArrayList(); 11 col.add("anc"); 12 col.add("aaa"); 13 col.add("ddd"); 14 col.add("eeee"); 15 16 // 获取集合对象的迭代器 17 Iterator it = col.iterator(); 18 // 判断是否存下一个元素 19 while (it.hasNext()) { 20 Object o = it.next(); 21 System.out.println(o);// 获得元素 22 23 // col.remove(o);// 抛异常 24 25 it.remove();// 删除next最后一次获取的对象,如果使用迭代器遍历集合,必须使用迭代器的remove方法删除元素 26 } 27 System.out.println("------------"); 28 for (Object o : col) { 29 System.out.println(o); 30 } 31 32 } 33 34 }
-----------------------------------------------------------------------------------------------------------------------------------
六、Iterator接口
作用:遍历集合中的对象
原理:先对元素进行判断,判断是否有内容,如果有内容则把内容取出
特点:只能读取和删除,不能添加、修改
方法:(1)boolean hasNext() 是否存在下一个对象(2)E next() 获取下一个对象(3)void remove() 删除最近next之后获取的对象
eg:
1 // 获取集合对象的迭代器 2 Iterator it = col.iterator(); 3 // 判断是否存下一个元素 4 while (it.hasNext()) { 5 Object o = it.next(); 6 System.out.println(o);// 获得元素 7 it.remove();// 删除next最后一次获取的对象,如果使用迭代器遍历集合,必须使用迭代器的remove方法删除元素 8 }