黑马程序员——Collection单列集合

------- android培训java培训、期待与您交流! ----------

(一)集合概述

出现意义:面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

集合与数组辨析
容器长度
          集合长度可变
          数组长度固定
存储内容类型
          集合存储引用数据类型
          数组存储任意类型
是否可存储不同类型数据
         集合可以存储不同类型数据
         数组只能存储相同数据类型

Java中的集合:JDK为我们提供了一套完整的容器类库,这些容器可以用于存储各种类型的对象,并且长度都是可变的,我们把这些类统称为集合类,它们都位于java.util包中。


分类:

单列集合Collection
      -List:元素有序、包含重复元素
      -Set:元素无序、不包含重复元素
双列集合Map:键值映射关系
其他功能接口
    -迭代器Iterator
    -Comparable与Comparator用于比较元素

(二)Collection
lCollection接口:单列集合的根接口
主要方法
        -boolean add(E e)
        -boolean remove(Object o)
        -void clear()
        -boolean contains(Object o)
       -boolean isEmpty()
       -int size()
主要方法2
       -boolean addAll(Collection c)
       -boolean removeAll(Collection c)
       -boolean containsAll(Collection c)
       -boolean retainAll(Collection c)
返回迭代器方法
      -Iterator<E>iterator()
lIterator接口:单列集合的迭代器。迭代器会像地震搜救队的方式一样去遍历集合中的每一个元素。
主要方法
-boolean hasNext()
-E next()
使用固定格式:
格式一:

Collection c = new ArrayList();

Iterator it = c.iterator();

while(it.hasNext()){

   System.out.println(it.next());

}

格式二:

for(Interator it = c.iterator();it.hasNext();){

     System.out.println(it.next());

}

练习:

/*
 * 集合概述:
 * 		面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式
 * 		JDK为我们提供了一套完整的容器类库,这些容器可以用于存储各种类型的对象,并且长度都是可变的,
 * 		我们把这些类统称为集合类,它们都位于java.util包中。
 * 
 * Collection:所有单列集合的接口
 * 由于该Collection是一个接口,无法直接创建实例,使用其子类ArrayList对象来创建对象,完成Collection方法的学习。
 * 
 * 1:创建集合对象
 * 2:创建元素对象
 * 3:将元素放到集合中
 * 4:集合遍历(集合获取内容)
 * 
 * boolean add(E e) 添加元素
 */
public class Demo01_Collection {

	public static void main(String[] args) {
		
		Collection c = new ArrayList();
		
		c.add("abc");
		c.add("bcd");
		
		Person p = new Person("黄盖",58);
		c.add(p);
		c.add(p);
		
		c.add(true);
		
		
		System.out.println(c);
	}

	//之前的数组容器,长度是固定的。添加新的内容算法麻烦
	public void method(){
		String[] arr = new String[]{"曹操","刘备","孙权","曹丕","刘禅","董卓"};
		
		while(true) {
			System.out.println("柳岩找男朋友:");
			Random random = new Random();
			int randomIndex = random.nextInt(arr.length);
			
			System.out.println("与您配对的是"+arr[randomIndex]);
			System.out.println("您是否满意:满意输入1,不满意输入2,将继续匹配");
			Scanner sc = new Scanner(System.in);
			
			String next = sc.next();
			if(next.equals("1")) {
				System.out.println("祝你们幸福");
				break;
			}else if(next.equals("2")){
				continue;
			}
			
		}
	}
}

/*
 * 
 * 1:创建集合对象
 * 2:创建元素对象
 * 3:将元素放到集合中
 * 4:集合遍历(集合获取内容)
 * 
 * Collection类的其他方法:
 * 		boolean add(E e) 添加元素
 * 		boolean remove(Object o) 删除元素
 */
public class Demo02_Collection {

	public static void main(String[] args) {
		method2();
	}

