黑马程序员- 集合框架

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

1,集合类

    为什么出现集合类?

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

      集合和集合类同时容器,有何不同?

    数组虽然也可以存储对象,但长度是固定的,集合长度是可变的

   数组中可以存储基本数据类型,集合只能存储对象。

   集合类的特点

       集合只用于存储对象,集合的长度是可变的,集合可以存储不同类型的对象。

2,集合的学习体系:

    ----  |Colleciton 描述所有接口的共性

        ------|List可以有重复元素的集合

        ------|Set 不能有重复元素的集合

3,Collection 常用方法

    1增加:

          add();将指定的对象存储到集合容器中

          addAll() 将指定集合中的元素添加到调用方法集合中

     2,删除

           remove()将指定集合元素添加到调用该方法的集合中。

           removeAll()将指定集合中的元素删除

     3,修改:

         clear()清空集合中的所有元素

      4,判断

          isEmpty() 判断集合是否为空

          contains()判断集合中是否包含指定对象 使用equals()判断两个对象是否相等

          containsAll(0判断集合中是否包含指定集合 使用equals()判断两个对象是否相等。

      5,获取

          size()返回集合容器的大小

       6,查看集合里面的所有元素转换方法:

           toArray()返回包含collection中所有元素的数组

       7,Iterable迭代器 该类主要用来便利集合对象,该类描述了遍历集合的常用迭代方法。

            1,hashNext()如果有元素可以迭代,就返回true;

            2,next()返回下一个元素。如果没有下一个元素,调用元素会抛出NoSuchElementExcepton

            3,remover()从迭代器指向的集合中移除迭代器返回的最后一个元素

            4,迭代器 游戏或指针,其实就是调用了ArrayList.get() index++;

import java.util.ArrayList;

public class Test1 {
	public static void main(String[] args) {
		ArrayList a1 = new ArrayList();
		// 添加元素
		a1.add("java01");// add(Object obj);
		a1.add("java02");
		a1.add("java03");
		sop(a1);

		a1.remove("java02");// 删除元素
		a1.clear();// 清除元素
		sop("java03是否存在" + a1.contains("java01"));
		sop("集合是否为空?" + a1.isEmpty());
		// 获取长度
		sop("size" + a1.size());
	}

	public static void sop(Object obj) {
		System.out.println(obj);
	}
}
import java.util.ArrayList;
import java.util.Iterator;

/*
 * 什么是迭代器
 * 其实就是集合的取出元素的方式。
 */

public class Test2 {
	public static void main(String[] args) {
		method_get();
	}

	public static void method_get() {
		ArrayList a1 = new ArrayList();
		// 添加元素
		a1.add("java01");// add(Object obj);
		a1.add("java02");
		a1.add("java03");
		Iterator it = a1.iterator();// 获取迭代器,用于取出集合中的元素
		while (it.hasNext()) {
			sop(it.next());
		}
	}

	public static void sop(Object obj) {
		System.out.println(obj);
	}
}



 

 4,List

     1,获取

          1,get(int index);

               注意:IndexOutOfBoundsExcepton;

            2,修改

                set(int index,E element);

            3,查找:

                   int indexOf(Object);//找不到返回-1;

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

/*
 * Collection 
 *     |--List:元素是有序的,元素可以重复,因为该集合体系有索引
 *     |--Set :元素无序,元素不可以重复
 *   List
 *   本身也是一个抽取出来的接口
 *   特有方法:凡是可以操作角标的方法都是该体系特有的方法
 *    增
 *      add(index,element);
 *      addAll(index,Collection);
 *    删
 *       remove(index);
 *    改
 *     set(index,elemet);
 *    查
 *       get(index);
 *       subList(from,to);
 *       listIterator();
 */
public class Test3 {
	public static void sop(Object obj) {
		System.out.println(obj);
	}

	public static void main(String[] args) {
		ArrayList a1 = new ArrayList();
		a1.add("java01");
		a1.add("java02");
		a1.add("java03");
		sop("源集合是" + a1);
		a1.add(1, "java09");// 添加指定位置
		a1.remove(2);// 删除指定位置的元素
		// 修改元素
		a1.set(2, "java07");
		// 通过角标获取元素
		sop("get(1):" + a1.get(1));
		// 获取所有元素
		for (int x = 0; x < a1.size(); x++) {
			System.out.println("a1" + a1.get(x));
		}
		Iterator it=a1.iterator();
		while(it.hasNext()){
			sop("next:"+it.next());
		}
		sop("index"+a1.indexOf("java02"));
		List sub=a1.subList(1, 3);//包含1不包含3
		sop("sub"+sub);
	}
}


 删除list集合重复的值。

 

import java.util.ArrayList;
public class Test{
 public static void main(String[] args) {
  ArrayList list = new ArrayList();
  //list.add("abc");
  list.add("adb");
  list.add("abc");
  list.add("abc");
  list.add("adb");
  list.add("abc");
  System.out.println(list.size());
  //int size = list.size();
  for (int x = 0; x < list.size(); x++){//循环
   String str = (String)list.get(x);
   if (str.equals("abc")) {//判断条件
    list.remove(x);
      // list.remove(0);
       System.out.println("--还剩下"+list.size()+".."+x);
       x=-1;//集合的长度在不断的变化,所以这里要是x=-1;
   }
  }
  System.out.println(list);
  System.out.println(list.size());
 }
}
 

5,ArrayList,LinkedList比较

        2, ArrayList 实现List接口

        3,LinkedList

             1,查找元素慢,出入和删除快。

         4,ArrayList和LinkedList的存储查找的优点和缺点

            1,ArrayList是采用动态数组来存储元素的,它允许直接下标号直接查找对应的元素。

                     但是,插入元素要涉及数组元素移动及内存的操作。总结:查找速度快,插入操作忙。

            2,LindedList 是采用双向链表示实现存储,按序号索引数据需要进行前向或后向便利

                    但是插入数据的时,只需要记录本项前后项即可,所以插入速度快。

import java.util.LinkedList;

public class Test4 {
	public static void main(String[] args) {
		LinkedList link = new LinkedList();
		link.addFirst("java01");// linklist特有方法
		link.addFirst("java02");
		link.addFirst("java03");
		link.addFirst("java04");
		link.addLast("java05");
		sop(link);
		sop(link.getFirst());// 不删除获取
		sop(link.getLast());
		sop(link.remove());// 获取并删除
		sop(link.size());
	}

	public static void sop(Object obj) {
		System.out.println(obj);
	}

}


6,Set

   Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复

   Set:集合的功能和Collection是一致的。

      1,问题:有一批数据要存储,要求存储这批数据不能出现重复数据,ArrayList,LinkedList都没法满足需求

          解决方法:Set集合

      2,set集合特点:无序。不能有重复元素的集合

      3,HashSet:数据结构是哈希表,线程是非同步的

         哈希表是按照哈希值来存储的

          不是同一对象,但是地址值是一样的,这个时候他会在该地址值下顺延。

            保证元素唯一性的原理:判断元素的hashCode值是否相同

           如果相同,还会继续判断元素的equals方法,是否为true;添加失败就为假。

            HashSet是如何保证元素唯一性的呢?

              是通过元素的两个方法,hashCode和equals来完成。

              如果元素的HashCode值相同,才会判断euqals是否为true,如果元素的hashscode值不同,不会调用equals.(建立一个比较有针对性的hashcode会比较高效一些)

       

import java.util.HashSet; import java.util.Iterator;

/**  * HashSet存储自定义对象  *  * @author Administrator 网hashset存入自定义对象,姓名和年龄相同为同一个人,重复元素  */ public class Test {  public static void main(String[] args) {   HashSet hs = new HashSet();   //添加person对象   hs.add(new Person("a1", 11));   hs.add(new Person("a2", 12));   hs.add(new Person("a3", 13));   hs.add(new Person("a2", 12));   //hs.add(new Person("a4", 14));   Iterator it = hs.iterator();//迭代器对象   //遍历   while (it.hasNext()) {    Person p = (Person) it.next();//强制类型转换    sop(p.getName()+"::"+p.getAge());   }  }    /**     * 打印方法     * @param obj     */  public static void sop(Object obj) {   System.out.println(obj);  } }  /**   * person类,名字年龄   * @author Administrator   *   */ class Person {  private String name;

 public String getName() {   return name;  }

 public int getAge() {   return age;  }

 private int age;

 Person(String name, int age) {   this.name = name;   this.age = age;  }     //重写equals方法  public boolean equals(Object obj) {   if (!(obj instanceof Person)) {    return false;   }   Person p = (Person) obj;   return this.name.equals(p.name) && this.age == p.age;  } }

以上打印结果为:

     a2::12
     a1::11
     a2::12  
     a3::13

equals没有被调用。因为比较先看地址。new 出来的,都有自己独立的hashcode,有自己的位置存储,都存进去了,不用再读equals方法了。

现在要覆盖Person 的hashcode方法,建立Person对象自己的哈希值。怎么建立哈希值呢?你的判断条件是什么,依据条件来生成哈希值,这里按照姓名年龄判断是不是同一个元素,那就依据这个条件判断哈希值。

  

import java.util.HashSet;
import java.util.Iterator;

/**
 * HashSet存储自定义对象
 * 
 * @author Administrator 网hashset存入自定义对象,姓名和年龄相同为同一个人,重复元素
 */
public class Test2 {
	public static void main(String[] args) {
		HashSet hs = new HashSet();
		hs.add(new Person("a1", 11));
		hs.add(new Person("a2", 12));
		hs.add(new Person("a3", 13));
		hs.add(new Person("a2", 12));
		//hs.add(new Person("a4", 14));
		Iterator it = hs.iterator();
		while (it.hasNext()) {
			Person p = (Person) it.next();
			sop(p.getName()+"::"+p.getAge());
		}
	}

	public static void sop(Object obj) {
		System.out.println(obj);
	}
}

class Person {
	private String name;

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	private int age;

	Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
    public int hashCode(){
    	System.out.println(this.name+"....hashcode");
    	//按照条件设置hashcode
    	return name.hashCode()+this.age*39;//39没有特殊意思,也可以是其他,容易导致hashcode相同,尽量保持哈希值的唯一
    //不科学的比较方式	return 60;
    }
	public boolean equals(Object obj) {
		if (!(obj instanceof Person)) {
			return false;
		}
		Person p = (Person) obj;
		System.out.println(this.name+".euqals.."+p.name);
		return this.name.equals(p.name) && this.age == p.age;
	}
}


 

科学的打印

a1....hashcode
a2....hashcode
a3....hashcode
a2....hashcode
a2.euqals..a2
a2::12
a3::13
a1::11

非科学打印结果为

a1....hashcode
a2....hashcode
a2.euqals..a1
a3....hashcode
a3.euqals..a2
a3.euqals..a1
a2....hashcode
a2.euqals..a3
a2.euqals..a2
a3::13
a2::12
a1::11
HashSet判断和删除的依据

注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。先判断hashCode,hashcode如果有的话, 再判断equals.

import java.util.HashSet; import java.util.Iterator;

/**  * HashSet存储自定义对象  *  * @author Administrator 网hashset存入自定义对象,姓名和年龄相同为同一个人,重复元素  */ public class Test {  public static void main(String[] args) {   HashSet hs = new HashSet();   hs.add(new Person("a1", 11));   hs.add(new Person("a2", 12));   hs.add(new Person("a3", 13));   hs.add(new Person("a2", 12));   //hs.add(new Person("a4", 14));   sop(hs.contains(new Person("a1",11)));   hs.remove(new Person("a1",11));   Iterator it = hs.iterator();   while (it.hasNext()) {//迭代器迭代    Person p = (Person) it.next();    sop(p.getName()+"::"+p.getAge());   }  }    //打印  public static void sop(Object obj) {   System.out.println(obj);  } }

class Person {  private String name;

 public String getName() {   return name;  }

 public int getAge() {   return age;  }

 private int age;

 Person(String name, int age) {   this.name = name;   this.age = age;  }  //重写hashCode方法     public int hashCode(){      System.out.println(this.name+"....hashcode");      //按照条件设置hashcode      return name.hashCode()+this.age*39;//39没有特殊意思,也可以是其他,容易导致hashcode相同,尽量保持哈希值的唯一     //不科学的比较方式 return 60;     }     //重写equals方法  public boolean equals(Object obj) {   if (!(obj instanceof Person)) {    return false;//如果不是Person的实例,返回false;   }   Person p = (Person) obj;   System.out.println(this.name+".euqals.."+p.name);   return this.name.equals(p.name) && this.age == p.age;//比较年龄和名字  } }

ArrayList判断元素是否存在,和删除元素只依赖于equals,而hashSet依赖于hashCode和equals

     4TreeSet:可以对set集合中的元素进行排序。自然顺序ASCII表

          

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

/**
 * 可以对Set集合中的元素进行排序。Ascii排序
 * 
 * @author Administrator
 * 
 */
public class Test4 {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet();
		ts.add("abcd");
		ts.add("abcg");
		ts.add("aaaa");
		ts.add("bca");
		Iterator it = ts.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());// 跟存的顺序不一样但是打印的时候有自己的顺序
			// 打印结果aaaa
			// abcd
			// abcg
			// bca
		}
	}
}


 

                       底层数据结构是二叉树

                       保证元素的唯一性的依据

                       compareTo方法return 0,返回0认为元素相同,否则都不相同

                       排序的第一种方式:让元素自身具备比较性,让元素自身具备比较性。

                         元素需要实现Compaable接口,覆盖compareTo方法,这种方式称为元素的自然顺序,或者叫做默认顺序,一被定义出来就具备比较性

                      排序的第二种方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性。

                 存储自定义对象

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

/**
 * 存储之定义对象
 * 往TreeSet集合中存储自定义对象
 * 想按照学生的年龄进行排序
 * @author Administrator
 * 
 */
public class Test4 {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet();
		ts.add(new Student("lisi02", 22));
		ts.add(new Student("lise007", 20));
		ts.add(new Student("lise09", 22));
		ts.add(new Student("lise01", 22));
		Iterator it = ts.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());

		}
	}
}

