天天看点

黑马程序员——Java基础——集合(三)

------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

Collection接口:

package cu.fu._06collection;
/**
 * 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(Collection coll);
 * boolean isEmpty();判断集合中是否有元素.
 * 
 * 4.获取:
 * int size();
 * Iterator iterator();
 * 取出元素的方式:迭代器.
 * 该对象必须依赖于具体容器,因为每一个容器的数据结构不同,所以该迭代器对象是在容器中进行内部实行的,
 * 也就是iterator方法在每个容器中的实现方式是不同的.
 * 对于使用者而言,具体的实现不重要,只要通过荣区获取到该实现的迭代器的对象即可,也就是iterator方法.
 * Iterator接口就是对所有Collection容器进行元素取出的公共接口.
 * 
 * 5.其他:
 * boolean retainAll(Collection coll);取交集
 * Object toArray();将集合转成数组
 */
import java.util.*;
public class CollectionDemo1 {
	public static void main(String[] args) {
		Collection coll = new ArrayList();
		show(coll);
		
		System.out.println("========================");
		
		Collection c1 = new ArrayList();
		Collection c2 = new ArrayList();
		show(c1,c2);
		
	}
	public static void show(Collection coll){
		//1.添加元素
		coll.add("abcdefg");
		System.out.println(coll.add("hijklmn"));//true
		coll.add("opqrst");
		coll.add("uvwxyz");
		System.out.println(coll);//[abcdefg, hijklmn, opqrst, uvwxyz]
		//2.删除元素
		coll.remove("hijklmn");
		System.out.println(coll);//[abcdefg, opqrst, uvwxyz] 集合长度发生变化
		//coll.removeAll(coll);//清空coll
		//System.out.println(coll);//[]
		//coll.clear();//[]
		//3.判断
		boolean b = coll.contains("abcdefg");
		System.out.println(b);//true
		System.out.println(coll.containsAll(coll));//true 自己包含自己的所有元素吗?
		System.out.println(coll.isEmpty());//false coll为空集合吗?
	}
	public static void show(Collection c1,Collection c2){
		//c1添加元素
		c1.add("abc1");
		c1.add("abc2");
		c1.add("abc3");
		c1.add("abc4");
		//c2添加元素的
		c2.add("abc1");
		c2.add("abc5");
		c2.add("abc6");
		System.out.println(c1);//[abc1, abc2, abc3, abc4]
		System.out.println(c2);//[abc1, abc5, abc6]
		//将c2添加到c1中
		c1.addAll(c2);
		System.out.println(c1);//[abc1, abc2, abc3, abc4, abc1, abc5, abc6]
		//从c1中删除和c2相同的元素
		c1.removeAll(c2);
		System.out.println(c1);//[abc2, abc3, abc4] 删除了两个abc1
		//演示containsAll
		boolean b1 = c1.containsAll(c2);//c1包含c2吗?
		System.out.println(b1);//false 已经删除重复,所以否
		//取交集
		System.out.println("取交集前"+c1);
		boolean b2 = c1.retainAll(c2);
		System.out.println("取交集后"+c1);//[] 取出的交集替换了c1
	}
}
           

输出结果: true

[abcdefg, hijklmn, opqrst, uvwxyz]

[abcdefg, opqrst, uvwxyz]

true

true

false

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

[abc1, abc2, abc3, abc4]

[abc1, abc5, abc6]

[abc1, abc2, abc3, abc4, abc1, abc5, abc6]

[abc2, abc3, abc4]

false

取交集前[abc2, abc3, abc4]

取交集后[]

package cu.fu._06collection;
import java.util.*;

public class CollectionDemo2 {
	public static void main(String[] args) {
		Collection coll = new ArrayList();
		coll.add("abc1");
		coll.add("abc2");
		coll.add("abc3");
		coll.add("add4");
		
		System.out.println(coll);//[abc1, abc2, abc3, add4]
		//使用Collection中的iterator()方法.调用集合中的迭代器方法,是未来获取集合中的迭代器对象.
		Iterator it1 = coll.iterator();
		while(it1.hasNext()){
			System.out.println(it1.next());
		}
		System.out.println("------------------");
		//for循环结束,Iterator变量内存释放,更高效
		for(Iterator it2 = coll.iterator();it2.hasNext();){
			System.out.println(it2.next());
		}
	}

}
           