	//使用集合存储特殊引用类型字符串
	public static void method() {
		//1:创建集合对象
		Collection c = new ArrayList();
		//2:创建元素对象
		String s = "郭采洁";
		String s2 = "郭嘉";
		String s3 = "郭靖";
		String s4 = "郭达";
		String s5 = "郭德纲";
		//3:将元素添加到集合中
		c.add(s);
		c.add(s2);
		c.add(s3);
		c.add(s4);
		c.add(s5);

		System.out.println(c);
		System.out.println(c.remove("郭达"));
		System.out.println(c.remove("郭敬明"));
		System.out.println(c);
	}

	
	//使用集合存储一般的引用类型 Person
		public static void method2() {
			//1:创建集合对象
			Collection c = new ArrayList();
			//2:创建元素对象
			Person p = new Person("郭采洁",28);
			Person p2 = new Person("郭嘉",32);
			Person p3 = new Person("郭靖",18);
			Person p4 = new Person("郭达",80);
			Person p5 = new Person("郭德纲",44);

			//3:将元素添加到集合中
			c.add(p);
			c.add(p2);
			c.add(p3);
			c.add(p4);
			c.add(p5);
			c.add(p4);

			System.out.println(c);
//			System.out.println(c.remove(p4));
			boolean b = c.remove(new Person("郭达",80));
			System.out.println(b);
			System.out.println(c.remove(new Person("郭敬明",9)));
			System.out.println(c);
		}
}

/*
 * Collection类的其他方法:
 * 		boolean add(E e) 添加元素
 * 		boolean remove(Object o) 删除元素
 * 		void clear()  清空集合
 * 		boolean contains(Object o)  判断集合中是否包含参数元素
 * 		boolean isEmpty()  判断集合是否为空
 */
public class Demo03_Collection {

	public static void main(String[] args) {
		
		Collection c = new ArrayList();
		
		c.add("黄忠");
		c.add("黄月英");
		c.add("黄盖");
		c.add("黄晓明");
		
		System.out.println(c);
		System.out.println("该集合长度为:"+c.size());
		System.out.println("以上集合是否为空:"+c.isEmpty());
		System.out.println("判断该集合是否有黄家驹:"+c.contains("黄家驹"));
		
		c.clear();
		System.out.println("清空后的集合内容:"+c);
		System.out.println("该集合长度为:"+c.size());
		System.out.println("以上集合是否为空:"+c.isEmpty());
		
		Collection c2 = new ArrayList();
		
		c2.add(new Person("黄忠",18));
		c2.add(new Person("黄月英",18));
		c2.add(new Person("黄盖",18));
		c2.add(new Person("黄晓明",18));
		
		System.out.println(c2.contains(new Person("黄晓明",18)));
	}

}

/*
 * Collection的普通方法:
 * 		boolean addAll(Collection c)  将参数集合的所有内容,添加到调用方法的集合中
 * 		boolean removeAll(Collection c)  移除此 collection 中那些也包含在指定 collection 中的所有元素
 * 		boolean containsAll(Collection c)  如果此 collection 包含指定 collection 中的所有元素,则返回 true。 
 * 		boolean retainAll(Collection c)  仅保留此 collection 中那些也包含在指定 collection 的元素  即求交集
 * 		调用该方法后,会将交集的内容赋值给调用方法的集合
 *      返回值代表的并不是是否有交集,而是调用方法的集合内容是否改变
 */
public class Demo04_Collection {

