黑马程序员——集合框架(一) —— Collection

本文详细介绍了Java集合框架中的Collection接口及其常用的子接口List和Set。重点讲解了ArrayList、Vector、LinkedList、HashSet、LinkedHashSet和TreeSet的特性,并阐述了Collection接口的基本方法,如add、remove、clear等。此外,文章还探讨了List接口特有的方法和遍历方式,以及泛型的概念和使用,包括泛型类、泛型方法、泛型接口以及泛型通配符。最后,通过示例展示了如何在HashSet中处理自定义对象的唯一性,强调了重写hashCode()和equals()的重要性。
摘要由CSDN通过智能技术生成

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

 

 

Collection总体概述与常用方法

 

一、Collection(接口):
     1. List(接口):1.有序的;2.可以存储重复值;
          ArrayList(类):数组实现;不同步的,效率高;
          Vector(类):数组实现;同步的,效率低;
          LinkedList(类):链表实现;不同步的,效率高;
     2. Set(接口):1.无序的;2.不能存储重复值;(全是不同步的)
          HashSet(类):哈希表实现;验证重复:hashCode()和equals()
          LinkedHashSet(类):链表,哈希表实现;链表:有序;哈希表:唯一
          TreeSet(类):树结构;唯一性验证:比较的方法compareTo()或者compare()方法如果返回0,就不存;
               对元素排序的:
                    1.自然排序:
                        1).存储的对象必须实现Comparable接口
                        2).重写compareTo()方法;
                    2.比较器排序:
                        1).自定义比较器,实现Comparator接口
                        2).重写compare()方法;
                        3).实例化TreeSet对象时,传递自定义比较器的对象;(一般我们使用匿名内部类的式) 

 

二、Collection接口的常用方法:
    1.基本方法:
         boolean add(Object e):将参数e添加到集合
         boolean remove(Object o):将参数o从集合中移除
         void clear():清空集合
         boolean contains(Object o):基于equals()进行判断;
         boolean isEmpty():判断集合是否为空
         int size():集合中元素的数量;
    2.批量方法:
         boolean addAll(Collection c):将参数集合,一次性全部添加到当前集合
         boolean removeAll(Collection c):移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作
         boolean containsAll(Collection c):如果此 collection 包含指定 collection 中的所有元素,则返回 true
         boolean retainAll(Collection c):移除此 collection 中未包含在指定 collection 中的所有元素。
    3.遍历的方式:
         A.toArray();
         B.Iterator() 

三、针对上述的常用方法,给出部分代码演示:

  1.基本方法的用法:

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;

public class Demo {
	public static void main(String[] args) {
		//1.定义集合对象
		Collection col = new ArrayList();//多态:可存储重复元素
		Collection col2 = new HashSet();//不能存储重复元素;
		
		//2.向仓库中添加元素
		System.out.println(col.add("孙悟空"));
		System.out.println(col.add("猪八戒"));
		System.out.println(col.add("沙师弟"));
		System.out.println(col.add("唐僧"));
		System.out.println(col.add("唐僧"));
		
		System.out.println("---------------------------");
		System.out.println(col2.add("孙悟空"));
		System.out.println(col2.add("猪八戒"));
		System.out.println(col2.add("孙悟空"));
		
		System.out.println("集合元素:" + col);
		//3.移除元素
		System.out.println("删除元素:唐僧: " + col.remove("唐僧"));
		System.out.println("删除元素:白骨精:" + col.remove("白骨精"));
		System.out.println("集合元素:" + col);
		
		//4.void clear()
	//	col.clear();
	//	System.out.println("清空集合后:" + col);
		
		//5.boolean contains(Object o)
		System.out.println("是否包含:白骨精:" + col.contains("白骨精"));
		System.out.println("是否包含:孙悟空:" + col.contains("孙悟空"));
		
		//6.boolean isEmpty()
	//	col.clear();
		System.out.println("集合是否为空:" + col.isEmpty());
		
		//7.int size():
		System.out.println("集合中元素的数量:" + col.size());
		
	}
}

 