class Student {
	private String name;
	private int age;

	public int getAge() {
		return age;
	}

	Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

}

类型转换异常,学生不能不能被转换java.lang.Comparable
Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法被称为自然比较法。

以上例子,存储一个对象,就没有异常,再存就出现了异常。。TreeSet集合能排序,可是按照什么方式排呢?学生对象不具备比较性。所以java说,你必须要让你的元素具备比较性。TreeSet集合的要求是,往里面存的集合必须具备比较性。怎么具备比较性呢?

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

/**
 * 存储之定义对象
 * 往TreeSet集合中存储自定义对象
 * 想按照学生的年龄进行排序
 * @author Administrator
 * 
 */
public class Test4 {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet();
		ts.add(new Student("lisi02", 22));
		ts.add(new Student("lise007", 20));
		ts.add(new Student("lise09", 19));
	//	ts.add(new Student("lise01", 22));
		Iterator it = ts.iterator();
		while (it.hasNext()) {
			Student stu=(Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());

		}
	}
}

class Student implements Comparable {//该类接口强制让学生具备比较性
	private String name;
	private int age;

	public int getAge() {
		return age;
	}

	Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	@Override
	public int compareTo(Object obj) {
		// TODO Auto-generated method stub
		if(!(obj instanceof Student)){
			throw new RuntimeException("不是学生对象");
		}
		Student s=(Student)obj;
		System.out.println(this.name+"...........compareto........"+s.name);
		if(this.age>s.age){//此对象大于指定对象返回正数
		   return 1;
		}else if(this.age==s.age){
			return 0;
		}
		return -1;
	}

}

