JavaSe基础XX17——常用对象API-集合框架_3

回顾:

集合类的由来:
对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定。
就使用集合容器进行存储。

集合特点:
1,用于存储对象的容器。
2,集合的长度是可变的。
3,集合中不可以存储基本数据类型值。 






集合容器因为内部的数据结构不同,有多种具体容器。
不断的向上抽取,就形成了集合框架。


框架的顶层Collection接口:


Collection的常见方法:


1,添加。
boolean add(Object obj):
boolean addAll(Collection coll):



2,删除。
boolean remove(object obj):
boolean removeAll(Collection coll);
void clear();

3,判断:
boolean contains(object obj):
boolean containsAll(Colllection coll);
boolean isEmpty():判断集合中是否有元素。 


4,获取:
int size():
Iterator iterator():取出元素的方式:迭代器。
该对象必须依赖于具体容器,因为每一个容器的数据结构都不同。
所以该迭代器对象是在容器中进行内部实现的。
对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的迭代器的对象即可,
也就是iterator方法。

Iterator接口就是对所有的Collection容器进行元素取出的公共接口。
其实就是抓娃娃游戏机中的夹子!


5,其他:
boolean retainAll(Collection coll);取交集。
Object[] toArray():将集合转成数组。 



-------------------------------
Collection
|--List:有序(存入和取出的顺序一致),元素都有索引(角标),元素可以重复。
|--Set:元素不能重复,无序。




List:特有的常见方法:有一个共性特点就是都可以操作角标。

1,添加
void add(index,element);
void add(index,collection);




2,删除;
Object remove(index):




3,修改:
Object set(index,element);



4,获取:
Object get(index);
int indexOf(object);
int lastIndexOf(object);
List subList(from,to);


list集合是可以完成对元素的增删改查。




List:
|--Vector:内部是数组数据结构,是同步的。增删,查询都很慢!
|--ArrayList:内部是数组数据结构,是不同步的。替代了Vector。查询的速度快。
|--LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。



LinkedList:


addFirst();
addLast():
jdk1.6
offerFirst();
offetLast();


getFirst();.//获取但不移除,如果链表为空,抛出NoSuchElementException.
getLast();
jdk1.6
peekFirst();//获取但不移除,如果链表为空,返回null.
peekLast():

removeFirst();//获取并移除,如果链表为空,抛出NoSuchElementException.
removeLast();
jdk1.6
pollFirst();//获取并移除,如果链表为空,返回null.
pollLast();



作业:
1,自己去查文档演示Vector中的elements()方法。


2,LinkedList中的,addFirst addLast getFirst,getLast  removeFirst removeLast。

3,既然集合是存储对象的,请定义ArryaList集合,并存储Person对象。如new Person("lisi",20);
并取出。将姓名和年龄打印出来。








---------------------------------------------


Set:元素不可以重复,是无序。
Set接口中的方法和Collection一致。
|--HashSet: 内部数据结构是哈希表 ,是不同步的。
如何保证该集合的元素唯一性呢?
是通过对象的hashCode和equals方法来完成对象唯一性的。
如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。 
如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。

记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。
一般情况下,如果定义的类会产生很多对象,比如人,学生,书,通常都需要覆盖equals,hashCode方法。
建立对象判断是否相同的依据。




|--TreeSet:可以对Set集合中的元素进行排序。是不同步的。 
判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,是0,就是相同元素,不存。 

TreeSet对元素进行排序的方式一:
让元素自身具备比较功能,元就需要实现Comparable接口。覆盖compareTo方法。

如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?
可以使用TreeSet集合第二种排序方式二:
让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。
将该类对象作为参数传递给TreeSet集合的构造函数。






if(this.hashCode()== obj.hashCode() && this.equals(obj))






哈希表确定元素是否相同
1,判断的是两个元素的哈希值是否相同。
如果相同,在判断两个对象的内容是否相同。


2,判断哈希值相同,其实判断的是对象的hashCode的方法。判断内容相同,用的是equals方法。


注意:如果哈希值不同,是不需要判断equals。


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------



*01-常用对象API(集合框架-泛型-概述)

JDK1.5出现的安全机制


package cn.itcast.p1.generic.demo;

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

public class GenericDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		
		int[] arr = new int[4];
//		arr[0] = 3.0;
		
		
		ArrayList<String> al = new ArrayList<String>();
		
		al.add("abc");//public boolean add(Object obj)
		al.add("hahah");