输出结果: [abc1, abc2, abc3, add4]

abc1

abc2

abc3

add4

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

abc1

abc2

abc3

add4

List:

package cu.fu._07list_set;
/**
 * List Set
 * Collection
 * 		List:有序(存入和取出的顺序一致),元素都有索引(角标),允许重复元素.
 * 		Set:元素不能重复,无序.
 * 
 * List:特有的常见方法,共同特性是可以操作角标(index).
 * 
 * 1.添加
 * void add(index,element);
 * void addAll(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集合可以完成对元素的增删改查.
 */

import java.util.*;

public class ListDemo {

	public static void main(String[] args) {
		List list = new ArrayList();
		show(list);
	}
	public static void show(List list){
		//添加元素
		list.add("abc1");
		list.add("abc2");
		list.add("abc3");
		System.out.println(list);//[abc1, abc2, abc3]
		//插入元素
		list.add(1,"abc1");
		System.out.println(list);//[abc1, abc1, abc2, abc3] 在1索引插入,其他元素顺次右移
		//删除元素
		System.out.println(list.remove(2));//abc2 返回被删除的元素
		System.out.println(list);//[abc1, abc1, abc3]
		//修改元素
		System.out.println(list.set(1,"abc2"));//abc1 返回被修改的元素
		System.out.println(list);//[abc1, abc2, abc3]
		//获取元素
		System.out.println(list.get(0));//abc1 返回获取的元素
		//获取子列表
		System.out.println(list.subList(0, 2));//[abc1, abc2] 返回新的List 含头不含尾
	}
}
           

输出结果:

[abc1, abc2, abc3]

[abc1, abc1, abc2, abc3]

abc2

[abc1, abc1, abc3]

abc1

[abc1, abc2, abc3]

abc1

[abc1, abc2]

package cu.fu._07list_set;
import java.util.*;

public class ListDemo2 {
	public static void main(String[] args) {
		List list = new ArrayList();
		show(list);
	}
	public static void show(List list){
		list.add("abc1");
		list.add("abc2");
		list.add("abc3");
		list.add("abc4");
		
		//几种遍历方式
		Iterator it = list.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
		System.out.println("---------------------");
		for(Iterator it2 = list.iterator();it2.hasNext();){
			System.out.println(it2.next());
		}
		System.out.println("---------------------");
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
		
	}
}
           

运行结果: abc1

abc2

abc3

abc4

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

abc1

abc2

abc3

abc4

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

abc1

abc2

abc3

abc4

package cu.fu._07list_set;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;



public class ListDemo3 {

	public static void main(String[] args) {
		List list = new ArrayList();
		//show1(list);
		show2(list);
	}
	public static void show1(List list){
		list.add("123");
		list.add("456");
		list.add("789");
		System.out.println(list);//[123, 456, 789]
		Iterator it = list.iterator();
		while(it.hasNext()){
			Object obj = it.next();//出现异常 java.util.ConcurrentModificationException
			if(obj.equals("789")){
				list.add("012");
			}else{
				System.out.println(list);
			}
		}
		System.out.println(list);
	}
	
	public static void show2(List list){
		list.add("123");
		list.add("456");
		list.add("789");
		System.out.println(list);//[123, 456, 789]
		ListIterator lit = list.listIterator();//获取列表迭代器对象
		//它可以实现在迭代过程中完成对元素的增删改查.
		//只有list集合具有listIterator功能.
		while(lit.hasNext()){
			Object obj = lit.next();
			if(obj.equals("789")){
				lit.add("10");
			}
		}
		System.out.println(lit.hasNext());
		System.out.println(lit.hasPrevious());
		while(lit.hasPrevious()){
			System.out.println(lit.previous());
		}
		System.out.println(list);
	}
}
/*
 * P.S.
 * 在迭代器过程中,不要使用集合操作元素,容易出现异常
 * java.util.ConcurrentModificationException
 * 可以使用Iterator接口的子接口ListIterator来完成在迭代中对元素进行更多的操作.
 * 
 */
           

运行结果: [123, 456, 789]

false

true

10

789

456

123

[123, 456, 789, 10]

package cu.fu._08list;
import java.util.*;