	public static void main(String[] args) {
		
		Collection<String> c = new ArrayList<String>();
		
		c.add("abc");
		c.add("bcd");
		c.add("cde");
		
		Collection<String> c2 = new ArrayList<String>();
		
		c2.add("134");
		c2.add("134e");
		c2.add("13234");
		
		c.addAll(c2);
		c.addAll(c2);
		System.out.println("c1:"+c);
		System.out.println("c2:"+c2);
		
		System.out.println("判断C1中是否包含C2中的所有元素"+c.containsAll(c2));
		
		c.removeAll(c2);
		
		System.out.println("c1:"+c);
		System.out.println("c2:"+c2);
		System.out.println("判断C1中是否包含C2中的所有元素"+c.containsAll(c2));
		
		
		System.out.println("========================");
		Collection<String> c3 = new ArrayList<String>();
		c3.add("貂蝉");
		c3.add("西施");
		c3.add("杨玉环");
		c3.add("王昭君");
		c3.add("小莲");
		
		Collection<String> c4 = new ArrayList<String>();
		c4.add("貂蝉");
		c4.add("西施");
		c4.add("杨玉环");
		c4.add("王昭君");
		c4.add("李师师");
		c4.add("赵飞燕");
		
		System.out.println(c3);
		System.out.println(c3.retainAll(c4));
		System.out.println(c3);
		
	}

}
/*
 * 1:创建集合对象
 * 2:创建元素对象
 * 3:将元素放到集合中
 * 4:集合遍历(集合获取内容)
 * 
 * Iterator iterator()  返回在此 collection 的元素上进行迭代的迭代器。  即 返回该集合的迭代器对象
 * 
 * Iterator: 用来遍历集合的工具     该类的对象也是容器。在返回的迭代器这个容器中,已经将集合中的内容复制了一份。
 * 在该类中提供了方法,供我们取值
 * boolean hasNext()  判断是否有写一个元素
 * E next()  返回迭代的下一个元素。 
 */
public class Demo05_iterator {

	public static void main(String[] args) {
		
		//1:创建集合对象
		Collection<String> c = new ArrayList<String>();
		//2:创建元素对象
		//3:将元素放到集合中
		c.add("诸葛亮");
		c.add("姜维");
		c.add("司马懿");
		c.add("鲁肃");
		c.add("庞统");
		c.add("周瑜");
		c.add("贾诩");
		c.add("郭嘉");
		c.add("荀彧");
		
		//4:集合遍历(集合获取内容)
		//1)返回迭代器对象
		Iterator<String> iterator = c.iterator();
		//2)调用迭代器的方法
		while(iterator.hasNext()) {
			System.out.println(iterator.next());
		}
		
	}

}
<div>
</div>
(三)List
List:单列集合,可存放重复元素,元素有序
主要子类:
      •ArrayList:底层数据结构是数组结构。线程不安全的。所以ArrayList的出现替代了Vector。增删慢,改查快。
      •LinkedList:底层是链表数据结构。线程不安全的,同时对元素的增删操作效率很高。
      •Vector:底层数据结构是数组结构。jdk1.0版本。线程安全的。无论增删还是查询都非常慢.已被ArrayList替代。
特殊方法
      •void add(int index, E element)
      •E remove(int index)
      •E get(int index)
      •E set(int index, E element)
      •List<E> subList(int fromIndex, int toIndex)
      •int indexOf(Object o)
      •int lastIndexOf(Object o)
      •ListIterator<E> listIterator() 注意:用于应对 并发修改异常
ListIterator:list特有的迭代器,内含避免并发修改异常的算法。
主要方法:
      -boolean hasNext()
      -E next()
      -boolean hasPrevious()
      -E previous() 
      -void add(E e)
      -void remove()
      -void set(E e)
/*
 * List:有序的Collection集合,并且带索引的。
 * 		 可以对插入位置进行精确地控制
 * 
 * List的普通方法:
 * 		void add(int index, E element)  指定位置插入指定元素
 * 		E remove(int index)  删除指定位置的元素
 * 		E get(int index)   获取指定位置的元素
 * 		E set(int index,E element) 替换指定位置的元素为新的元素对象
 */
public class Demo01_List {

	public static void main(String[] args) {

		List list = new ArrayList();
		
		list.add("黄月英");
		list.add("黄飞鸿");
		list.add("黄世仁");
		list.add("黄药师");
		list.add("黄继光");
		
		System.out.println(list);
		
		list.add(2,"黄健翔");
		list.remove(0);
		System.out.println(list.get(0));
		list.set(0, "黄圣依");
		
		System.out.println(list);
	}

}


LinkedList:与ArrayList不同,LinkedList是方便添加删除的List。
主要方法:
      -public void addFirst(E e)
      -public void addLast(E e)
      -public E getFirst() 
      -public E getLast()
