容器---马士兵java

容器

1136(一个一个三个知识点六个接口

Set:没有顺序,不能重复

List:有顺序,可以重复

重复的意思是指,两个对象互相equals,就算重复了

Map:定义了存储“”(key),(value)映射对的方法

一、Collection接口

示例1:

import java.util.*;

public class BasicContainer {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Collection c=new ArrayList();
//父类引用指向子类对象,可以改掉new后面的,提高对象灵活性(比如改为LinkedList)
		c.add("hello");
		c.add(new Name("f1","l1"));
//add里装的必须是对象object(对象),对象是定义在堆上的,栈里的是值,值随时会被清空
		c.add(new Integer(100));
		System.out.println(c.size());//装了几个对象
		System.out.println(c);//相当于调用了c.toString 
	}
class Name {
	private String firstName,lastName;                                        
	public Name(String firstName,String lastName) {//构造方法                              
		// TODO 自动生成的构造函数存根
		this.firstName=firstName;
		this.lastName=lastName;
	}
	public String getFirstName() {
		return firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public String toString() {
		return firstName+" "+lastName;
	}

输出结果:3

                [hello,f1 11,100]


示例2:

		// TODO 自动生成的方法存根
		Collection c=new HashSet();//父类引用指向子类对象,可以改掉new后面的代码,提高灵活性
		c.add("hello");
		c.add(new Name("f1","11"));//add里装的必须是对象object(对象),对象是定义在堆上的,栈里的是值,值随时会被清空
		c.add(new Integer(100));
		c.remove("hello");//可以remove掉
		c.remove(new Integer(100));//可以remove掉,因为Integer也重写了equals方法,而且他们俩只要值一样就算equals
		System.out.println(c.remove(new Name("f1","l1")));//返回true/false  //没有重写的equals方法Hash就不能去除
		System.out.println(c);//相当于调用了c.toString 

输出:false

         [f1,l1]


Collection方法举例:


重写一个对象的equals()方法必须要重写它的hashCode()方法

两个对象互相的equals,两个对象具备相同的hashCode

什么时候有用?当这个对象当做索引(键)的时候


示例3:

---在Name类中重写equalshashCode---

class Name {
	private String firstName,lastName;                                          
	public Name(String firstName,String lastName) {//构造方法                               
		// TODO 自动生成的构造函数存根
		this.firstName=firstName;
		this.lastName=lastName;
	}
	public String getFirstName() {
		return firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public String toString() {
		return firstName+""+lastName;
	}
	 
	public boolean equals(Object obj) {
		if(obj instanceof Name) {
			Name name=(Name)obj;//强制转换为Name对象
			return (firstName.equals(name.firstName))&&
					(lastName.equals(name.lastName));
		}
		return super.equals(obj);//如果传入的不是 Name对象,就交给Name父类Object类处理传入的对象
	}
	public int hashCode(){//重写equals()方法必须重写hashCode()方法。当这个对象当做索引当做键的时候
		return firstName.hashCode();
	}

输出:true

         []



二、Iterator接口


Iterator像是用来做遍历


ArrayList底层是数组,要找一个数组,从头到尾找就可以了(找快

LinkedList是连接的,是以链表为底层元素的(找慢


示例1:

一个典型的遍历

import java.util.*;
public class Test {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Collection c=new HashSet();//没顺序
		c.add(new Name("f1","11"));
		c.add(new Name("f2","12"));
		c.add(new Name("f3","13"));
		Iterator i =c.iterator();//拿到HashSet本身遍历自身的对象,那个对象是什么没关系不用去管//拿到对象了
		while(i.hasNext()) {
			//next()的返回值为object类型,需要转换为相应类型
			Name n=(Name) i.next();//强制转换为Name类型
			System.out.print(n.getFirstName()+" ");
		}
	}
}

输出:f1 f2 f3 


示例2:

Iterator对象的remove()方法是迭代过程中删除元素的唯一的安全方法

import java.util.*;
public class Test2 {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Collection c=new HashSet();
		c.add(new Name("fff1","1111"));
		c.add(new Name("f2","12"));
		c.add(new Name("fff3","1113"));
		for (Iterator i =c.iterator();i.hasNext();) {//for的第一个语句只执行一次,i被初始化。没有第三个语句
			Name name=(Name)i.next();
			if(name.getFirstName().length()<3) {//getFirstName返回的String类型
				i.remove();
            //如果换成c.remove(name);会产生例外
			//不能使用容器自身的remove()方法,要用Iterator的,因为在执行过程中,Iterator执行了锁定(线程)
			}
		}
		System.out.println(c);
	}
}

输出:[fff3 1113, fff1 1111]



三、EnhancedFor


import java.util.*;

public class EnhancedFor {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int []arr= {1,2,3,4,5};
		for (int i : arr) {//把arr数组的元素存到i中
			System.out.println(i);
		}
		
		Collection c=new ArrayList();
		c.add(new String ("aaa"));
		c.add(new String ("bbb"));
		c.add(new String ("ccc"));
		for (Object  o : c) {//把c中的元素放到对象o中
			System.out.println(o);//把o打印出来,相当于调用o.toString
		}
	}
}

输出:1
          2
          3
          4
          5
          aaa

          bbb   

          ccc

       


四、Set接口


示例1:

import java.util.*;

public class TestSet2 {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Set s1=new HashSet();
		Set s2=new HashSet();
		s1.add("a");s1.add("b");s1.add("c");
		s2.add("d");s2.add("a");s2.add("b");
		//Set和List容器类都具有Constructor(Collection c)
		//构造方法用以初始化容器类
		Set sn=new HashSet(s1);//s1中所有内容给sn
		sn.retainAll(s2);//求s1,s2的交集
		Set su=new HashSet(s1);
		su.addAll(s2);//s1全部元素添加到s2里,重复元素不添加
		System.out.println(sn);
		System.out.println(su);
	}
}
输出 [a, b]
          [a, b, c, d]


示例2:

import java.util.*;;

public class TestSet {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Set s=new HashSet();//父类引用指向子类对象
		s.add("hello");
		s.add("world");
		s.add(new Name("f1","f2"));
		s.add(new Integer(100));
		s.add(new Name("f1","f2"));//相同元素不会往里添加
		s.add("hello");//相同元素不会往里添加
		System.out.println(s);
	}
}

输出:[world, 100, hello, f1 f2]



五、List接口


List非常像数组

set():返回的是一个对象,因为是替换掉一个对象,不是覆盖

add():添加一个元素,在原来元素上往后挤一格

indexOf():求一个字符或者字符串在另一个字符串中出现的位置。用到了equals()方法

返回该列表中指定元素的第一次出现的索引,或者如果该列表不包含元素,则返回-1。


示例:


import java.util.*;
public class TestList {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		List l1=new LinkedList();
		for (int i = 0; i <=5; i++) {
			l1.add("a"+i);
		}
		System.out.println(l1);
		l1.add(3,"a100");//add是往后挤一个
		System.out.println(l1);
		l1.set(6, "a200");//替换
		System.out.println(l1);
		System.out.print((String)l1.get(2)+" ");//返回第2个位置的元素,转回字符串类型
		System.out.println(l1.indexOf("a3"));//找到a3的位置
		l1.remove(1);//移除第一个位置的元素,即a1
		System.out.println(l1);
	}
}

输出:

[a0, a1, a2, a3, a4, a5]

[a0, a1, a2, a100, a3, a4, a5]
[a0, a1, a2, a100, a3, a4, a200]
a2 4

[a0, a2, a100, a3, a4, a200]



六、Collections类

1136(一个图一个类三个知识点六个接口)

binarySearch():用二分法查找


示例:

import java.util.*;
public class TestList2 {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		List l1=new LinkedList();
		List l2=new LinkedList();
		for (int i = 0; i <=9; i++) {
			l1.add("a"+i);
		}
		System.out.println(l1);
		Collections.shuffle(l1);//随机排序
		System.out.println(l1);
		Collections.reverse(l1);//逆序
		System.out.println(l1);
		Collections.sort(l1);//排序
		System.out.println(l1);
		System.out.println(Collections.binarySearch(l1, "a5"));//折半查找
	}
}