但是以上的代码还是有问题的。如果再添加一个年龄相同的对象,则发现打印 的时候少了一个对象。当他们年龄相等的时候,compareTo返回0.
代表此对象与指定对象是相同的。就没有存进去。在本例中,年龄相同,姓名也相同才是同一个人。毫无疑问,判断完年龄后,再判断一下姓名。当主要条件相同时,要排序次要条件排。次要条件相同,那就相同了。这里要比较字符串,字符串具备比较行为。String 类的compareTo(String anotherString)按照字典顺序比较两个字符串。

String类,本身就已经实现了Comparable.java中的很多对象都具备比较性。

 记住:排序时,当主要条件相同时,一定判断一下次要条件。

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

/**
 * 存储之定义对象
 * 往TreeSet集合中存储自定义对象
 * 想按照学生的年龄进行排序
 * @author Administrator
 * 
 */
public class Test4 {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet();
		ts.add(new Student("lisi02", 22));
		ts.add(new Student("lise007", 20));
		ts.add(new Student("lise09", 19));
		ts.add(new Student("lise10", 19));
	//	ts.add(new Student("lise01", 22));
		Iterator it = ts.iterator();
		while (it.hasNext()) {
			Student stu=(Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());

		}
	}
}

class Student implements Comparable {//该类接口强制让学生具备比较性
	private String name;
	private int age;

