Java集合之Collection

集合与数组的区别

数组:
1.存储 基本类型 和 引用类型的数据
2.长度是固定的。
集合:
1.只能存储引用类型的数据。
2.可以扩容变长。

Collection常用方法

  1. boolean add(E e);
    用于向集合中添加元素。如果添加元素确实改变了集合就返回true,如果集合没有发生改变就返回false。例如,如果试图向集合中添加一个对象,而这个对象在集合中已经存在,这个添加就没有生效,因为集合中不允许有重复的对象。

  2. boolean addAll(Collection<? extends E> c);
    将c集合中的所有元素添加到这个集合,如果这个调用改变了集合,返回true

  3. int size(); 返回当前存储在集合中的元素个数

  4. boolean isEmpty(); 如果集合中没有元素,返回true

  5. boolean contains(Object o); 如果集合中包含了一个与o相等的对象,返回true

  6. boolean containsAll(Collection<?> c); 如果这个集合保护c集合的多有元素,返回true

  7. Object[] toArray(); 返回这个集合的对象数组

  8. T[] toArray(T[] a);
    返回这个集合的对象数组,如果a足够大,就将集合中的原损填入这个数组中,剩余空间补null,否则分配一个新数组,其成员类型与a的成员类型相同,其长度等于集合的大小,并填入集合元素

  9. boolean remove(Object o); 从这个集合中删除等于o的对象,如果有匹配的对象被删除,返回true

  10. boolean removeAll(Collection<?> c);
    从这个集合中删除c集合中存在的所有元素,如果由于这个调用改变了集合,返回true

  11. boolean retainAll(Collection<?> c);
    从这个集合中删除所有与c集合中的元素不同的元素,如果由于这个调用改变了集合,返回true

  12. void clear(); 从这个集合中删除所有元素

public static void main(String[] args) {
		Collection<String> c = new ArrayList<>();
		// 1. 添加 一个元素信息,添加成功true,失败false
		c.add("aa");
		c.add("bb");
		c.add("cc");
		System.out.println(c);//[aa, bb, cc]
		// 2. 集合是否为 空 ,为空 true
		System.out.println(c.isEmpty());// false
		// 3. 获得集合中已经存储的元素的个数
		System.out.println(c.size());// 3
		// 4. 把参数集合中的所有元素添加到 当前集合中,当前集合发生了改变true
		Collection<String> c1 = new ArrayList<>();
		c1.add("dd");
		c1.add("ee");
		// c1 dd,ee
		c.addAll(c1);
		System.out.println(c);// [aa, bb, cc, dd, ee]
		// 5. 把参数对象 从当前集合中删除掉。当前集合发生了改变true
		c.remove("cc");
		System.out.println(c);// [aa, bb, dd, ee]
		// 6. 删除 参数集合中的所有元素,当前集合发生了改变true
		c.removeAll(c1);
		System.out.println(c);// [aa, bb]
		// 7. 参数对象 在 当前集合中是否包含,存true
		System.out.println(c.contains("aa"));// true
		System.out.println(c.contains("ee"));// false
		// 8.  [aa, bb] 集合转数组,把集合中元素 存储到一个数组对象中
		Object [] objs = c.toArray();
		objs = c.toArray(new Object[0]);// [aa, bb]
		objs = c.toArray(new Object[5]);// [aa, bb, null, null, null]
		System.out.println(Arrays.toString(objs));// [aa, bb]
		// 保留类型
		String [] strs = c.toArray(new String[0]);
		System.out.println(Arrays.toString(strs));// [aa, bb]
		// 9. 清空
		c.clear();
		System.out.println(c);// []
		System.out.println(c.isEmpty());// true
		System.out.println(c.size());// 0
	}

List集合