class Person{
	private String name;
	private int age;
	public Person(){}
	public Person(String name, int age){
		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;
	}
	//为ArrayListTest2去重重写equals
	public boolean equals(Object obj){
		if(this == obj){//判断两个对象是否为同一个对象
			return true;
		}else if(!(obj instanceof Person)){//判断是否对象都源自Person类
			throw new ClassCastException("类型不同");
		}else {
			Person p = (Person)obj;//将obj的类型转换为Person方便调用name和age
			return this.name.equals(p.name)&&this.age==p.age;//姓名属于String,由于String类的不变性,不能用==,需要用equlas判断其内容是否相同
		}
	}	
	
}

public class ArrayListTest {

	public static void main(String[] args) {
		ArrayList al = new ArrayList();
		al.add(new Person("龙1",19));
		al.add(new Person("龙2",20));
		al.add(new Person("龙3",21));
		al.add(new Person("龙4",22));
		
		Iterator it = al.iterator();
		while(it.hasNext()){
			Person p = (Person)(it.next());
			System.out.println(p.getName()+" "+p.getAge());
		}
	}

}
           

运行结果: 龙1 19

龙2 20

龙3 21

龙4 22

package cu.fu._08list;
/**
 * 定义功能去除ArrayList中的重复元素.
 */
import java.util.*;

public class ArrayListTest2 {
	public static void main(String[] args) {
		ArrayList al = new ArrayList();
		al.add(new Person("展昭",25));
		al.add(new Person("包拯",35));
		al.add(new Person("小倩",22));
		al.add(new Person("如花",45));
		al.add(new Person("曾哥",43));
		al.add(new Person("如花",45));
		show(al);
		System.out.println("-----------------");
		show(getSingleElement(al));
		
	}
		public static ArrayList getSingleElement(ArrayList al){
			//定义一个临时容器
			ArrayList temp = new ArrayList();
			//迭代al集合
			Iterator it = al.iterator();
			while(it.hasNext()){
				Object obj = it.next();
				//判断迭代到的元素是否在临时容器内存在
				//contains 方法依靠的是equals方法
				if(!temp.contains(obj)){
					temp.add(obj);
				}
			}
			return temp;
		}
		public static void show(ArrayList al){
			Iterator it =al.iterator();
			while(it.hasNext()){
				Person p = (Person)(it.next());
				System.out.println(p.getName()+" "+p.getAge());
			}
			
		}
}
           

输出结果: 展昭 25

包拯 35

小倩 22

如花 45

曾哥 43

如花 45

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

展昭 25

包拯 35

小倩 22

如花 45

曾哥 43

package cu.fu._08list;
import java.util.*;
public class LinkedListDemo {

	public static void main(String[] args) {
		LinkedList link = new LinkedList();
		link.add("abc1");
		link.add("abc2");
		link.add("abc3");
		link.add("abc4");
		
		Iterator it = link.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
		System.out.println(link);//[abc1, abc2, abc3, abc4]
		System.out.println(link.getFirst());//abc1
		System.out.println(link.getLast());//abc4
		System.out.println(link.removeFirst());//abc1 获取第一个,但是删除
		System.out.println(link);//[abc2, abc3, abc4]
		//删除所有元素的方法
		//link.clear();
		while(!link.isEmpty()){//显示元素的删除操作
			System.out.println(link.removeFirst());
		}
		System.out.println(link);
	}

}
           

运行结果: abc1

abc2

abc3

abc4

[abc1, abc2, abc3, abc4]

abc1

abc4

abc1

[abc2, abc3, abc4]

abc2

abc3

abc4

[]

package cu.fu._08list;
/**
 * 请使用LinkedList来模拟衣服堆栈或者队列数据结构.
 * 堆栈:先进后出 First In Last Out FIFO(自定义myGet()中,用removeLast()方法)
 * 队列:先进先出 First In First Out FIFO(本列模拟)
 * 我们应该描述这样一个容器,给使用者提供一个容器对象完成这两种结构中的一种.
 */
import java.util.*;

class DuiLie{
	private LinkedList link;
	
	public DuiLie(){
		link = new LinkedList();
	}
	//队列的增删功能
	public void myAdd(Object obj){
		link.addLast(obj);
	}
	public Object myGet(){
		return link.removeFirst();
	}
	public boolean isNull(){
		return link.isEmpty();
	}
}

public class LinkedListTest {