2.关于遍历的方式:

 

 

package cn.itcast_collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Iterator_迭代器 {
	public static void main(String[] args) {
		//创建集合对象
		Collection<Student> col = new ArrayList<Student>();
		//将学生对象添加到集合中
		col.add(new Student("北城以北",25,99));
		col.add(new Student("帆@彼岸",26,99));
		/*//使用迭代器(接口)遍历集合,集合对象调用iterator()方法,返回值类型为Iterator接口类型
		Iterator<Student> it = col.iterator();//迭代器的类型随着集合的明确而明确泛型,这样下面Student接收值的时候就不需要强转
		//使用hasNext()加while循环判断是否还有下一个元素,如果有点话,使用next()
		while(it.hasNext()){
			Student stu =  it.next();
			System.out.println("姓名:"+stu.getName()+", 年龄:"+stu.getAge()+", 战斗力:"+stu.getScore());
		}*/
		
		//使用for循环精简代码
		for(Iterator<Student> it = col.iterator();it.hasNext();){//代码初始化;判断是否有下一个;(循环操作可以省略)
			Student stu =  it.next();
			System.out.println("姓名:"+stu.getName()+", 年龄:"+stu.getAge()+", 战斗力:"+stu.getScore());
		}
	}
	
}

 

关于ArrarList的应用

 

    集合中,ArrayList是最常用的一种集合,因此这是我们必须要掌握的知识!但是,ArrayList没有特有方法,都是使用的父接口中定义的。即:Collection和List中的方法。

    Collection在上面已经讲过,这里讲一下List的特有方法。

    List接口的常用方法:
        1).新增的方法:
           void add(int index,E element)
           E remove(int index)
           E get(int index)
           E set(int index,E element)
           ListIterator listIterator()
        2).遍历的方式:
           A.结合Collection的size()和List的get()方法,使用for()循环;
           B.ListIterator:可以向前遍历,也可以向后遍历;
    Iterator 和 ListIterator的区别:
        1.ListIterator是Iterator的子接口;
        2.Iterator只能向下遍历;
        3.ListIterator可以双向遍历;

    对于这些基本方法,这里就不做演示了,大家可以参考Collection中关于基本方法的演示自己试着做一下。下面给出一个例子。这个例子是关于怎样去除ArrayList中重复的元素:

    这里给出了两种方法,大家参考一下:


import java.util.ArrayList;
import java.util.List;

/*
 * 
 * 方式一:定义一个新集合;
 * 方式二:遍历当前集合,在当前集合的基础上进行修改;
 */
public class Demo {
	public static void main(String[] args) {
		List list = new ArrayList();
		list.add(new Student("李四",22));
		list.add(new Student("李四",22));
		list.add(new Student("李四",22));
		list.add(new Student("张三",20));
		list.add(new Student("李四",22));
		list.add(new Student("李四",22));
		list.add(new Student("王五",24));
		list.add(new Student("王五",24));
		list.add(new Student("王五",24));
		list.add(new Student("王五",24));
		list.add(new Student("王五",24));
		/*
		//方式一:
		List newList = new ArrayList();
		
		//遍历
		loop:
		for(int i = 0;i < list.size() ;i++){
			Student stu = (Student)list.get(i);
			for(int j = 0;j < newList.size() ; j++){
				Student stu2 = (Student)newList.get(j);
				if(stu.equals(stu2)){
					continue loop;
				}
			}
			//将stu添加到newList中
			newList.add(stu);
		}
		
		//遍历newList
		for(int i = 0 ;i < newList.size() ; i++){
			Student stu = (Student)newList.get(i);
			System.out.println(stu.name + "," + stu.age);
		}*/
		
		//方式二:
		for(int i = 0; i < list.size() - 1 ; i++){
			Student stu1 = (Student)list.get(i);
			for(int j = i + 1 ; j < list.size() ; j++){
				Student stu2 = (Student)list.get(j);
				if(stu1.equals(stu2)){
					list.remove(j);
					j--;
				}
			}
		}
		//遍历原集合
		for(int i = 0; i < list.size() ; i++){
			Student stu = (Student)list.get(i);
			System.out.println(stu.name + "," + stu.age);
		}
		
	}
}

 

 