/*
 * LinkedList:  可以对集合一头一尾进行便捷操作的List集合对象
 * 
 * 普通方法
 * 		public void addFirst(E e) 插入列表头
 * 		public void addLast(E e) 插入列表尾
 * 
 * 		public E getFirst()  获取列表头
 * 		public E getLast()  获取列表尾
 * */
public class Demo01_LinkedList {

	public static void main(String[] args) {
		
		//创建集合对象
		LinkedList ll = new LinkedList();
		//创建元素对象
		//将元素放到集合中
		ll.add("刘");
		ll.add("张");
		ll.add("赵");
		ll.add("栾");
		ll.add("李");
		
		System.out.println(ll);
		ll.addFirst("钱");
		System.out.println(ll);
		ll.addLast("孙");
		System.out.println(ll);
		
		
		
	}

}

Vector:安全的List,Vector中提供了一个独特的取出方式,就是枚举Enumeration。此接口Enumeration的功能与Iterator 接口的功能是重复的。
主要方法:
      -public E elementAt(int index)
      -public E firstElement()
      -public E lastElement()
      -public void setElementAt(E obj, int index)
      -public void removeElementAt(int index)及其他删除
      -public Enumeration<E> elements()
/*
 * Vector: 版本老的   速度慢的    安全的  ArrayList
 * 
 * public void addElement(E obj)   添加元素
 * public Enumeration elements()   返回该集合的枚举
 * Enumeration:枚举   即现阶段,只要认为是一个容器,用于存储元素。 相当于另外一种形式的iterator。
 * boolean hasMoreElements()  相当于hasNext
 * E nextElement()  相当于next方法
 * public E elementAt(int index)  根据索引获取元素对象
 */
public class Demo02_Vector {

	public static void main(String[] args) {

		Vector vector = new Vector();
		
		vector.add("刘胡兰");
		vector.add("董存瑞");
		vector.add("江姐");
		vector.add("黄继光");
		
		Enumeration elements = vector.elements();
		
		while (elements.hasMoreElements()) {
			String name = (String) elements.nextElement();
			System.out.println(name);
		}
		System.out.println("=============");
		for (int i=0; i<vector.size(); i++) {
			System.out.println(vector.elementAt(i));
		}
	}

}
(四)Set
Set:单列集合,无序,元素不得重复。与Collection方法一致。
Set方法取出元素只能使用迭代器。
Set主要子类
      •HashSet:线程不安全,存取速度快
           -底层结构为哈希表结构,即区分元素时使用hash值。可以通过hashCode与equals方法的重写,保证元素唯一性。
           -具体代码体现为:先判断哈希值是否相等,再判断equals方法是否返回true。true则为相同元素,存储元素失败,false则为不同元素,存储元素成功。
     •TreeSet:线程不安全,可以对集合中的元素进行排序。
           -通过Comparable让集合内元素具备比较性。
           -通过Comparator让集合具备比较某种类型元素的能力。
           -当Comparator与Comparable冲突时,以Comparator作为标准。
     •LinkedHashSet
           -在HashSet集合的基础上,使迭代顺序可预测
/*
 * Set:无序,元素不得重复
 * HashSet: 底层结构为哈希表结构的set集合
 */
public class Demo03_Set {

	public static void main(String[] args) {

		Set set = new HashSet();
		
		set.add("杨千嬅");
		set.add("张娜拉");
		set.add("容祖儿");
		set.add("范冰冰");
		set.add("李冰冰");
		set.add("李冰冰");
		
		Iterator iterator = set.iterator();
		
		while (iterator.hasNext()) {
			String name = (String) iterator.next();
			System.out.println(name);
		}
	}

}
/*
 * HashSet判断元素唯一性:
 * 		先判断hashCode值,判断新添加进来的元素的hashCode与老元素的hashCode是否相等
 * 			如果相等:继续使用新添加元素的equals方法与老元素进行比较
 * 				如果equals也相等,说明新元素与老元素相同,不加入集合
 * 				如果equals不相等,说明新元素与老元素不相同,加入集合
 * 			如果不等:直接判断,两元素不同,接入集合
 */
public class Demo04_HashSet {

