Collection中的常用方法
boolean add(E e) | 在集合中添加元素 |
boolean addAll?(Collection<? extends E> c) |
往集合中添加另一个集合 |
void clear() | 清空集合 |
boolean contains?(Object o) | 该集合是否包含指定的元素 |
boolean containsAll?(Collection<?> c) | 集合是否包含指定合c中的全部元素 |
boolean isEmpty() | 判断集合是否为空 |
boolean remove?(Object o) | 移除集合中的元素 |
boolean removeAll?(Collection<?> c) | 移除集合对象中的和集合c中相同的元素 |
boolean retainAll?(Collection<?> c) | 返回和集合c的交集 |
int size() | 返回集合的大小 |
Iterator<E> iterator() | 返回集合的迭代器对象 |
集合典型继承体系树
Collection
|--List:元素是有序的,元素可以重复,因为该集合体系有索引。需要注意的是,contains和remove方法底层使用的是equals方法。因此,在去除集合中的重复元素时一定要在自定义的类中覆盖Object类中的equals方法,实现自己的子类方法,这时就不需要逐个去比较了,直接用集合的contains方法。
|--ArrayList:底层使用的是数组结构。特点:查询速度快,但是增删速度慢。线程不同步。
|--LinkedList:底层使用的是链表结构。特点:增删速度快,查询速度慢。
|--Vector:底层是数组数据结构。元老级。Vector是同步的。被ArrayList替代了。枚举是Vector特有的取出方式。其实枚举和迭代器是相同的。
|--Set:元素不保证顺序(存入和取出的顺序不一定一致),不包含重复元素。
|--HashSet:底层使用的是哈希表。线程非同步。该集合通过hashCode和equals方法来判断集合中的元素是否相同。先调用hashCode方法,如果该方法的返回值相同,再调用equals方法。对于判断元素是否相同,删除集合中的元素等,底层使用的方法还是hashCode和equals方法。
|--TreeSet:底层使用的是二叉树结构。可以对传入的元素进行自动排序,排序使用的是Comparable接口中的compareTo方法。如果方法返回值是0,则代表传入的数据相同,则忽略该元素。
对元素的排序有两种方式:
1.元素自身具备自然排序,其实就是自定义的类实现了Comparable接口重写了compareTo方法。
2.比较器排序,在创建TreeSet集合时,在构造函数中指定具体的比较器方法。需要定义一个类实现Comparator接口,重写compare方法。
List集合特有方法:
由于List集合体系带有索引,所以可以使用常规取出数组的操作来取出List集合中的元素。
void add?(int index, E element) | 在指定位置添加元素 |
boolean addAll?(int index, Collection<? extends E> c) | 在指定位置添加集合 |
E remove?(int index) | 删除指定位置上的元素 |
E set?(int index, E element) | 修改指定位置上的元素 |
E get?(int index) | 获取指定位置上的元素 |
List<E> subList?(int fromIndex, int toIndex) | 获取指定范围内的集合 |
ListIterator<E> listIterator() | 在迭代时可以进行增删改操作 |
eg:常规取出方式:
public class Test { public static void main(String[] args) { ArrayList<String> s1 = new ArrayList<String>(); s1.add("java1"); s1.add("java2"); s1.add("java3"); s1.add("java4"); for (int i = 0; i < s1.size(); i++) { System.out.println(s1.get(i)); } } }
迭代器方式:
public class Test { public static void main(String[] args) { ArrayList<String> s1 = new ArrayList<String>(); s1.add("java1"); s1.add("java2"); s1.add("java3"); s1.add("java4"); for (Iterator<String> iterator = s1.iterator(); iterator.hasNext();) { String string = (String) iterator.next(); System.out.println(string); } } }
去除ArrayList集合中的重复元素
LinkedList集合特有方法
根据removeFirst()方法会返回并删除第一个元素,也可以实现元素的迭代。
void addFirst(); | 升级版JDK1.6后 | boolean offerFirst?(E e) | |
void addLast(); | boolean offerLast?(E e) | ||
E getFirst(); | 如果没有元素会抛出NoSuchElementException异常。 | E peekFirst() | 如果没有元素会返回null |
E getLast(); | 如果没有元素会抛出NoSuchElementException异常。 | E peekLast() | 如果没有元素会返回null |
E removeFirst(); | 如果没有元素会抛出NoSuchElementException异常。 | E pollFirst() | 如果没有元素会返回null |
E removeLast(); | 如果没有元素会抛出NoSuchElementException异常。 | E pollLast() | 如果没有元素会返回null |
使用LinkedList的特有方法实现堆栈、队列结构
package second.study; import java.util.LinkedList; public class Test { public static void main(String[] args) { Stack<String> stack = new Stack<String>(); stack.myAdd("Java01"); stack.myAdd("Java02"); stack.myAdd("Java03"); stack.myAdd("Java04"); while(!stack.isNull()) { System.out.println(stack.myGet()); } System.out.println("hello"); } } class Stack<E>{//堆栈结构:先进后出 private LinkedList<E> link; Stack(){ link = new LinkedList<E>(); } public boolean myAdd(E e) { return link.offerFirst(e); } public E myGet() { return link.pollFirst(); } public boolean isNull() { return link.isEmpty(); } } class Queue<E>{//队列结构,先进先出 private LinkedList<E> link; Queue(){ link = new LinkedList<E>(); } public boolean myAdd(E e) { return link.offerFirst(e); } public E myGet() { return link.pollLast(); } public boolean isNull() { return link.isEmpty(); } }
泛型
好处:
1.将运行时期出现的问题ClassCastException,转移到了编译时期。
2.避免了强制转换的麻烦。
格式:
通过<>来定义要操作的引用数据类型。
泛型方法:
public <T> void show(T t);
特殊:静态方法不可以访问类上定义的泛型。如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。
通配符 ?作用:一般用于程序的扩展,但也有局限性。
? extends E:可以接收E类型或E的子类型,上限;
? super E:可以接收E类型或E的父类型,下限;
Map集合
该集合存储键值对,一对一对往里存,而且要保证键的唯一性。Set集合底层就是调用的Map集合。
添加元素时,如果出现相同的键,那么后添加的值会覆盖原有键对应的值。并返回被覆盖的值。
Map集合典型继承体系树
Map集合的两种取出方式:
1.Set<K> keySet()方法:将map中所有的键存入到Set集合中,因为Set具备迭代器,可以使用迭代器方式取出所有的键。再根据Map集合中的get方法,获取每个键对应的值。
2.Set<Map.Entry<K,V>> entrySet()方法:将map集合中的映射关系存入到Set集合中,而这个关系的数据类型为Map.Entry。
Map
|--Hashtable:数据结构:哈希表,同步的,不允许null作为键和值。被HashMap替代。
|--Properties:属性集,键和值都是字符串,而且可以结合流进行键值操作,等到了IO流,会更清楚。
|--HashMap:数据结构:哈希表,不同步的,允许null作为键和值。
|--LinkedHashMap:基于链表+哈希表,可以保证map集合有序(存入和取出的顺序一致)。
|--TreeMap:数据结构:二叉树。不是同步的,可以对map集合中的键进行排序。
项目练习
需求:
每一个学生都有自己的归属地;
学生属性:姓名,年龄;
注意:姓名和年龄相同的视为同一个学生
package second.study; public class Student implements Comparable<Student> { private String name; private int age; public Student(String name, int age) { super(); 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 int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } @Override public int compareTo(Student o) {//按年龄排序,年龄相同按姓名字典顺序排序 int res = Integer.valueOf(this.age).compareTo(Integer.valueOf(o.age)); return res == 0?this.name.compareTo(o.name):res; } }
package second.study; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; //使用HahMap存储 public class Test { public static void main(String[] args) { HashMap<Student,String> hashMap = new HashMap<Student, String>(); hashMap.put(new Student("zhangsan1", 20), "shanghai"); hashMap.put(new Student("zhangsan2", 30), "nanjing"); hashMap.put(new Student("zhangsan3", 28), "zhejiang"); // hashMap通过判断键中的hashCode和equals方法,来判断键是否相同,相同则覆盖值。 hashMap.put(new Student("zhangsan3", 28), "tianjin"); hashMap.put(new Student("zhangsan4", 25), "hangzhou"); // 通过获取hashMap中的键,来迭代。 Set<Student> set = hashMap.keySet(); for (Iterator<Student> iterator2 = set.iterator(); iterator2.hasNext();) { Student student = iterator2.next(); String add = hashMap.get(student); System.out.println(student + "..." + add); } // 获取迭代器中的键值关系来获取键值 Set<Map.Entry<Student,String>> mapEntry = hashMap.entrySet(); for (Iterator<Map.Entry<Student,String>> iterator = mapEntry.iterator(); iterator.hasNext();) { Map.Entry<Student, String> entry = iterator.next(); System.out.println(entry.getKey() + "......" + entry.getValue()); } } }
Res: Student [name=zhangsan4, age=25]...hangzhou Student [name=zhangsan1, age=20]...shanghai Student [name=zhangsan2, age=30]...nanjing Student [name=zhangsan3, age=28]...tianjin Student [name=zhangsan4, age=25]......hangzhou Student [name=zhangsan1, age=20]......shanghai Student [name=zhangsan2, age=30]......nanjing Student [name=zhangsan3, age=28]......tianjin
使用TreeMap存储
package second.study; import java.util.TreeMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class Test { public static void main(String[] args) { TreeMap<Student,String> treeMap = new TreeMap<Student, String>(); treeMap.put(new Student("zhangsan1", 20), "shanghai"); treeMap.put(new Student("zhangsan2", 30), "nanjing"); treeMap.put(new Student("zhangsan3", 28), "zhejiang"); // hashMap通过判断键中的hashCode和equals方法,来判断键是否相同,相同则覆盖值。 treeMap.put(new Student("zhangsan3", 28), "tianjin"); treeMap.put(new Student("zhangsan4", 25), "hangzhou"); treeMap.put(new Student("zhangsan1", 25), "hangzhou"); // 通过获取hashMap中的键,来迭代。 Set<Student> set = treeMap.keySet(); for (Iterator<Student> iterator2 = set.iterator(); iterator2.hasNext();) { Student student = iterator2.next(); String add = treeMap.get(student); System.out.println(student + "..." + add); } // 获取迭代器中的键值关系来获取键值 Set<Map.Entry<Student,String>> mapEntry = treeMap.entrySet(); for (Iterator<Map.Entry<Student,String>> iterator = mapEntry.iterator(); iterator.hasNext();) { Map.Entry<Student, String> entry = iterator.next(); System.out.println(entry.getKey() + "......" + entry.getValue()); } } }
Res: Student [name=zhangsan1, age=20]...shanghai Student [name=zhangsan1, age=25]...hangzhou Student [name=zhangsan4, age=25]...hangzhou Student [name=zhangsan3, age=28]...tianjin Student [name=zhangsan2, age=30]...nanjing Student [name=zhangsan1, age=20]......shanghai Student [name=zhangsan1, age=25]......hangzhou Student [name=zhangsan4, age=25]......hangzhou Student [name=zhangsan3, age=28]......tianjin Student [name=zhangsan2, age=30]......nanjing
集合框架工具类(Collections)全部是静态方法
常见方法:
1.static <T extends Comparable<? super T>> void sort?(List<T> list);//对List集合中的元素按照元素中的compareTo方法排序;
static <T extends Comparable<? super T>> void sort?(List<T> list, Comparator<? super T> c);//对List集合中的元素按照自定义的compareTo方法排序;
2.static <T extends Object & Comparable<? super T>> T max?(Collection<? extends T> coll);//对List集合中的元素按照元素中的compareTo方法的返回值大小获取最大值;
static <T> T max?(Collection<? extends T> coll, Comparator<? super T> comp);//对List集合中的元素按照自定义的compareTo方法的返回值大小获取最大值;
3.static <T> int binarySearch?(List<? extends Comparable<? super T>> list, T key);//List中的元素必须实现Comparable接口,然后用1.(1)的sort方法对集合进行排序后可返回正确结果。
static <T> int binarySearch?(List<? extends T> list, T key, Comparator<? super T> c);//List中的元素必须实现Comparable接口,然后用1.(2)的sort方法对集合进行排序后可返回正确结果。
4.static <T> Comparator<T> reverseOrder();//对该集合中的元素的排序方法强行逆转;
static <T> Comparator<T> reverseOrder?(Comparator<T> cmp);//对自定义的比较器强行逆转。
数组集合工具类(Arrays)全部是静态方法
常见方法:
1.static <T> List<T> asList?(T... a); //将数组转成List集合,可以使用集合的思想操作字符串,但是不可以进行增删操作。
注意:如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。
如果数组中的元素是基本数据类型时,那么会将该数组作为集合中的元素存在。eg:int[] arr = {2,3,4};List<int[]> list = Arrays.asList(arr);
将集合变成数组,使用的是集合中的toArray方法(<T> T[] toArray?(T[] a),优势:为了限定对元素的操作,不能进行增删操作。
注意:当传入参数类型的长度小于集合的size,内部会创建一个新数组,长度为集合的size。
当传入参数类型的长度大于集合的size,就不会创建数组了,而是使用传递进来的数组。
原文:https://www.cnblogs.com/star-491849224/p/12499778.html