	public int getAge() {
		return age;
	}

	Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	@Override
	public int compareTo(Object obj) {
		// TODO Auto-generated method stub
		if(!(obj instanceof Student)){
			throw new RuntimeException("不是学生对象");
		}
		Student s=(Student)obj;
		System.out.println(this.name+"...........compareto........"+s.name);
		if(this.age>s.age){//此对象大于指定对象返回正数
		   return 1;
		}else if(this.age==s.age){
	            return this.name.compareTo(s.name);
		}
		return -1;
	}

}

TreeSet 排序就是互相比较,元素越多,你互相比较的次数越多,效率很低。所以为了优化效率,TreeSet用了一种特殊的数据结构。二叉树,减少比较次数,提高比较性能。(小于的在左边,大于的在右边)

如果是降序,return 的值1变为-1,都取反。

现在让数据怎么存进去的怎么取出来。怎么做呢?

在TreeSet比较对象的时候,和compareTo 方法中的if判断是没有关系的。只看结果,是正是负,是0,?直接return 1就可以实现。

排序的第二种方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性。

在集合初始化时,就有了比较方式。构造函数

定义比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

第一种,让元素具备比较性,第二种让容器自身具备比较性。当两种排序都存在时,以比较器为主。

定义一个类。实现Comparator接口,覆盖Compare方法

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