List 就是列表的意思,它是Collection 的一种,即继承了 Collection 接口,可以定义一个允许重复项的有序集合。
该接口不但能够对列表的一部分进行处理,还添加了面向位置(索引)的操作。
List 是按对象的进入顺序进行保存对象,而不做排序或编辑操作。它除了拥有Collection接口的所有的方法外还拥有一些其他的方法。
面向位置(索引)的操作包括插入某个元素或 Collection 的功能,还包括获取、除去或更改元素的功能。在 List 中搜索元素可以从列表的头部或尾部开始,如果找到元素,还将报告元素所在的位置。

List的方法

  1. boolean addAll(Collection<? extends E> c)
    按照迭代器返回的元素顺序,将指定集合插入到指定集合中

  2. boolean addAll(int index, Collection<? extends E> c)
    从指定的位置开始,将指定 collection 中的所有元素插入到此列表中

  3. E get(int index)
    返回列表中指定位置的元素

  4. int indexOf(Object o)
    返回该元素第一次出现在集合中的索引值;若不包含该元素,则返回 -1

  5. int lastIndexOf(Object o)
    返回该元素最后一次出现在集合中的索引值;若不包含该元素,则返回 -1

  6. ListIterator listIterator()
    返回此列表元素的列表迭代器(按适当顺序)

  7. E remove(int index)
    根据索引删除元素,返回值为被删除的元素

  8. E set(int index, E element)
    根据索引,修改集合中的元素,返回值为替换前的元素

public static void main(String[] args) {
		 
		List<String> list = new ArrayList<>();
		// 分配索引,按照元素添加的顺序
		list.add("aa");// 0
		list.add("bb");// 1 
		list.add("cc");// 2
		System.out.println(list);// [aa, bb, cc]
		// 1. 向指定索引位置 添加一个元素
		list.add(1, "hello");
		System.out.println(list);// [aa, hello, bb, cc]
		// 2. 获得参数位置的 元素
		System.out.println(list.get(3));// cc
		// 3. 修改指定位置的元素
		list.set(1, "Tom");
		System.out.println(list);// [aa, Tom, bb, cc]
		// 4. 取 子集合
		System.out.println(list.subList(0, 2));// [aa, Tom]
		// 5.
		list.sort(new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				return o1.compareTo(o2);
			}
		});//[Tom, aa, bb, cc]
		list.sort((s1,s2)->s2.compareTo(s1));// [cc, bb, aa, Tom
		// 默认 按照 自然升序(Comparable)
		list.sort(null);// 空对象 没有指定比较器 这里用String的比较器 升序
		System.out.println(list);// [Tom, aa, bb, cc]

	}

List接口子实现类的特点

  1. ArrayList:底层结构是数组,增删慢,查询快(线程不安全,效率高)
  2. Vector:底层结构是数组,增删,查询都很慢(线程安全,因此查询效率比ArrayList要低),现在一般不用这个类
  3. LinkedList:内部是链表数据结构,增删元素的速度很快(线程不安全)

集合遍历

Iterator迭代器

Iterator 只能用于 Collection迭代

  1. Iterator iterator();
    iterator()方法用于返回一个实现了Iterator接口的对象。可以使用这个迭代器对象依次访问集合中的元素
  2. boolean hasNext(); 如果存在可访问的元素,返回true
  3. E next(); 返回将要访问的下一个对象,如果已经到达了集合的尾部,将抛出NoSuchElementWxception
  4. void remove()
    删除上次访问的对象。这个方法必须紧跟在访问一个元素之后执行。如果上次访问之后集合已经发生了变化,将抛出IllegalStateException.
public static void main(String[] args) {
		Collection<String> c = new ArrayList<>();
		c.add("aa");
		c.add("bb");
		c.add("cc");
		System.out.println(c);//[aa, bb, cc]
		// 集合的遍历
		// 1. 增强for
		for(String s:c){
			System.out.println(s);
		}
		// 2. 集合的forEach
		c.forEach(System.out::println);
		// 3. 迭代器
		Iterator<String> ir = c.iterator();
		// (1)
		ir.forEachRemaining(System.out::println);
		// (2) next()
		System.out.println("-------------");
		ir = c.iterator();//上一个迭代器的指针已经到了末尾,这里重新获得一个迭代器
//		System.out.println(ir.next());// aa
//		System.out.println(ir.next());// bb
//		System.out.println(ir.next());// cc
		// 循环简化
		// 是否获得下一个元素,获得 true
		while(ir.hasNext()){
			System.out.println(ir.next());
		}

	}