	public static void main(String[] args) {
		DuiLie dl = new DuiLie();
		dl.myAdd("abc1");
		dl.myAdd("abc2");
		dl.myAdd("abc3");
		dl.myAdd("abc4");
		
		while(!dl.isNull()){
			System.out.println(dl.myGet());
		}
	}

}
           

运行结果:

abc1

abc2

abc3

abc4

package cu.fu._08list;
/**
 * Vector ArrayList LinkedList
 * List
 * 		Vector:		内部是数组数据结构,同步,增删查询都很慢.
 * 		ArrayList:	内部是数组数据结构,不同步,取代了Vector,查询的速度快.
 * 		LinkedList:	内部是链表数据结构,不同步,增删元素速度快.
 * 
 * LinkedList方法:
 * 		addFirst();
 * 		addLast();
 * 
 * JDK6版本后的新方法:
 * 		offerFirst();与addFirst方法没有区别.
 * 		offerLast();与addLast方法没有区别.
 * 		getFirst();//获取但不移除,如果链表为空,抛出NoSuchElementException
 * 		getLast();
 * 
 * 		peekFirst();//获取但不移除,如果链表为空,返回null
 * 		peekLast();
 * 		removeFirst();//获取并移除,如果链表为空,抛出NoSuchElementException
 * 		removeLast();
 * 
 * 		pollFirst();//获取并移除,如果链表为空,返回null;
 * 		pollLast();
 */
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;

public class VectorArrayListLinkedListDemo {
	public static void main(String[] args) {
		Vector v = new Vector();
		v.addElement("abc1");
		v.addElement("abc2");
		v.addElement("abc3");
		v.addElement("abc4");
		//两种迭代方式
		Enumeration en = v.elements();
		
		while(en.hasMoreElements()){
			System.out.println(en.nextElement());
		}
		System.out.println("----------------");
		Iterator it = v.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
	}

}
           

运行结果: abc1

abc2

abc3

abc4

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

abc1

abc2

abc3

abc4

package cu.fu._09set;
/**
 * Set:元素不可以重复,无序
 * set接口中的方法和Collection一致.
 * 		HashSet:内部数据结构是哈希表,是不同步的.
 * 		TreeSet:可以对Set集合中的元素进行排序,是不同步的.
 */
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class HashSetDemo {
	public static void main(String[] args) {
		Set hs = new HashSet();
		
		hs.add("麦兜");
		hs.add("野比");
		hs.add("路飞");
		hs.add("哆啦A梦");
		Iterator it = hs.iterator();
		while(it.hasNext()){
			System.out.println(it.next());//顺序改变了
		}
	}

}
           

运行结果: 哆啦A梦

麦兜

路飞

野比

package cu.fu._09set;
/**
 * 哈希表确定元素是否相同
 * 1.判断的是两个元素的哈希值是否相同.
 * 如果相同,再判断两个对象的内容是否相同.
 * 2.判断哈希值相同,其实判断的对象是HashCode方法,判断内容相同,用的是equals方法.
 * 
 * P.S.
 * 如果哈希值不同,不需要判断equals.
 * 往HashSet集合中存储Person对象.如果姓名年龄相同,视为同一个人,视为相同元素.
 */
import java.util.*;

class Person{
	private String name;
	private int age;
	
	public Person(){}
	
	public Person(String name,int age){
		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;
	}
	//重写hashCode()方法
	public int hashCode(){
		return name.hashCode()+age*39;
	}
	//重写equals()方法
	public boolean equals(Object obj){
		if(this == obj){
			return true;
		} else if(!(obj instanceof Person)){
			throw new ClassCastException("类型错误");
		}else {
			Person p = (Person)obj;
			return this.name.equals(p.name)&&this.age==p.age;
		}
	}
}

public class HashSetTest {

	public static void main(String[] args) {
		HashSet hs = new HashSet();
		hs.add(new Person("悟空",1500));
		hs.add(new Person("悟净",2500));
		hs.add(new Person("悟能",3000));
		hs.add(new Person("白龙马",2000));
		hs.add(new Person("悟空",1500));
		//由于重写了HashCode()方法和equals()方法,所以相同内容的对象无法存储进去.
		
		Iterator it = hs.iterator();
		while(it.hasNext()){
			Person p = (Person)(it.next());
			System.out.println(p.getName()+" "+p.getAge());
		}
	}

}
           

运行结果: 白龙马 2000

悟空 1500

悟净 2500

悟能 3000