/**
 * 存储之定义对象
 * 往TreeSet集合中存储自定义对象
 * 想按照学生的年龄进行排序
 * @author Administrator
 * 
 */
public class Test4 {
	public static void main(String[] args) {
		TreeSet ts = new TreeSet(new MyCompares());
		ts.add(new Student("lisi02", 22));
		ts.add(new Student("lisi007", 20));
		ts.add(new Student("lisi09", 19));
		ts.add(new Student("lisi10", 19));
		ts.add(new Student("lisi007", 20));
	//	ts.add(new Student("lise01", 22));
		Iterator it = ts.iterator();
		while (it.hasNext()) {
			Student stu=(Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());

		}
	}
}

class Student implements Comparable {//该类接口强制让学生具备比较性
	private String name;
	private int age;

	public int getAge() {
		return age;
	}

	Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	@Override
	public int compareTo(Object obj) {
		// TODO Auto-generated method stub
		if(!(obj instanceof Student)){
			throw new RuntimeException("不是学生对象");
		}
		Student s=(Student)obj;
		//System.out.println(this.name+"...........compareto........"+s.name);
		if(this.age>s.age){//此对象大于指定对象返回正数
		   return 1;
		}else if(this.age==s.age){
	            return this.name.compareTo(s.name);
		}
		return -1;
	}

}
class MyCompares implements Comparator{
 //这里不用复写equals方法了,因为MyCompares继承了Object了。已经有了equals
	@Override
	public int compare(Object o1, Object o2) {
		// TODO Auto-generated method stub
		Student s1=(Student)o1;
		Student s2=(Student)o2;
		int num= s1.getName().compareTo(s2.getName());
		if(num==0){//主要条件相同,判断次要条件
			/*if(s1.getAge()>s2.getAge()){
				return 1;
			}
			if(s1.getAge()==s2.getAge()){
				return 0;
			}
			//return -1;*/
		return	new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
		}
		return num;
	
	}
	
}

以上就是排序的两种方式。

实例:按照字符串长度进行比较

import java.util.HashSet;
import java.util.Iterator;

public class Test5 {
	public static void main(String[] args) {
		// Test5 t1=new Test5();
		// Test5 t2=new Test5();
		HashSet hs = new HashSet();
		hs.add("javao1");// 返回true
		hs.add("javao1");// 返回false;
		hs.add("javao2");
		hs.add("javao3");
		Iterator it = hs.iterator();
		while (it.hasNext()) {
			sop(it.next());
		}
	}

	public static void sop(Object obj) {
		System.out.println(obj);
	}
}
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

/*  * 按照字符串长度排序TreeSet基本应用  */ public class Test6 {  public static void main(String[] args) {   TreeSet ts = new TreeSet(new StringLengthCommparator());   ts.add("abcd");   ts.add("cc");   ts.add("z");   ts.add("hahha");   Iterator it = ts.iterator();   while (it.hasNext()) {    System.out.println(it.next());   }  } }

class StringLengthCommparator implements Comparator {

 @Override  public int compare(Object o1, Object o2) {   // TODO Auto-generated method stub   String s1 = (String) o1;   String s2 = (String) o2;   /*    * if(s1.length()>s2.length()){ return 1; }    * if(s1.length()==s2.length()){ return 0; }    */   int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));   if (num == 0) {    return s1.compareTo(s2);   }   return num;  }

}

 

|-- HashSet
       |-- 底层是哈希表,不存储重复元素
       |-- 存储自定义对象,需要覆盖对象中的hashCode和equals方法,保证对象对象唯一
     |-- TreeSet
       |-- 底层是二叉树结构,不存储重复元素
       |-- 存储对象,按照对象的自然顺序排序
       |-- 自定义对象,必须具备比较性
         |--对象本身具备比较性,实现Comparable接口,覆盖compareTo方法
         |--TreeSet本身具备比较性,自定义比较器,实现Comparator接口,覆盖compare方法  