	public static void main(String[] args) {
		
		Set set = new HashSet();
		
		Cat cat = new Cat("大黄",6);
		Cat cat2 = new Cat("旺财",5);
		Cat cat3 = new Cat("点点",12);
		Cat cat4 = new Cat("登登",5);
		
		set.add(cat);
		set.add(cat2);
		set.add(cat3);
		set.add(cat4);
		set.add(new Cat("登登",5));
		
		System.out.println(set);
		
		Iterator iterator = set.iterator();
		
		while (iterator.hasNext()) {
			Cat c = (Cat) iterator.next();
			System.out.println(c);
		}
	}
}

/*
 * LinkedHashSet:具有可预知迭代顺序的Set
 */
public class Demo05_LinkedHashSet {

	public static void main(String[] args) {
		
		LinkedHashSet lhs = new LinkedHashSet();
		
		lhs.add("刘亦菲");
		lhs.add("宋承宪");
		lhs.add("高圆圆");
		lhs.add("黄海波");
		lhs.add("黄海波");
		
		Iterator iterator = lhs.iterator();
		
		while (iterator.hasNext()) {
			String name = (String) iterator.next();
			System.out.println(name);
		}
	}
}

/*
 * 使用TreeSet存储自定义数据类型 
 * 
 * Comparable:此接口强行对实现它的每个类的对象进行整体排序。该类有方法可以定义比较规则
 * 		int compareTo(T o)  定义比较顺序
 * 
 * 使用TreeSet存储自定义数据类型的方式一:
 * 		1:定义元素类,实现Comparable,为了让元素具备比较性
 *  	2:重写compareTo方法,定义比较规则,本例中的需求规则是先比较年龄,再比较姓名
 *  	3:按照正常的集合使用方法,存储自定义数据类型对象
 *  
 * TreeSet判断元素唯一性的方法,就是元素大小顺序的比较方法。
 */
public class Demo06_TreeSet {

	public static void main(String[] args) {
		
		TreeSet ts = new TreeSet();
		
		Person p = new Person("b张飞",18);
		Person p2 = new Person("李逵",19);
		Person p3 = new Person("包公",20);
		Person p4 = new Person("a张骞",18);
		Person p5 = new Person("a张骞",18);
		
		ts.add(p);
		ts.add(p2);
		ts.add(p3);
		ts.add(p4);
		ts.add(p5);
		
		System.out.println(ts);
		
	}

}
public class Person implements Comparable{

	private String name;
	private int age;

	public Person() {
	}

	public Person(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 String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

	/*
	 * 先比较年龄
	 * 如果年龄相同,再比较姓名
	 */
	@Override
	public int compareTo(Object o) {
		
		Person p = (Person)o;
		
		//this: 新添加的元素
		//p: 集合中已经存在的老元素
		
		int result = 0;
		//比较年龄
		result = this.age - p.age;
		//如果年龄相同,再比较姓名
		if(result==0) {
			result = this.name.compareTo(p.name);
		}
		
		return result;
	}
}


 
  
/*
 * 使用TreeSet存储自定义数据类型 
 * 
 * TreeSet构造:
 * 		public TreeSet(Comparator comparator)  带比较器的构造方法
 * 
 * Comparator: 比较器
 * 		强行对某个对象 collection 进行整体排序 的比较函数
 * 
 * 使用TreeSet存储自定义数据类型的方式二:
 * 		1:定义比较器类,实现Comparator,为了让集合具备比较某种元素的能力
 *  	2:重写compare方法,定义比较规则,本例中的需求规则是先比较姓名,再比较年龄
 *  	3:创建比较器对象
 *  	4:使用比较器对象创建集合
 *  	3:按照正常的集合使用方法,存储自定义数据类型对象
 *  
 * TreeSet判断元素唯一性的方法,就是元素大小顺序的比较方法。
 */
public class Demo07_TreeSet {