package cu.fu._09set;
/**
 * 无序变有序,使用LinkHashSet
 */

import java.util.*;

public class LinkedHashSetDemo {
	public static void main(String[] args) {
		HashSet hs = new LinkedHashSet();
		hs.add("马云");
		hs.add("马化腾");
		hs.add("李彦宏");
		hs.add("雷军");
		Iterator it = hs.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
	}

}
           

运行结果: 马云

马化腾

李彦宏

雷军

package cu.fu._09set;
/**
 * 需求:对字符串长度排序
 */

import java.util.*;
class ComparatorByLength implements Comparator{//固定套路,可以记住
	public int compare(Object o1,Object o2){
		String s1 = (String)o1;
		String s2 = (String)o2;
		int temp = s1.length()-s2.length();
		return temp==0 ? s1.compareTo(s2):temp; 
	}
}

public class Test {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet(new ComparatorByLength());
		ts.add("sada");
		ts.add("sad2");
		ts.add("lkjsdflkjadsf");
		ts.add("caklsjdlas");
		ts.add("aeiournvcxczxc");
		Iterator it = ts.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
		
	}

}
           

运行结果: sad2

sada

caklsjdlas

lkjsdflkjadsf

aeiournvcxczxc

package cu.fu._09set;
/**
 * TreeSet判断元素唯一性的方式:
 * 就是根据比较方法的返回结果是否是0,是0就是相同元素,不存.
 * 
 * TreeSet对元素进行排序的方式之一:
 * 让元素自身具备比较功能,元素就要实现Comparable接口,重写compareTo方法.
 */
import java.util.Iterator;
import java.util.TreeSet;
class Person2 implements Comparable{
	private String name;
	private int age;
	
	public Person2(){}
	public Person2(String name,int age){
		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;
	}
	public int hashCode(){
		return name.hashCode()+age*39;
	}
	public boolean equals(Object obj){
		if(this == obj){
			return true;
		} else if(!(obj instanceof Person2)){
			throw new ClassCastException("数据类型错误");
		} else{
			Person2 p =(Person2)obj;
			return this.name.equals(p.name)&&this.age==p.age;
		}
	}
	public int compareTo(Object o){
		Person2 p = (Person2)o;
		//先按照年龄排序,再按照名字排序,避免年龄相同的人没有存进去.
		int temp = this.age-p.age;
		return temp == 0 ? this.name.compareTo(p.name):temp;
	}	
}

public class TreeSetDemo {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet();
		//以Person对象年龄进行从小到大的排序
		ts.add(new Person2("麦兜",27));
		ts.add(new Person2("兔子",25));
		ts.add(new Person2("豆豆",27));
		ts.add(new Person2("兔子妈咪",44));
		ts.add(new Person2("麦兜妈咪",51));
		
		Iterator it = ts.iterator();
		while(it.hasNext()){
			Person2 p = (Person2)(it.next());
			System.out.println(p.getName() + " "+p.getAge());
		}
	}

}
           

运行结果: 兔子 25

豆豆 27

麦兜 27

兔子妈咪 44

麦兜妈咪 51

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

//创建一个根据Person2类的name进行排序的比较器.
class ComparatorByName implements Comparator{
	public int compare(Object o1,Object o2){
		Person2 p1 = (Person2)o1;
		Person2 p2 = (Person2)o2;
		
		int temp =p1.getName().compareTo(p2.getName());
		return temp ==0 ? p1.getAge()-p2.getAge() : temp;
	}
}

public class TreeSetDemo2 {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet(new ComparatorByName());
		ts.add(new Person2("a",20));
		ts.add(new Person2("ss",22));
		ts.add(new Person2("dsf",25));
		ts.add(new Person2("s",16));
		ts.add(new Person2("s",18));//相同姓名时,年纪小先排序
		
		Iterator it = ts.iterator();
		while(it.hasNext()){
			Person2 p = (Person2)(it.next());
			System.out.println(p.getName()+" "+p.getAge());
		}
	}
}
/*
 * P.S.
 * 比较方式优先级:比较器高于元素内实现Comparable
 * 如果自定义类实现了Comparable接口,并且TreeSet的构造函数中也传入了比较器,那么以比较器为准.
 * TreeSet集合的底层是二叉树进行排序的.
 */
           

运行结果: a 20

dsf 25

s 16

s 18

ss 22