泛型


 1.在定义集合时,可以指定这个集合内只能装什么类型元素,这种方式就是“泛型”
     ArrayList<String> strList = new ArrayList<String>();
     或:
     ArrayList<String> strList = new ArrayList<>();
     或:
    ArrayList<String> strList = new ArrayList();
 2.泛型类:class MyArrayList<T>{}
         1.T:可以是任何字母;大小写都可以;
         2.也可以定义多个泛型,中间用逗号隔开;<T,V>
 3.泛型方法:
     class MyArrayList{
     //接收的是什么类型,返回的就是具有这个类型
      public <T> T show(T t){
      return t;
     }
   }
 4.泛型接口:
    interface IA<T>{
     T show(T t);
   }
   子类实现时:
       1.可以继续定义泛型:
        class A <T> implements IA<T>{
          public T show(T t){
         }
        }
       2.可以固定为某个具体类型
        class A  implements IA<String>{
          public String show(String s){
          }
       }
       3.可以将泛型丢弃
         class A implements IA{
         public Object show(Object o){
         }
       }
 5.泛型的通配符:
  1:<?>:
  2:<? extends E>:
  3:<? super E>:

 

这里关于泛型通配符不是很好理解,给出一个Demo帮助大家快速掌握:

 

package cn.itcast.demo11_泛型通配符;

import java.util.ArrayList;
import java.util.List;

/*
 * 泛型通配符:
 * 1.<?> : 
 * 		1).变量可以指向什么类型的对象:具有任何泛型的集合对象;
 * 		2).可以存储什么东西:由于?不确定具体类型,所以不能add()任何类型
 * 		3).取出时用什么接收:只能用Object接收;
 * 	 作用:不能存入,只能获取,所以一般用作方法的返回值声明;
 * 2.<? extends E> :
 * 		1).变量可以指向什么类型的对象:具有E泛型或者E子类泛型的集合;
 * 		2).可以存储什么东西:由于不确定是哪个E的子类,所以不能存任何东西;
 * 		3).取出时用什么接收:只能用E及E的父类类型接收;
 * 3.<? super E> : 
 * 		1).变量可以指向什么类型的对象:具有E泛型或者E父类泛型的集合;
 * 		2).可以存储什么东西:只能存储E或者E的子类对象;
 * 		3).取出时用什么接收:由于存储的可能是任何的E的子类对象,所以只能用Object接收;
 */
class Animal{}
class Cat extends Animal{};
class Dog extends Animal{};
class JMDog extends Dog{};
public class Demo {
	public static void main(String[] args) {
		//1.<?>
		List<?> list1 = new ArrayList<>();
		List<?> list2 = new ArrayList<String>();
		List<?> list3 = new ArrayList<Animal>();
//		
//		list2.add("aa");
//		list2.add(10);
//		list2.add(new Animal());
		
		Object obj = list2.get(0);
		
		//2.<? extends E>
	//	List<? extends Dog> list4 = new ArrayList<Animal>();//编译错误
		List<? extends Dog> list5 = new ArrayList<Dog>();
		List<? extends Dog> list6 = new ArrayList<JMDog>();
		/*
		list5.add("你好");
		list5.add(10);
		list5.add(new Animal());
		list5.add(new Dog());
		list5.add(new JMDog());
		*/
		Dog d1 = list5.get(0);
		Animal a1 = list5.get(0);
		
		//3.<? super E>
		List<? super Dog> list7 = new ArrayList<Animal>();
		List<? super Dog> list8 = new ArrayList<Dog>();
	//	List<? super Dog> list9 = new ArrayList<JMDog>();
		
	//	list7.add(new Animal());
		list7.add(new Dog());
	//	list7.add(new Cat());
		list7.add(new JMDog());
		
		Object d = list7.get(0);
		
		
	}
}

 

 