 7,泛型

        1泛型的好处:

            1,将运行时的异常提前至编译时发生

            2,使用get获取元素的时候无需强类型转型,就避免了类型转换的异常问题

   泛型的格式:通过<>来定义要操作的引用数据类型。

   在使用java提供的对象时,什么时候写泛型呢?

通常在集合框架中很常见

只要见到<>就要定义泛型。

其实<>就是用来接收类型的。

当使用集合时,将集合中要存储的数据类型做作为参数传递到<>中即可。

上面的例子可以优化

 

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

/**
 * 存储之定义对象
 * 往TreeSet集合中存储自定义对象
 * 想按照学生的年龄进行排序
 * @author Administrator
 * 
 */
public class Test4 {
	public static void main(String[] args) {
		TreeSet<Student> ts = new TreeSet<Student>(new MyCompares());
		ts.add(new Student("lisi02", 22));
		ts.add(new Student("lisi007", 20));
		ts.add(new Student("lisi09", 19));
		ts.add(new Student("lisi10", 19));
		ts.add(new Student("lisi007", 20));
	//	ts.add(new Student("lise01", 22));
		Iterator it = ts.iterator();
		while (it.hasNext()) {
			Student stu=(Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());

		}
	}
}

class Student implements Comparable {//该类接口强制让学生具备比较性
	private String name;
	private int age;

	public int getAge() {
		return age;
	}

	Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	@Override
	public int compareTo(Object obj) {
		// TODO Auto-generated method stub
		if(!(obj instanceof Student)){
			throw new RuntimeException("不是学生对象");
		}
		Student s=(Student)obj;
		//System.out.println(this.name+"...........compareto........"+s.name);
		if(this.age>s.age){//此对象大于指定对象返回正数
		   return 1;
		}else if(this.age==s.age){
	            return this.name.compareTo(s.name);
		}
		return -1;
	}

}
class MyCompares implements Comparator<Student>{//定义泛型不用转换了。
 
	@Override
	public int compare(Student s1, Student s2) {
		// TODO Auto-generated method stub
		
		int num= s1.getName().compareTo(s2.getName());
		if(num==0){//主要条件相同,判断次要条件
			
		return	new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
		}
		return num;
	
	}
	
}


 

以下是自定义泛型的示例

public class Test7 {
   public static void main(String[] args) {
	   
	  Tool<Worker> u=new Tool<Worker>();
	  u.setObject(new Worker());
	  Worker w=u.getObect();
   }
}
class Worker{
	
}
class Student{
	
}
class Tool<QQ>{
	private QQ q;
	public void setObject(QQ q){
		this.q=q;
	}
	public QQ getObect(){
		return q;
	}
}


 什么时候定义泛型类呢?

当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展。

现在定义泛型来完成扩展。

泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。

为了让不同方法可以操作不同类型,而且类型还不确定,那么可以就将泛型定义在方法上。

class Demo{

       public <T> void show(T t)

      {

             syso(t)

      }

}

  8,map

        --|Map接口   将键映射到值得对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。

              --|HashMap采用哈希表实现,所以无序

         1,常见方法

                  添加

              put(key,value);可以使用相同的key值,但是添加的value值会覆盖前面的,返回值是前一个value。

                   //添加元素,如果出现相同的键,那么后添加的值会覆盖原有键对应的值。并put方法返回被覆盖的值。

                     删除

             remove(key)删除关联对象,指定key对象

             clear()清除集合对象

                   判断

              containsValue(Object value)

              containsKey(Object key)

              isEmpty()

                     获取

              get(Object key);

               size()

                value()

                entrySet()

                 keySet()

          2,遍历方式

               需要分别获取key和value Set<> keySet()返回所有对象的Set集合

          3,结构体系

                   |--Hashtable:底层是哈希表数据结构,不可以存入null键null值,该集合是线程同步的,用作键的对象,必须实现hashCode方法,和equals方法,该集合是元老级别的。效率低。

                   |--HashMap:底层是哈希表数据结构,并允许使用null键null值,该集合不同步的,效率高。

                   |--TreeMap:底层是二叉树数据结构,线程不同步,,可以用于给map集合中的键进行排序

             和set很像,Set底层就是使用了Map集合

Map.Entry其实Entry也是一个接口,它是Map接口中的一个内部接口。Map集合内部的事物,只有有了Map集合才能有关系,Entry直接访问Map集合中的元素。所以定义了内部规则。

public static interface Map.Entry<k,v>;能加static的接口一定是内部接口。只有接口在成员位置上,才能加上静态修饰符。

interface Map{