	public static void main(String[] args) {
		//使用匿名内部类方式调用TreeSet带比较器对象的构造方法
		TreeSet ts = new TreeSet(new Comparator(){

			//自定义比较规则:先比较姓名,再比较年龄
			@Override
			public int compare(Object o1, Object o2) {
				
				Student s = (Student)o1;
				Student s2 = (Student)o2;
				
				//s:新添加的元素
				//s2: 集合中已经存在的老元素
				
				int result = 0;
				//比较姓名
				result = s.getName().compareTo(s2.getName());
				//如果姓名相同,再比较年龄
				if(result==0) {
					result = s.getAge() - s2.getAge();
				}
				
				return result;
			}}
		);
		
		Student p = new Student("b张飞",18);
		Student p2 = new Student("d李逵",19);
		Student p3 = new Student("c包公",20);
		Student p4 = new Student("a张骞",18);
		Student p5 = new Student("a张骞",131);
		
		ts.add(p);
		ts.add(p2);
		ts.add(p3);
		ts.add(p4);
		ts.add(p5);
		
		System.out.println(ts);
	}

}
(五)泛型
泛型:用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数传递。
泛型的优点:
      •提高程序的安全性
      •将运行期问题转移到了编译期
      •省去了类型强转的麻烦
      •优化了程序设计
泛型的使用
      •直接在指定泛型的地方给出明确的数据类型即可
      •在使用泛型后的集合中,迭代器返回时,可以直接返回该种数据类型对象。
      •替代了Object类的“任意化”性,避免了程序员必须预知使用时数据类型的情况。
      •<>里边什么都不写,叫菱形泛型,即前边是什么类型,后边也是什么类型。
泛型的定义
      •泛型类:在类上定义泛型,类中使用该类型
          -格式:class 类名<T>{使用T}
      •泛型方法: 
          -格式:public<T> void method(){使用T}
      •泛型接口:在接口上使用泛型。
          -格式:interface 接口名<T>{}
          -在类实现接口时明确泛型类型
          -在类实现接口时仍不明确泛型类型,在创建对象时明确泛型类型
      •泛型通配符:<?>可匹配任意一种数据类型
      •<?>与<T>的差别
          -通配符修饰的泛型不能直接使用而<T>可以使用
          -通配符修饰相当于声明了一种变量,它可以作为参数在方法中传递,如collection的containsAll方法
          -使用<?>可以完成类型限定,可参见TreeSet

        ? extends E 限定类型上限

        ? super E  限定类型下限

(六)Collections
Collections 集合工具类
      •以上为两种工具类,分别对数组或集合进行了常规动作的操作。日常开发中,出现在该两类的功能应该直接调用,而不应手动自己开发。
      •重点关注数组与集合相互转换的方法。
      •重点关注带可变参数与泛型的的方法。
      •注意:当数组转成集合后,长度不可增加

/*
 * Collections:集合工具类
 * public static <T> boolean addAll(Collection<? super T> c, T... elements)  为某个集合一次添加多个元素
 * Person extends Animal
 * 
 * public static <T> int binarySearch(List<? extends Comparable<? super T>> list,T key)  二分法查找
 * public static <T> int binarySearch(List<? extends T> list,T key, Comparator<? super T> c)  二分法查找
 * 
 * public static void reverse(List<?> list) 翻转集合
 * public static void shuffle(List<?> list) 使用默认随机源对指定列表进行置换。所有置换发生的可能性都是大致相等的。
 * 即  随机打乱顺序
 */
public class Demo08_Collections {

	public static void main(String[] args) {
		
		Collection<String> c = new ArrayList<String>();
		Collections.addAll(c, "悟空","悟能","悟净","吴尊","吴奇隆");
		System.out.println(c);
		
		Collection<Animal> c2 = new ArrayList<Animal>();
		
		Person p = new Person("吴用",18);
		Person p2 = new Person("晁盖",48);
		Person p3 = new Person("宋江",38);
		Person p4 = new Person("武松",28);
		
		Collections.addAll(c2,p,p2,p3,p4);
		System.out.println(c2);
		
		Collections.reverse((List<Animal>)c2);
		System.out.println(c2);
		
		Collections.shuffle((List<Animal>)c2);
		System.out.println(c2);
	}

}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值