ListIterator迭代器

ListIterator 是 Iterator的子接口,只能遍历 List,比Iterator多了两个方法

  1. hasPrevious()

  2. previous()

public static void main(String[] args) {
		List<String> list = new ArrayList<>();
		list.add("aa");// 0
		list.add("bb");// 1
		list.add("cc");// 2
		System.out.println(list);// [aa, bb, cc]
		// 1. 增强for
		// 2. forEach()
		// 3. Iterator 
		// --------------- List独特的了--------------------
		// 4. 基本for
		for(int i = 0 ; i < list.size(); i ++){
			System.out.println(list.get(i));
		}
		// 5. 迭代器 ListIterator 
		ListIterator<String> li = list.listIterator();
		// 向后遍历
		System.out.println("------------------");
		while(li.hasNext()){
			System.out.println(li.next());
			li.add("hello");
		}
		System.out.println("-----------------------");
		// 是否存在上一个元素 ,存在 true
		while(li.hasPrevious()){
			System.out.println(li.previous());
		}
		// remove() 删除最近一次调用next()的元素
		//-------------------------------------------
		li = list.listIterator();// 迭代器
		System.out.println(list);// [aa, hello, bb, hello, cc, hello]
		System.out.println(li.next());// aa
		System.out.println(li.next());// hello
		li.remove();//删除最近一次调用next()的元素
		System.out.println(li.next());
		li.remove();
		System.out.println(list);

	}

ArrayList

数组作为底层数据结构

public static void main(String[] args) {
		
		/*
		 * 底层的数组:   transient Object[] elementData;
		 *  private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
		     public ArrayList() {
        		this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    			}
		 */
		ArrayList<String> list = new ArrayList<>();
		/*
		 * 添加元素:
		 * 初始容量: private static final int DEFAULT_CAPACITY = 10;
		 * 扩容方式: int newCapacity = oldCapacity + (oldCapacity >> 1);
		 * private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
		 * 最大容量: Integer.MAX_VALUE 
		 */
		list.add("aa");
		list.add("aa");
		list.add("bb");
		list.add("cc");
		list.add("cc");
		System.out.println(list);// [aa, aa, bb, cc, cc]
		System.out.println(list.size());// 5
	}

ArrayList扩容机制

LinkedList

底层是链表
链表:由 非连续的结点Node 组成的存储结构。
链表使用Node 存储数据。

public static void main(String[] args) {
		LinkedList<String> list = new LinkedList<>();
		/*
		 * 结点存数据:
		 * 
		 *     private static class Node<E> {
        			E item;
        			Node<E> next;
        			Node<E> prev;

        			Node(Node<E> prev, E element, Node<E> next) {
            		this.item = element;
            		this.next = next;
            		this.prev = prev;
        }
    }
		 */
		list.add("aa");
		list.add("bb");
		list.add("cc");
		list.addLast("dd");
		list.addFirst("hello");
		System.out.println(list);// [hello, aa, bb, cc, dd]

	}

ArrayList 和LinkedList区别

ArrayList :存储空间是连续的,因此遍历和查询速度快,但删除和插入速度慢
LinkedList:存储空间不连续,遍历和查询速度慢,删除和插入速度快

ArrayList 和 Vector 区别

底层都是数组。

  1. ArrayList 1.2版本
    Vector 1.0版本 (性能低)
  2. ArrayList :线程非安全 ,速度快
    Vector : 线程安全的。速度慢。
  3. ArrayList 扩容: old容量 + old 容量 * 0.5
    Vector扩容 : old 容量 + old容量
posted @ 2020-03-17 22:23  我不是忘尘  阅读(229)  评论(0)    收藏  举报