    public static interface Entry{

             public abstract Object getKey();

            public abstract Object getValue();

   }

}

class HashMap implements Map.Entry{

   public Object getKey();

   public Object getValue();

}

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class Test8 {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("01", "a1");
		map.put("02", "a2");
		map.put("03", "a3");
		System.out.println("containsKey" + map.containsKey("022"));// false
		System.out.println("remove" + map.remove("02"));// 返回移除的值
		System.out.println("get:" + map.get("023"));// 判断是否存在,返回null
		map.put("04", null);// 空可以作为键存在,Hashtbale不能空
		System.out.println("get:" + map.get("04"));// 可以通过get方法的返回值来判断一个键是否存在
		// 获取map集合中所有的值
		Collection<String> coll = map.values();
		System.out.println(coll);// 无序的
		// map.put(key,value)返回这个键对应的原来的值,没有返回null,存在则覆盖原有键对应的值,put方法返回被覆盖的值
		System.out.println("put:" + map.put("05", "a5"));

	}
}

keyset的示例

 取出原理:将map集合转成set集合。在通过迭代器取出。

       
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/*
 * map集合的两种取出方式
 *  1,keySet:将map中所有的键存入到set集合。因为set具备迭代器
 *    所有可以迭代方式取出所有的键,在根据get方法获取每一个键对应的值
 *   2,entrySet
 */
public class Test9 {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("01", "a1");
		map.put("02", "a2");
		map.put("03", "a3");
		// 先获取map集合的所有键的set集合,keyset();
		Set<String> keySet = map.keySet();
		// 有了Set集合,就可以获取其迭代
		Iterator<String> it = keySet.iterator();
		while (it.hasNext()) {
			String key = it.next();
			// 有了键就可以通过map集合的get方法获取其对应的值
			String value = map.get(key);
			System.out.println("key" + key + "value:" + value);
		}
	}
}


 entrySet示例

  

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/*
 * Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了set集合中,
 * 而这个关系数据类型就是:Map.Entry
 */
public class Test10 {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("01", "a1");
		map.put("02", "a2");
		map.put("03", "a3");
		// 将map集合中的映射关系取出,存入set集合中
		Set<Map.Entry<String, String>> entrySet = map.entrySet();
		Iterator<Map.Entry<String, String>> it = entrySet.iterator();
		while (it.hasNext()) {
			Map.Entry<String, String> me = it.next();
			String key = me.getKey();
			String valeu = me.getValue();
		}
	}
}


 

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * 练习: 每一个学生都有对应的归属地。 学生Student 地址String 学生属性:姓名,年龄 注意:姓名和年龄相同的视为同一个学生。
 * 保证学生的唯一性。
 * 
 * @author Administrator
 * 
 */
public class Test5 {
	public static void main(String[] args) {
         Map<Student1,String> map=new HashMap<Student1,String>();
         map.put(new Student1("lisi1",21), "beijign");
         map.put(new Student1("lisi2",22), "shanghai");
         map.put(new Student1("lisi3",23), "nanjing");
         map.put(new Student1("lisi4",24), "wuhan");
         //第一种方式取出keySet
         Set<Student1> keyset=map.keySet();
         Iterator<Student1> it=keyset.iterator();
         while(it.hasNext()){
        	 Student1 stu=it.next();
        	 String addr=map.get(stu);
        	 System.out.println(stu+".."+addr);
         }
         //第二种取出方式:
           Set<Map.Entry<Student1, String>>  entrySet=map.entrySet();
           Iterator<Map.Entry<Student1, String>> iter=entrySet.iterator();
           while(iter.hasNext()){
        	   Map.Entry<Student1, String> me=iter.next();
        	   Student1 stu=me.getKey();
        	   String addr=me.getValue();
        	   System.out.println(stu+"..."+addr);
           }
	}
}