//		al.add(4);//al.add(new Integer(4));
		
		Iterator<String> it = al.iterator();
		while(it.hasNext()){
			
			String str = it.next();
			System.out.println(str);
		}
	}

}





泛型:
jdk1.5出现的安全机制。

好处:
1,将运行时期的问题ClassCastException转到了编译时期。
2,避免了强制转换的麻烦。


<>:什么时候用?当操作的引用数据类型不确定的时候。就使用<>。将要操作的引用数据类型传入即可.
   其实<>就是一个用于接收具体引用数据类型的参数范围。


在程序中,只要用到了带有<>的类或者接口,就要明确传入的具体引用数据类型 。


泛型技术是给编译器使用的技术,用于编译时期。确保了类型的安全。



*02-常用对象API(集合框架-泛型-擦除&补偿)

提高的安全性:编译的时候检查完了。

运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除。
为什么擦除呢?因为为了兼容运行的类加载器。

泛型的补偿:在运行时,通过获取元素的类型进行转换动作。不用使用者在强制转换了。


*03-常用对象API(集合框架-泛型-在集合中的应用)


使用容器的时候,就要先确定好这个容器装什么类型元素。——泛型



第一种解决方法:



CompareTo可以覆盖。

但equals不可以,因为equals是继承了父类Object,而Object没有泛型。



第二种方法:








泛型里面是不能写基本数据类型。数组可以。泛型里面放的是引用数据类型。

*04-常用对象API(集合框架-泛型-泛型类)

可不可以定义一个工具类Tool操作所有类。

第一,先抽取类的共性。


/*
public class Tool {

	private Object object;

	public Object getObject() {
		return object;
	}

	public void setObject(Object object) {
		this.object = object;
	}
	
}
*/









*05-常用对象API(集合框架-泛型-泛型方法)





	/**
	 * 将泛型定义在方法上。
	 * @param str
	 */
	public <W> void show(W str){
		System.out.println("show : "+str.toString());
	}
	public void print(QQ str){
		System.out.println("print : "+str);
	}
	






*06-常用对象API(集合框架-泛型-泛型接口)


//泛型接口,将泛型定义在接口上。 
interface Inter<T>{
public void show(T t);
}


class InterImpl implements Inter<String>{
public void show(String str){
System.out.println("show :"+str);
}
}


package cn.itcast.p4.generic.define.demo;

public class GenericDefineDemo5 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		InterImpl in = new InterImpl();
		in.show("abc");
		
		InterImpl2<Integer> in2 = new InterImpl2<Integer>();
		in2.show(5);
	}
}

//泛型接口,将泛型定义在接口上。 
interface Inter<T>{
	public void show(T t);
}


class InterImpl2<Q> implements Inter<Q>{
	public void show(Q q){
		System.out.println("show :"+q);
	}
}




class InterImpl implements Inter<String>{
	public void show(String str){
		System.out.println("show :"+str);
	}
}

*07-常用对象API(集合框架-泛型-泛型限定(上限))


当一旦类型不一样的时候,可以使用通配符、

泛型的通配符:? 未知类型。 


package cn.itcast.p5.generic.advance.demo;

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

public class GenericAdvanceDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		ArrayList<String> al = new ArrayList<String>();
		
		al.add("abc");
		al.add("hehe");
		
		ArrayList<Integer> al2 = new ArrayList<Integer>();
		
		al2.add(5);
		al2.add(67);
		
		printCollection(al);
		printCollection(al2);
	}

	/**
	 * 迭代并打印集合中元素。
	 * @param al
	 */
	public static void printCollection(Collection<?> al) {	
	
		Iterator<?> it = al.iterator();
		
		while(it.hasNext()){
//			T str = it.next();
//			System.out.println(str);
			System.out.println(it.next().toString());
		}
		
	}

}





对容器的要求:只打印Person的子类








这叫做泛型的限定

第一种限定体现,? extends Person  上限