Set集合

 

 

Set集合:这里不是特别好理解,对于初学者,能掌握则好,掌握不了能看懂就可以。
    1.Set集合的特点:
       1).无序(取出时,跟存入时的顺序不一致)
       2).不存储重复元素。
    2.子类:
       1).HashSet:
          A.内部使用"哈希表"结构;
          B.使用hashCode()和equals()保证元素的唯一;
       2).TreeSet:
          A.内部使用"树"结构;
          B.比较方式:
             1.自然排序:
                自定义类实现Comparable接口。重写compareTo()
             2.比较器排序:
                自定义"比较器"实现Comparator接口,重写compare()方法;
                实例化TreeSet时,将"比较器"对象传入;
          C.无论哪种比较方式,只要返回0,就认为是相等的对象,不存。
  
       3).LinkedHashSet:有序的;
          A.内部使用链表、哈希表实现;
          B.由链表保证有序;由哈希表保证唯一

 

这里给出HashSet存储自定义对象时候需要重写hashCode()和equals()做一个示例:两个类Student类和Demo类

import java.util.HashSet;
import java.util.Set;
/*
 * 使用HashSet存储自定义对象
 * 
 * 1.需要判断出两个对象中的属性值是否完全一样,需要重写hashCode()和equals();
 * 2.怎么重写?
 * 		鼠标-->右键-->source-->Generate hashCode() and equals()
 */
public class Demo {
	public static void main(String[] args) {
		//创建集合对象,并添加元素
		Set<Student> stuSet = new HashSet<>();
		stuSet.add(new Student("张三",20));
		stuSet.add(new Student("李四",22));
		stuSet.add(new Student("王五",24));
		stuSet.add(new Student("王五",24));
		
		//遍历集合并输出
		for(Student stu : stuSet){
			System.out.println(stu.name + "---" + stu.age);
		}
		
		
		
	}
}

 

 这里Student类中重写了equals()和HashCode()方法:

public class Student {
	String name;
	int age;
	public Student(String name, int age) {
		super();
		this.name = name;
		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;
	}
	
}


 


public class Student {
	String name;
	int age;
	public Student(String name, int age) {
		super();
		this.name = name;
		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;
	}
	
}


public class Student {
 String name;
 int age;
 public Student(String name, int age) {
  super();
  this.name = name;
  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;
 }
 
}

 


一.Set集合:
 1.Set集合的特点:
  1).无序(取出时,跟存入时的顺序不一致)
  2).不存储重复元素。
 2.子类:
  1).HashSet:
   A.内部使用"哈希表"结构;
   B.使用hashCode()和equals()保证元素的唯一;
  2).TreeSet:
   A.内部使用"树"结构;
   B.比较方式:
    1.自然排序:
     自定义类实现Comparable接口。重写compareTo()
    2.比较器排序:
     自定义"比较器"实现Comparator接口,重写compare()方法;
     实例化TreeSet时,将"比较器"对象传入;
   C.无论哪种比较方式,只要返回0,就认为是相等的对象,不存。
  
  3).LinkedHashSet:有序的;
   A.内部使用链表、哈希表实现;
   B.由链表保证有序;由哈希表保证唯一