class Student1 implements Comparable<Student1> {
	private String name;
	private int age;
      Student1(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 String toString(){
		return name+":"+age;
	}
	public int hashCode(){
		return name.hashCode()+age*34;
	}
	public boolean euqals(Object obj){//不能加泛型
		if(!(obj instanceof Student)){
		//	return new RuntimeException("类型不匹配");
			throw new ClassCastException("类型不匹配");
		}
		Student1 s=(Student1)obj;
		return this.name.equals(s.name)&&this.age==s.age;
	}
	@Override
	public int compareTo(Student1 s) {
		// TODO Auto-generated method stub
		int num=new Integer(this.age).compareTo(new Integer(s.age));
		if(num==0){
			return this.name.compareTo(s.name);
		}
		return num;
	}
	
	
}

//按照学生姓名比较,自定义比较器。

treeMap

import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * 练习: 每一个学生都有对应的归属地。 学生Student 地址String 学生属性:姓名,年龄 注意:姓名和年龄相同的视为同一个学生。
 * 保证学生的唯一性。
 * 
 * @author Administrator
 * 
 */
public class Test5 {
	public static void main(String[] args) {
		// Map<Student1,String> map=new HashMap<Student1,String>();
		TreeMap<Student1, String> map = new TreeMap<Student1, String>(
				new StuNameComparator());
		map.put(new Student1("blisi1", 21), "beijign");
		map.put(new Student1("lisi2", 22), "shanghai");
		map.put(new Student1("lisi2", 22), "nanjing");
		map.put(new Student1("lisi4", 24), "wuhan");
		// 第一种方式取出keySet
		Set<Student1> keyset = map.keySet();
		Iterator<Student1> it = keyset.iterator();
		while (it.hasNext()) {
			Student1 stu = it.next();
			String addr = map.get(stu);
			System.out.println(stu + ".." + addr);
		}
		// 第二种取出方式:
		/*
		 * Set<Map.Entry<Student1, String>> entrySet=map.entrySet();
		 * Iterator<Map.Entry<Student1, String>> iter=entrySet.iterator();
		 * while(iter.hasNext()){ Map.Entry<Student1, String> me=iter.next();
		 * Student1 stu=me.getKey(); String addr=me.getValue();
		 * System.out.println(stu+"..."+addr); }
		 */
	}
}

class Student1 implements Comparable<Student1> {
	private String name;
	private int age;

	Student1(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 String toString() {
		return name + ":" + age;
	}

	public int hashCode() {
		return name.hashCode() + age * 34;
	}

	public boolean euqals(Object obj) {// 不能加泛型
		if (!(obj instanceof Student)) {
			// return new RuntimeException("类型不匹配");
			throw new ClassCastException("类型不匹配");
		}
		Student1 s = (Student1) obj;
		return this.name.equals(s.name) && this.age == s.age;
	}

	@Override
	public int compareTo(Student1 s) {
		// TODO Auto-generated method stub
		int num = new Integer(this.age).compareTo(new Integer(s.age));
		if (num == 0) {
			return this.name.compareTo(s.name);
		}
		return num;
	}

}

class StuNameComparator implements Comparator<Student1> {

	@Override
	public int compare(Student1 o1, Student1 o2) {
		// TODO Auto-generated method stub
		int num = o1.getName().compareTo(o2.getName());
		if (num == 0) {
			return new Integer(o1.getAge()).compareTo(new Integer(o2.getAge()));
		}
		return num;
	}

}


import java.util.TreeMap;

/**
 * 第一次用a字母作为键去找集合,那么集合没有a这个键,所以也没有对应的次数。 返回null, 如果为null,就将a字母和1存入集合。
 * 如果指定的键已经存在,说明有对应的次数,就将对应的次数取出,并自增后再重新存入集合。
 * 
 * @author Administrator 思路: 1,将字符串转换成字符数组,因为要对每一个字母进行操作。
 *         2,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。
 *         3,遍历字符数组,将每一个字母作为字母作为键去查map集合,如果返回null,就将该字母和1存入map集合中,
 *         如果返回不是null,说明,该字母在map集合中已经存在,并有对应的次数,并获取该次数,并进行自增。
 *         然后将该字母和子增后的次数存入map集合中,覆盖原来键所对应的值 4,将map集合中的数据变成指定的字符串形式返回。
 */
public class Test6 {
	public static void main(String[] args) {
		String str = "tabdf..daf";
		charCount(str);
	}

	public static String charCount(String str) {

		char[] chs = str.toCharArray();
		int count = 0;
		TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
		for (int x = 0; x < chs.length; x++) {
			if (!(chs[x] >= 'a' && chs[x] <= 'z' || chs[x] >= 'A'
					&& chs[x] <= 'Z')) {
				continue;
			}
			Integer value = tm.get(chs[x]);
			/*
			 * if (value == null) { tm.put(chs[x], 1); } else { value = value +
			 * 1; tm.put(chs[x], value); }
			 */
			if (value != null) {
				count = value;
			}
			count++;
			tm.put(chs[x], count);
			count = 0;
		}
		System.out.println(tm.toString());

		return null;
	}
}



 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值