public class GenericAdvanceDemo2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		ArrayList<Person> al = new ArrayList<Person>();
		
		al.add(new Person("abc",30));
		al.add(new Person("abc4",34));
		
		ArrayList<Student> al2 = new ArrayList<Student>();
		
		al2.add(new Student("stu1",11));
		al2.add(new Student("stu2",22));
		ArrayList<String> al3 = new ArrayList<String>();
		
		al3.add("stu3331");
		al3.add("stu33332");
		
		printCollection(al2);
		printCollection(al);
	}

	/**
	 * 迭代并打印集合中元素。
	 * 
	 * 可以对类型进行限定:
	 * ? extends E:接收E类型或者E的子类型对象。上限!
	 * 
	 * ? super E :接收E类型或者E的父类型。下限!
	 * @param al
	 */
	/*public static void printCollection(Collection<? extends Person> al) {//Collection<Dog> al = new ArrayList<Dog>()
		Iterator<? extends Person> it = al.iterator();
		
		while(it.hasNext()){
//			T str = it.next();
//			System.out.println(str);
//			System.out.println(it.next().toString());
			Person p = it.next();
			
			System.out.println(p.getName()+":"+p.getAge());
		}
		
	}*/

*08-常用对象API(集合框架-泛型-泛型限定(下限))


* ? super E :接收E类型或者E的父类型。下限!
什么时候会用呢?


(Collection<? super Student> al):这种情况只能 接受Student和Person。


package cn.itcast.p5.generic.advance.demo;

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

import cn.itcast.p2.bean.Person;
import cn.itcast.p2.bean.Student;
import cn.itcast.p2.bean.Worker;

public class GenericAdvanceDemo2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		ArrayList<Person> al = new ArrayList<Person>();
		
		al.add(new Person("abc",30));
		al.add(new Person("abc4",34));
		
		ArrayList<Student> al2 = new ArrayList<Student>();
		
		al2.add(new Student("stu1",11));
		al2.add(new Student("stu2",22));
		ArrayList<String> al3 = new ArrayList<String>();
		
		al3.add("stu3331");
		al3.add("stu33332");
		
		printCollection(al2);
		printCollection(al);
	}

	/**
	 * 迭代并打印集合中元素。
	 * 
	 * 可以对类型进行限定:
	 * ? extends E:接收E类型或者E的子类型对象。上限!
	 * 
	 * ? super E :接收E类型或者E的父类型。下限!
	 * @param al
	 */
	/*public static void printCollection(Collection<? extends Person> al) {//Collection<Dog> al = new ArrayList<Dog>()
		Iterator<? extends Person> it = al.iterator();
		
		while(it.hasNext()){
//			T str = it.next();
//			System.out.println(str);
//			System.out.println(it.next().toString());
			Person p = it.next();
			
			System.out.println(p.getName()+":"+p.getAge());
		}
		
	}*/
	
	public static void printCollection(Collection<? super Student> al){
		Iterator<? super Student> it = al.iterator();
		
		while(it.hasNext()){
			
			System.out.println(it.next());
		}
	}

}

*09-常用对象API(集合框架-泛型-泛型限定(上限的体现))

为什么会要用到泛型的上限。


一般定义存的时候,用上限。

package cn.itcast.p5.generic.advance.demo;

import java.util.ArrayList;

import cn.itcast.p2.bean.Person;
import cn.itcast.p2.bean.Student;
import cn.itcast.p2.bean.Worker;

public class GenericAdvanceDemo3 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		ArrayList<Person> al1 = new ArrayList<Person>();
		
		al1.add(new Person("abc",30));
		al1.add(new Person("abc4",34));
		
		ArrayList<Student> al2 = new ArrayList<Student>();
		
		al2.add(new Student("stu1",11));
		al2.add(new Student("stu2",22));
		
		
		ArrayList<Worker> al3 = new ArrayList<Worker>();
		
		al3.add(new Worker("stu1",11));
		al3.add(new Worker("stu2",22));
		
		ArrayList<String> al4 = new ArrayList<String>();
		al4.add("abcdeef");
//		al1.addAll(al4);//错误,类型不匹配。
		
		al1.addAll(al2);
		al1.addAll(al3);
		
		System.out.println(al1.size());
		
		
//		printCollection(al2);
//		printCollection(al);
	}
	
	

}

/*
 * 一般在存储元素的时候都是用上限,因为这样取出都是按照上限类型来运算的。不会出现类型安全隐患。 
 * 
 */

class MyCollection<E>{
	public void add(E e){
	
	}
	public void addAll(MyCollection<? extends E> e){
		
	}
}

*10-常用对象API(集合框架-泛型-泛型限定(下限的体现))



什么时候用下限呢?