输出:

[a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]
[a3, a0, a6, a9, a1, a5, a4, a8, a2, a7]
[a7, a2, a8, a4, a5, a1, a9, a6, a0, a3]
[a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]

5

LinkedList逆序起来比ArrayList容易

如果要排从低到高,则先排好序(循环实现)再逆序



七、Comparable接口


comparaTo里传的可以是任何对象




示例:给字母顺序给名字排序

import java.util.*;
public class BC2 {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		 List l1=new LinkedList();
		   l1.add(new Name("Karl","M"));
		   l1.add(new Name("Steven","Lee"));
		   l1.add(new Name("John","O"));
		   l1.add(new Name("Tom","M"));
		   System.out.println(l1);
		   Collections.sort(l1);
		   System.out.println(l1);
	   }
}

class Name implements Comparable{                 
	private String firstName,lastName;                                            
	public Name(String firstName,String lastName) {//构造方法  
		// TODO 自动生成的构造函数存根
		this.firstName=firstName;
		this.lastName=lastName;
	}
	public String getFirstName() {
		return firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public String toString() {
		return firstName+" "+lastName;
	}
	 
	public boolean equals(Object obj) {
		if(obj instanceof Name) {
			Name name=(Name)obj;//强制转换为Name对象
			return (firstName.equals(name.firstName))&&
					(lastName.equals(name.lastName));
		}
		return super.equals(obj);
		//如果传入的不是 Name对象,就交给Name父类Object类处理传入的对象
	}
	public int hashCode(){
		//重写equals()方法必须重写hashCode()方法。当这个对象当做索引当做键的时候
		return firstName.hashCode();
	}
	
	public int compareTo(Object o) {
		Name n=(Name)o;//强制转换类型,如果传入其他对象,立马出现问题
		int lastCmp=lastName.compareTo(n.lastName);
		//String类实现了Comparabel接口,所以可以调用compareTo方法,比较姓氏首字母
		return (lastCmp!=0?lastCmp:firstName.compareTo(n.firstName));
		//如果lastCmp!=0,就返回姓氏,如果姓氏相同,比较名字首字母
	}
}

输出:

[Karl M, Steven Lee, John O, Tom M]

[Steven Lee, Karl M, Tom M, John O]



八、如何选择数据结构



九、Map接口


HashMap是用哈希表实现的

TreeMap是用二叉树实现的

**这里的重复指的还是equals,但是比较equals来查键不能重复,效率太低,直接比较hashCode,所以重写了equals的类必须重写hashCode,两个对象互相equals,它们的hashCode必须相等就在于这个地方,因为Map规定了键值不能重复,比较equals太慢,所以比较hashCode**


put():返回的是object,因为是替换掉原来的value,替换掉的就被返回了

get():通过key找到相对应的对象object

putAll():把另外一个Map的东西都加进来

clear():清除


示例:


import java.util.*;
public class MapTest {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Map m1=new HashMap();
		Map m2=new TreeMap();
		m1.put("one",new Integer(1));
		//key是string类型,value是Integer对象类型
		m1.put("two",new Integer(2));                                          
		m1.put("three",new Integer(3));
		//key:one two three,对应的对象1 2 3,只不过不是基本数据类型,是基本数据类型包装的对象
		m2.put("A",new Integer(1));
		m2.put("B",new Integer(2));
		System.out.println(m1.size());
		System.out.println(m1.containsKey("one"));//判断是否包含key
		System.out.println
		                  (m2.containsValue(new Integer(1)));//判断是否包含value
		if (m1.containsKey("two")) {
			int i=((Integer)m1.get("two")).intValue();
			//get找到键(key),根据索引找到相对应的对象value
			//拿到的是object,所以要强制转换为Integer,
			//因为要复制到int的基础类型,求它作为int类型的值再穿进去(.intValue())
			System.out.println(i);                      
		}                                               
		Map m3=new HashMap(m1);//m1的数据放到m3里
		m3.putAll(m2);//m2的数据全放到m2里
		System.out.println(m3);
	}
}

