集合和数组的区别?
- 集合的长度可变,数组的长度时固定的
- 集合只可以存储引用类型,数组可以存储基本类型和引用类型
- 集合可以同时存储多种类型数据,数组只能存储同种类型数据
Collection集合:接口
- 一些集合可以允许元素重复(List),一些集合不允许元素重复(Set)
- 一些集合可以允许元素有序(存储和取出一致:List),一些集合无序的(存储和取出不一致:Set)
JDK不提供此接口的任何直接实现,通过具体的子接口的子实现类实现!
基本功能
添加元素
* boolean add(Object e)
* 删除元素
* void clear():暴力删除,全部清空
* boolean remove(Object o):删除指定的元素
* 判断功能
* 判断集合中是否包含元素
* boolean contains(Object o):判斷集合是否包含指定的元素
* boolean isEmpty():判断集合是否为空
* 获取集合的元素数:
* int size()
* 转换功能:
* Object[] toArray():将集合转换成数组class Test{ public static void main(String[] args) { Collection list = new ArrayList(); //添加功能 list.add("aaa"); list.add(100); list.add('a'); System.out.println(list);// list.remove("aaa");//删除指定元素 System.out.println(list); System.out.println(list.contains('a'));//判断集合中是否包含元素 System.out.println(list.isEmpty());//判断集合是否为空 System.out.println("list集合的长度:"+list.size());//获取集合长度 Object[] objects = list.toArray();//转换为数组 //遍历object数组 for (int i = 0; i < objects.length; i++) { System.out.print(objects[i]+", "); } System.out.println(); list.clear();//暴力删除全部 System.out.println(list); } }
Collection集合的高级功能:
- boolean addAll(Collection c):添加一个集合中的所有元素
class Test{ public static void main(String[] args) { Collection list = new ArrayList(); //添加功能 list.add("abc1"); list.add("abc2"); Collection list2 = new ArrayList(); list2.add("abc1"); list2.add("abc2"); System.out.println(list); list.addAll(list2);//添加一个集合中的所以元素 System.out.println(list); } }
- boolean removeAll(Collection c):取A和B集合的交集,在A集合中删除
class Test{ public static void main(String[] args) { Collection list = new ArrayList(); //添加功能 list.add("abc1"); list.add("abc2"); list.add("abc3"); list.add("abc4"); Collection list2 = new ArrayList(); list2.add("abc1"); list2.add("abc7"); list2.add("abc5"); list2.add("abc6"); System.out.println(list); list.removeAll(list2);//删除两个集合的交集 System.out.println(list); } }
- boolean containsAll(Collection c) :判断是否包含所有元素
class Test{ public static void main(String[] args) { Collection list = new ArrayList(); //添加功能 list.add("abc1"); list.add("abc2"); list.add("abc3"); list.add("abc4"); list.add("abc5"); Collection list2 = new ArrayList(); list2.add("abc1"); list2.add("abc2"); list2.add("abc3"); list2.add("abc4"); boolean flag = list.containsAll(list2);//判断是否包含另个集合的所以元素 System.out.println(flag); } }
- boolean retainAll(Collection c):对集合取交集:A集合对B集合取交集,看当两个的交集放到A集合中时A的集合元素有没有改变
有变化,就返回true
没有变化,就返回false!
class Test{ public static void main(String[] args) { Collection list = new ArrayList(); //添加功能 list.add("abc1"); list.add("abc2"); list.add("abc3"); Collection list2 = new ArrayList(); list2.add("abc1"); list2.add("abc2"); Collection list3 = new ArrayList(); list3.add("abc1"); list3.add("abc2"); list3.add("abc3"); list3.add("abc4"); Collection list4 = new ArrayList(); list4.add("a"); //对元素取交集 System.out.println(list.retainAll(list2)); System.out.println(list.retainAll(list3)); System.out.println(list.retainAll(list4)); } }
集合的专有迭代器:Iterator iterator() :
Collection接口的迭代器
迭代器属于集合的专有遍历方式Collection迭代器的结构
//迭代器 interface Iterator{ boolean hasNext() ; E next() ; //E :Element :代表任意类型 (Object) } //<E>Element,<T> Type 存储元素类型 //Iterator的封装接口 interface Iterable{ Iterator iterator();//:将指定类型的元素在迭代器上进行遍历 } interface Collection extends Iterable{ Iterator iterator()//:将指定类型的元素在迭代器上进行遍历 } interface List extends Collection{ Iterator iterator()//:将指定类型的元素在迭代器上进行遍历 } //具体子实现类 class ArrayList implements List{ public Iterator<E> iterator() { return new Itr(); //创建Itr类对象 } //ArrayList$Itr :成员内部类 private class Itr implements Iterator<E>{ public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked")//强制压制警告 public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } } } /*Collection 迭代器的原理:就是实现了Iterator接口的子实现类 ArrayList:Itr内部类 List----> ListIterator:列表迭代器 接口---->子实现类的 ListItr内部类*/
Collection list = new ArrayList(); Iterator iterator = list.iterator();通过Arraylist中的方法iterator(重写来自Iterable接口的方法)返回一个成员内部类对象(Itr),这个内部类实现了Iterator接口。通过接口多态创建Iterator对象
Iterator接口的方法:
boolean hasNext():判断迭代器中是否存在下一个元素
Object next()返回迭代的下一个元素。
class Student{ private String name; private String gender; public Student(String name, String gender) { this.name = name; this.gender = gender; } public String getName() { return name; } public String getGender() { return gender; } } class Test{ public static void main(String[] args) { //创建对象 Student sd = new Student("小明","男"); Student sd1 = new Student("小李","女"); Collection list = new ArrayList();//创建集合 //添加功能 list.add(sd); list.add(sd1); // for (Iterator iterator = list.iterator(); iterator.hasNext(); System.out.println(iterator.next())) { // } Iterator iterator = list.iterator();//创建迭代器 while(iterator.hasNext()){//判断是否存在下一个元素 Object obj = iterator.next();//使用Object类获取元素对现象 Student sd2 = (Student) obj;//向下转型为Student类对象引用 System.out.println(sd2.getName()+"=="+sd2.getGender()); } } }
注意:使用Iterator迭代器去遍历元素,不能使用集合操作元素,否则会出现并发修改异常: java.util.ConcurrentModificationException
解决方案:
- 集合遍历,集合操作元素-------------->需要使用List集合的get()方法
class Test{ public static void main(String[] args) { //创建对象 Student sd = new Student("小明","男"); Student sd1 = new Student("小李","女"); Student sd2 = new Student("小刘","男"); List list = new ArrayList();//创建集合 //添加功能 list.add(sd); list.add(sd1); for (int i = 0; i < list.size(); i++) { if(list.get(i).equals(new Student("小明","男"))){ list.add(i+1,sd2);//在指定位置的位置添加元素 break;//结束循环 } } //迭代器 Iterator iterator = list.iterator(); while(iterator.hasNext()){ Object o = iterator.next(); Student sd3 = (Student) o; System.out.println(sd3.getName()+"=="+sd3.getGender()); } } }
- 迭代器遍历,迭代器操作元素----------->使用List接口的方法:ListIterator 列表迭代器
class Test{ public static void main(String[] args) { //创建对象 Student sd = new Student("小明","男"); Student sd1 = new Student("小李","女"); Student sd2 = new Student("小刘","男"); List list = new ArrayList();//创建集合 //添加功能 list.add(sd); list.add(sd1); ListIterator lt = list.listIterator();//迭代器迭代 while(lt.hasNext()){ if(lt.next().equals(new Student("小明","男"))){//使用equals方法需要重写Object的hashcode和equals方法 lt.add(sd2);//迭代器添加 } } //迭代器 Iterator iterator = list.iterator(); while(iterator.hasNext()){ Object o = iterator.next(); Student sd3 = (Student) o; System.out.println(sd3.getName()+"=="+sd3.getGender()); } } }
List集合
List集合特点:
* 有序的(存储和取出一致)
* 集合的元素是可以重复的特有功能
* void add(int index,Object element):在指定的位置处 添加元素
* Object get(int index):通过角标可以获取指定的元素 + size() :普通for循环遍历
* ListIterator<Object> listIterator(): 可以使用List集合的专有遍历方式
* Object remove(int index):通过该角标删除指定的元素class ListDemo { public static void main(String[] args) { //创建List集合对象 List<String> list = new ArrayList<String>() ; //添加元素 list.add("hello") ; list.add("world") ; list.add("world") ; list.add("javaee") ; System.out.println(list); //void add(int index,Object element):在指定的位置处 添加元素 list.add(2,"android") ; System.out.println(list); //Object get(int index):通过角标可以获取指定的元素 String s = list.get(4); System.out.println(s); // Object remove(int index):通过该角标删除指定的元素 System.out.println(list.remove(2)); //返回被删除的元素 System.out.println(list); } }
List集合去重
- 新建集合思想:
* 使用新集合对象判断元素不包含,就不重复!
* contains方法底层依赖于equals方法
* 要去去重自定义对象,必须在当前类中重写equals以及 hashCode()class Test{ public static void main(String[] args) { //创建对象 Student sd = new Student("小明","男"); Student sd1 = new Student("小李","女"); Student sd2= new Student("小刘","男"); List list = new ArrayList();//创建集合 //添加功能 list.add(sd); list.add(sd1); list.add(sd1); list.add(sd2); list.add(sd2); Iterator iterator = list.iterator(); while(iterator.hasNext()){ Object o = iterator.next(); System.out.println(o); } System.out.println("=========去重复之后==========="); List newList = new ArrayList();//创建新集合 for (int i = 0; i < list.size(); i++) {//遍历旧集合 if(!newList.contains(list.get(i))){//当旧集合中的元素不在新集合中时 newList.add(list.get(i));//在新集合中添加 } } //迭代器 Iterator iterator1 = newList.iterator(); while(iterator1.hasNext()){ System.out.println(iterator1.next()); } } }
- 使用选择排序思想
class Test{ public static void main(String[] args) { //创建对象 Student sd = new Student("小明","男"); Student sd1 = new Student("小李","女"); Student sd2= new Student("小刘","男"); List list = new ArrayList();//创建集合 //添加功能 list.add(sd); list.add(sd1); list.add(sd1); list.add(sd2); list.add(sd2); Iterator iterator = list.iterator(); while(iterator.hasNext()){ Object o = iterator.next(); System.out.println(o); } System.out.println("=========去重复之后==========="); for (int i = 0; i < list.size()-1; i++) { for (int j = i+1; j < list.size(); j++) { if(list.get(i).equals(list.get(j))){ list.remove(j);//移除相等的元素 j--; } } } //迭代器 Iterator iterator1 = list.iterator(); while(iterator1.hasNext()){ Object o = iterator1.next(); System.out.println(o); } } }
List的三个子实现的特点:
ArrayList
List 接口的大小可变数组的实现:底层数据结构是数组
数组--->查询元素 数组名称[角标]
查询快,增删慢线程角度:
是一个不安全的类,不同步的,所以默认没有明确要求使用哪种集合都是使用ArrayList(执行效率高)Vector
可以实现可增长的对象数组; 底层数据结构数组
数组--->查询元素 数组名称[角标]
查询快,增删慢
线程角度:
Vector 是同步的,-----线程安全可靠, 执行效率低LinkedList
链接列表实现:底层数据结构是链表查询慢:都需要从链接列表查到末尾
增删快:数据域和指针域; 使用中间互换!
线程角度:
实现不同步的,是一个线程不安全的类,执行效率高!