二:泛型:
 1.在定义集合时,可以指定这个集合内只能装什么类型元素,这种方式就是“泛型”
  ArrayList<String> strList = new ArrayList<String>();
  或:
  ArrayList<String> strList = new ArrayList<>();
  或:
  ArrayList<String> strList = new ArrayList();
 2.泛型类:class MyArrayList<T>{}
                 1.T:可以是任何字母;大小写都可以;
                 2.也可以定义多个泛型,中间用逗号隔开;<T,V>
 3.泛型方法:
  class MyArrayList{
   //接收的是什么类型,返回的就是具有这个类型
   public <T> T show(T t){
    return t;
   }
  }
 4.泛型接口:
  interface IA<T>{
   T show(T t);
  }
   子类实现时:
  1.可以继续定义泛型:
   class A <T> implements IA<T>{
    public T show(T t){
    }
   }
  2.可以固定为某个具体类型
   class A  implements IA<String>{
    public String show(String s){
    }
   }
  3.可以将泛型丢弃
   class A implements IA{
    public Object show(Object o){
    }
   }
 5.泛型的通配符:见Demo
  1:<?>:
  2:<? extends E>:
  3:<? super E>:二:泛型:
 1.在定义集合时,可以指定这个集合内只能装什么类型元素,这种方式就是“泛型”
  ArrayList<String> strList = new ArrayList<String>();
  或:
  ArrayList<String> strList = new ArrayList<>();
  或:
  ArrayList<String> strList = new ArrayList();
 2.泛型类:class MyArrayList<T>{}
                 1.T:可以是任何字母;大小写都可以;
                 2.也可以定义多个泛型,中间用逗号隔开;<T,V>
 3.泛型方法:
  class MyArrayList{
   //接收的是什么类型,返回的就是具有这个类型
   public <T> T show(T t){
    return t;
   }
  }
 4.泛型接口:
  interface IA<T>{
   T show(T t);
  }
   子类实现时:
  1.可以继续定义泛型:
   class A <T> implements IA<T>{
    public T show(T t){
    }
   }
  2.可以固定为某个具体类型
   class A  implements IA<String>{
    public String show(String s){
    }
   }
  3.可以将泛型丢弃
   class A implements IA{
    public Object show(Object o){
    }
   }
 5.泛型的通配符:见Demo
  1:<?>:
  2:<? extends E>:
  3:<? super E>:二:泛型:
 1.在定义集合时,可以指定这个集合内只能装什么类型元素,这种方式就是“泛型”
  ArrayList<String> strList = new ArrayList<String>();
  或:
  ArrayList<String> strList = new ArrayList<>();
  或:
  ArrayList<String> strList = new ArrayList();
 2.泛型类:class MyArrayList<T>{}
                 1.T:可以是任何字母;大小写都可以;
                 2.也可以定义多个泛型,中间用逗号隔开;<T,V>
 3.泛型方法:
  class MyArrayList{
   //接收的是什么类型,返回的就是具有这个类型
   public <T> T show(T t){
    return t;
   }
  }
 4.泛型接口:
  interface IA<T>{
   T show(T t);
  }
   子类实现时:
  1.可以继续定义泛型:
   class A <T> implements IA<T>{
    public T show(T t){
    }
   }
  2.可以固定为某个具体类型
   class A  implements IA<String>{
    public String show(String s){
    }
   }
  3.可以将泛型丢弃
   class A implements IA{
    public Object show(Object o){
    }
   }
 5.泛型的通配符:见Demo
  1:<?>:
  2:<? extends E>:
  3:<? super E>:




package cn.itcast_collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Iterator_迭代器 {
	public static void main(String[] args) {
		//创建集合对象
		Collection<Student> col = new ArrayList<Student>();
		//将学生对象添加到集合中
		col.add(new Student("北城以北",25,99));
		col.add(new Student("帆@彼岸",26,99));
		/*//使用迭代器(接口)遍历集合,集合对象调用iterator()方法,返回值类型为Iterator接口类型
		Iterator<Student> it = col.iterator();//迭代器的类型随着集合的明确而明确泛型,这样下面Student接收值的时候就不需要强转
		//使用hasNext()加while循环判断是否还有下一个元素,如果有点话,使用next()
		while(it.hasNext()){
			Student stu =  it.next();
			System.out.println("姓名:"+stu.getName()+", 年龄:"+stu.getAge()+", 战斗力:"+stu.getScore());
		}*/
		
		//使用for循环精简代码
		for(Iterator<Student> it = col.iterator();it.hasNext();){//代码初始化;判断是否有下一个;(循环操作可以省略)
			Student stu =  it.next();
			System.out.println("姓名:"+stu.getName()+", 年龄:"+stu.getAge()+", 战斗力:"+stu.getScore());
		}
	}
	
}


 

 

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值