输出:

3
true
true
2

{A=1, B=2, two=2, three=3, one=1}



十、自动打包解包



修改代码:利用自动打包解包

修改TestMap:


import java.util.*;
public class MapTest2 {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Map m1=new HashMap();
		Map m2=new TreeMap();
		m1.put("one",1); //把1自动打包为对象
		m1.put("two",2);
		m1.put("three",3);
		m2.put("A",1);
		m2.put("B",2);
		System.out.println(m1.size());
		System.out.println(m1.containsKey("one"));//判断是否包含key
		System.out.println
                          (m2.containsValue(1));//自动把1打包成Integer对象		
		if (m1.containsKey("two")) {
			int i=(Integer)m1.get("two");
			//***一定加上(Integer)才可以自动拆包
			//因为拿到的时候是个对象,不知道能不能转换为int
			//所以强制转换后,会自动拆包成相对应的值
			System.out.println(i);                      
		}                                               
		Map m3=new HashMap(m1);//m1的数据放到m3里
		m3.putAll(m2);//m2的数据放到m2里
		System.out.println(m3);
	}
}

输出:

3
true
true
2

{A=1, B=2, two=2, three=3, one=1}


示例:判断字符串出现次数

import java.util.*;
//判断字符串出现次数
public class TestArgsWords {
	private static final Integer ONE=new Integer(1);//ONE里存的是1
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Map m=new HashMap();
		for (int i = 0; i < args.length; i++) {
			Integer freq=(Integer)m.get(args[i]);//以key(键)来查找value(值)
			m.put(args[i], (freq==null?ONE:new Integer(freq.intValue()+1)));
		}
		System.out.println(m.size()+" distinct words detected:");
		System.out.println(m);
	}
}
//输入aaa bbb aaa
//aaa是key,一开始对应的value是null,运行11行,freq==null,第12行,设置aaa的value为1
//bbb同上
//再次输入aaa,已经可以索引到value,所以12行中,取出value,然后+1,再转为Integer对象输出,即value变为2
//输出结果:
//3 distinct words detected:
//{aaa:2,bbb:1}