通常在取出集合的元素的时候,可以用下限,

package cn.itcast.p5.generic.advance.demo;

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

import cn.itcast.p2.bean.Person;
import cn.itcast.p2.bean.Student;
import cn.itcast.p2.bean.Worker;

public class GenericAdvanceDemo4 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		TreeSet<Person> al1 = new TreeSet<Person>(new CompByName());
		
		al1.add(new Person("abc4",34));
		al1.add(new Person("abc1",30));
		al1.add(new Person("abc2",38));
		
		TreeSet<Student> al2 = new TreeSet<Student>(new CompByName());
		
		al2.add(new Student("stu1",11));
		al2.add(new Student("stu7",20));
		al2.add(new Student("stu2",22));
		
		
		TreeSet<Worker> al3 = new TreeSet<Worker>();
		
		al3.add(new Worker("stu1",11));
		al3.add(new Worker("stu2",22));
		
		TreeSet<String> al4 = new TreeSet<String>();
		al4.add("abcdeef");
//		al1.addAll(al4);//错误,类型不匹配。
		
//		al1.addAll(al2);
//		al1.addAll(al3);
		
//		System.out.println(al1.size());
		
		
		
		Iterator<Student> it = al2.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
		
	}
}


/*
 * class TreeSet<Worker>
 * {
 * 		Tree(Comparator<? super Worker> comp);
 * }
 * 
 * 什么时候用下限呢?通常对集合中的元素进行取出操作时,可以是用下限。
 * 
 */

class CompByName implements Comparator<Person>{

	@Override
	public int compare(Person o1, Person o2) {
		
		int temp = o1.getName().compareTo(o2.getName());
		
		return temp==0? o1.getAge()-o2.getAge():temp;
	}
	
}

class CompByStuName implements Comparator<Student>{

	@Override
	public int compare(Student o1, Student o2) {
		
		int temp = o1.getName().compareTo(o2.getName());
		
		return temp==0? o1.getAge()-o2.getAge():temp;
	}
	
}

class CompByWorkerName implements Comparator<Worker>{

	@Override
	public int compare(Worker o1, Worker o2) {
		
		int temp = o1.getName().compareTo(o2.getName());
		
		return temp==0? o1.getAge()-o2.getAge():temp;
	}
	
}






*11-常用对象API(集合框架-泛型-泛型限定(通配符的体现))


package cn.itcast.p5.generic.advance.demo;

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

import cn.itcast.p2.bean.Person;
import cn.itcast.p2.bean.Student;
import cn.itcast.p2.bean.Worker;

public class GenericAdvanceDemo5 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		ArrayList<Person> al1 = new ArrayList<Person>();
		
		al1.add(new Person("abc",30));
		al1.add(new Person("abc4",34));
		ArrayList<Person> al2 = new ArrayList<Person>();
		
		al2.add(new Person("abc22222",30));
		al2.add(new Person("abc42222222",34));
		
		
		ArrayList<String> al4 = new ArrayList<String>();
		al4.add("abcdeef");
		al4.add("abc");
		
		al1.containsAll(al4);
		
		
//		"abc".equals(new Person("ahahah",20));
		
		
		
		
	}
	public static void printCollection(Collection<?> al){
		Iterator<?> it = al.iterator();
		
		while(it.hasNext()){
			
			System.out.println(it.next().toString());
		}
	}
}

class MyCollection2<E>{
	public boolean containsAll(Collection<?> coll){
		
		
		return true;
	}
}


===========================================================


集合的一些技巧:


需要唯一吗?
需要:Set
需要制定顺序: 
需要: TreeSet
不需要:HashSet
但是想要一个和存储一致的顺序(有序):LinkedHashSet
不需要:List
需要频繁增删吗?
需要:LinkedList
不需要:ArrayList

如何记录每一个容器的结构和所属体系呢?


看名字!




List
|--ArrayList
|--LinkedList


Set
|--HashSet
|--TreeSet


后缀名就是该集合所属的体系。


前缀名就是该集合的数据结构。


看到array:就要想到数组,就要想到查询快,有角标.
看到link:就要想到链表,就要想到增删快,就要想要 add get remove+frist last的方法 
看到hash:就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖hashcode方法和equals方法。 
看到tree:就要想到二叉树,就要想要排序,就要想到两个接口Comparable,Comparator 。


而且通常这些常用的集合容器都是不同步的。 








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值