修改代码:改为自动打包解包

import java.util.*;
//判断字符串出现次数
public class TestArgsWords2 {
	private static final int ONE=1;
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Map m=new HashMap();
		for (int i = 0; i < args.length; i++) {
			int freq=(Integer)m.get(args[i])==null?0:(Integer)m.get(args[i]);
			//把对象转换为Integer对象,因为传入的是对象,要判断是不是为空,为空就赋值0,不为空就是自身
			m.put(args[i], (freq==0?ONE:freq+1));
		}
		System.out.println(m.size()+" distinct words detected:");
		System.out.println(m);
	}
}



十一、泛型


容易出错在于:比如扔进去一只狗,强制转化成一只猫


示例:泛型

import java.util.*;
//泛型
public class BasicGeneric {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		List<String> c=new ArrayList<String>();//表示只能装String
		c.add("aaa");
		c.add("bbb");
		c.add("ccc");
		for (int i = 0; i < c.size(); i++) {
			String s=c.get(i);//原来需要强制转换,现在不需要了,因为扔进的是String,拿出来也是String
			System.out.println(s);
		}
		Collection<String>c2=new HashSet<String>();
		c2.add("aaa");
		c2.add("bbb");
		c2.add("ccc");
		for (Iterator <String> it = c2.iterator(); it.hasNext();) {
			String s=it.next();
			System.out.println(s);
		}
	}
}


class MyName implements Comparable<MyName>{
	//只跟MyName作比较,和其他类作比较没意义,其他类一传进来就出错
	int age;
	public int compareTo(MyName mn) {
		//原本compareTo方法里面的参数是object类型,利用泛型之后,指定为MyName类型
		//由编译器判断传入的是不是MyName类型,不再需要强制转换
		if (this.age>mn.age) 
			return 1;
		else if(this.age<mn.age)
			return -1;
		else return 0;
	}
}

输出:

aaa
bbb
ccc
aaa
ccc

bbb


修改代码:利用泛型和自动打包解包

修改MapTest:

import java.util.*;
//利用泛型和自动打包解包修改代码
public class MapTest3 {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Map<String,Integer> m1=new HashMap<String,Integer>();
		Map<String,Integer> m2=new TreeMap<String,Integer>();
		m1.put("one",1); //把1自动打包为对象
		m1.put("two",2);
		m1.put("three",3);
		m2.put("A",1);
		m2.put("B",2);
		System.out.println(m1.size());
		System.out.println(m1.containsKey("one"));//判断是否包含key
		System.out.println
                          (m2.containsValue(1));//自动把1打包成Integer对象		
		if (m1.containsKey("two")) {
			int i=m1.get("two");//拿出来是Integer对象类型
			System.out.println(i);                      
		}                                               
		Map m3=new HashMap(m1);//m1的数据放到m3里
		m3.putAll(m2);//m2的数据放到m2里
		System.out.println(m3);
	}
}

输出:

3
true
true
2

{A=1, B=2, two=2, three=3, one=1}


修改TestArgsWords:


import java.util.*;;
//判断字符串出现次数
public class TestArgsWords3 {
	private static final int ONE=1;
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Map<String,Integer>m=new HashMap<String,Integer>();
		for (int i = 0; i < args.length; i++) {
			if (!m.containsKey(args[i])) {//判断是=是否含有key
				m.put(args[i],ONE);
				//如果没有,就把ONE的值给它,这里用到了自动打包解包,因为put传入的是object类型
			}else {
				int freq=m.get(args[i]);//拿到key对应的value值并转换为int类型
				m.put(args[i],freq+1);//value+1
			}
		}
		System.out.println(m.size()+" distinct words detected:");
		System.out.println(m); 
	}
}

以后用到集合的时候,尽量使用泛型



十二、总结


(Generic:泛型)

六个接口:

1、Collection接口--->2、Set接口

                             --->3、List接口

4、Map接口

5、Iterator接口:标准的、统一的来遍历一个Collection方式

6、Comparable接口:可以运用泛型,来定义这个类之间两个对象谁大谁小

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值