黑马程序员-----集合(collection,map)

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


集合的继承体系结构图:

Collection
 |- List
       |- ArrayList
       |- LinkedList
       |- Vector
 |- Set
      |- HashSet
      |- TreeSet


Collection: 集合的顶层接口
 方法:
   添加功能:
    boolean add(E e) 把给定的数据 添加到集合中
    boolean addAll(Collection c) 把给定的集合的元素,添加到当前集合中
   删除功能:
    void clear() : 将集合中的元素清空
    boolean remove(Object o): 将给定的元素在集合中删除
    boolean removeAll(Collection c)将给定的集合元素,在当前集合中删除 
 
   长度功能:
    int size() 返回集合中元素的个数
 
 转换功能:
    Object[] toArray(): 把集合 转换成数组
 
   判断功能:
    boolean contains(Object o)判断当前集合中是否包含给定的元素
    boolean isEmpty() 判断当前集合中的元素 是否为空
    boolean containsAll(Collection<?> c) 判断当前集合中,是否包含给定集合中所有的元素
 
 遍历功能(迭代器):
  Iterator<E> iterator(): 遍历集合中的元素 
   Iterator中的方法:
       boolean hasNext()如果仍有元素可以迭代,则返回 true。
      Object next() 返回迭代的下一个元素。 
 
 交集功能:
  boolean retainAll(Collection<?> c)判断两个集合中相同的元素  

List:
 特点:
      它是Collection子集合
      可以存储重复的元素
      有序(元素存与取顺序一致)

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_05_List;

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

/*
 * 使用List集合存储自定义对象,并遍历
 */
public class ListDemo2 {
	public static void main(String[] args) {
		//创建List集合对象
		List list = new ArrayList();
		//创建元素对象
		Person p1 = new Person("天花", 10);
		Person p2 = new Person("菊花", 11);
		Person p3 = new Person("桃花", 12);
		
		//添加元素到集合
		list.add(p1);
		list.add(p2);
		list.add(p3);
		
		//遍历
		Iterator it = list.iterator();
		while (it.hasNext()) {
			Person p = (Person)it.next();
			System.out.println(p.getName() + "--" + p.getAge());
		}
	}
</span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">}
</span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><pre class="java" name="code">package cn.itcast_03_ArrayList;

public class Person {
	private String name;

	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Person(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}
</span></span></span>

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_12_ForEach;

import java.util.ArrayList;

/*
 * 需求:请使用ArrayList集合存储多个自定义对象,并遍历(泛型, 增强for)
 */
public class ForEachTest2 {
	public static void main(String[] args) {
		
		ArrayList<Person> list = new ArrayList<Person>();
		
		list.add(new Person("赵日天"));
		list.add(new Person("啦啦"));
		list.add(new Person("哈哈"));
		
		for(Person p : list) {
			System.out.println(p.getName());
		}
		
	}
}
</span></span></span>

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"> </span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"> </span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"> </span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><p>List:
 特有方法:
  void add(int index, E element) : 在当前集合中指定位置 添加给定的元素
    Object get(int index) 返回集合中指定位置的元素。
    int indexOf(Object o)返回此集合中第一次出现的指定元素的索引;如果此集合不包含该元素,则返回 -1。
    E remove(int index)移除集合中指定位置的元素
    E set(int index, E element)用指定元素替换集合中指定位置的元素
    ListIterator<E> listIterator() 返回此集合元素的列表迭代器</p><p> 并发修改异常产生的原因及解决方案:
  ConcurrentModificationException 并发修改异常:
  在使用迭代器遍历的过程中,原有集合中的元素个数不能发生改变,否则抛出 并发修改异常
  
  解决方式:
   普通for:
    添加的新元素到原有集合的末尾添加
   ListIterator:
    添加的新元素在Java元素的后面添加
  
常见的数据结构:
 栈:
  特点:
   先进后出
 队列:
  特点:
   先进先出
 数组:
  特点:
   增删慢,查询快
 链表:
  特点:
   增删快,查找慢
  
List的三个子类的特点:
 ArrayList:
    底层: 数组结构, 增删慢 ,查询快
    线程不同步,效率高,不安全
 Vector:
    底层: 数组结构, 增删慢,查询快
    线程同步,效率低, 安全
 LinkedList:
    底层: 链表结构, 增删快,查询慢
    线程不同步,效率高,不安全  </p><p>
ArrayList:
 案例:
  ArrayList存储字符串并遍历
  </p><pre class="java" name="code">public class ArrayListDemo {
	public static void main(String[] args) {
		//创建集合对象
		ArrayList list = new ArrayList();
		//添加字符串元素到集合
		list.add("Hello");
		list.add("Java");
		list.add("hehe");
		//遍历
		for (int i =0; i<list.size(); i++) {
			//获取到每一个元素,打印
			System.out.println( list.get(i) );
		}
	}
}</span></span></span>



  
Vector:
 特有方法:
  public void addElement(Object obj)  添加元素到集合    ————  add(Obejct obj)
    public Object elementAt(int index) 返回集合中给定位置上的元素  ---- get(int index)
    public Enumeration elements()返回此向量的组件的枚举     --- iterator()
     boolean hasMoreElements()  ----  hasNext()
     Object  nextElement() ---  next();

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">public class VectorDemo {
	public static void main(String[] args) {
		//创建集合对象
		Vector v = new Vector();
		//添加元素到集合
		//v.add("hello");
		v.addElement("hello");
		v.addElement("world");
		
		//遍历
		//size() 与 get()
		for (int i = 0; i < v.size(); i++) {
			System.out.println( v.elementAt(i) );
		}
		
		//迭代器
		Enumeration en = v.elements();
		//判断是否有下一个元素
		while (en.hasMoreElements()) {
			//获取下一个元素
			System.out.println( en.nextElement() );
		}
	}
}
</span></span></span>


 

LinkedList:
 特有方法:
  public void addFirst(Object e)将指定元素插入此列表的开头
  public void addLast(Object e)将指定元素添加到此列表的结尾。 
  public Object getFirst()返回此列表的第一个元素
  public Object getLast()返回此列表的最后一个元素。
  public Object removeFirst()移除并返回此列表的第一个元素。
  public Object removeLast()移除并返回此列表的最后一个元素。

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">public class LinkedListDemo {
	public static void main(String[] args) {
		//创建集合对象
		LinkedList list = new LinkedList();
		
		//添加元素
		list.add("JavaSE");
		
		//public void addFirst(Object e)
		list.addFirst("JavaEE");
		
		//public void addLast(Object e)
		list.addLast("Android");
		
		//public Object getFirst()
		System.out.println("getFirst:"+ list.getFirst());
		//public Object getLast()
		System.out.println("getLast:"+ list.getLast());
		
		System.out.println("-------------------------");
		//public Object removeFirst()
		//Object obj = list.removeFirst();
		//System.out.println("obj:"+obj);
		
		//public Object removeLast()
		Object obj = list.removeLast();
		System.out.println("obj:"+obj);
		
		//显示
		System.out.println(list);
		
	}
}
</span></span></span>


 

泛型:
 泛型: Generic

 泛型的格式:
  < 泛型类型  >
  注意: 这里的泛型类型可以任意的内容,基本的数据类型,
   比如  String Person QQ、T、E、K
  

 泛型常见在哪里可以使用?
     接口上使用泛型
     类上使用泛型
     方法上使用泛型
  
 泛型类:
  把泛型定义在类上
   格式:public class 类名<泛型类型1,…>
   注意:泛型类型必须是引用类型
  
  <QQ> 定义一个泛型
  QQ 使用当前这个泛型,这个QQ在程序运行的时候,会对应着一个具体的数据类型
  例如:
   public class Test<QQ> {
    private QQ name;
    public void setName(QQ name){
     this.name = name;
    }
    public QQ getName(){
     return name;
    }
   }


 

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">public class QQTest {
	public static void main(String[] args) {
		//Test t = new Test();
		Test<String> t = new Test<String>();
		t.setName("哈哈");
		System.out.println( t.getName() );
		
		
		Test<Integer> t2 = new Test<Integer>();
		t2.setName(123);
		System.out.println( t2.getName() );
	}
}
</span></span></span>


 
 泛型方法
  把泛型定义在方法上
   格式:public <泛型类型> 返回类型 方法名(泛型类型 .)
 
  K 的类型是在创建对象的时候 确定的
  TT 类型是在调用方法的时候 确定的
  这里的K,TT 理解为 是一种数据类型的变量名
  注意:创建多个泛型类对象的时候,可以赋值不同的泛型类型,不会产生冲突
  例如:
   public class GenericMethod<K> {
    //普通方法
    public String method(String str){
     return str + "哈哈";
    }
    //泛型方法
    public K function(K str){
     return str;
    }
    //泛型方法
    public <TT> TT show(TT str) {
     return str;
    }
   }
   
 泛型接口
  把泛型定义在接口上
   格式:public  interface 接口名<泛型类型1…>
   例如
   public interface Inter<TT> {
    public TT show(TT str);
   }
   
  实现泛型接口的类:
  方式1:在编写类的时候实现泛型接口
   public class InterImpl implements Inter<String> {
    @Override
    public String show(String str) {
     return str;
    }
   }
  方式2:创建对象的时候,确定泛型的数据类型
   InterImpl<QQ> 声明泛型QQ
   implements Inter<QQ> 使用QQ 所代表的数据类型
  
   public class InterImpl<QQ> implements Inter<QQ>{
    @Override
    public QQ show(QQ str) {
     return str;
    }
   }
   
 泛型高级之通配符
  泛型通配符<?>
   任意类型,如果没有明确,那么就是Object以及任意的Java类了

  ? extends E
   向上限定,E及其子类
    ?代表了 可以是E所对应的数据类型,或者是E的子类类型
   例如:
    ? extends Animal
    ? 代表了 Animal类型,或者Animal子类类型
 
  ? super E
   向下限定,E及其父类
    ?代表了  可以使 E所对应的数据类型,或者是E的父类类型  
   例如:
    ? super Dog
    ? 代表的是 Dog类型,或者是Dog的父类类型

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><pre class="java" name="code">package cn.itcast_11_Generic;

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

/*
 * 泛型通配符<?>
 		任意类型,如果没有明确,那么就是Object以及任意的Java类了

 	? extends E
 		向上限定,E及其子类
 		?代表了 可以是E所对应的数据类型,或者是E的子类类型
 		
 		例如:
 		? extends Animal
 		? 代表了 Animal类型,或者Animal子类类型
 
 
 	? super E
 		向下限定,E及其父类
 		?代表了  可以使 E所对应的数据类型,或者是E的父类类型
 		
 		例如:
 		? super Dog
 		? 代表的是 Dog类型,或者是Dog的父类类型

 */
class Animal {
}

class Dog extends Animal {
}

class Cat extends Animal {
}

public class CollectionDemo {
	public static void main(String[] args) {
		//泛型的数据类型 要求左右一致
		//Collection<Object> coll = new ArrayList<Animal>();
		//Collection<Animal> coll = new ArrayList<Dog>();
		
		
		Collection<?> c1 = new ArrayList<Animal>();
		Collection<?> c2 = new ArrayList<Dog>();
		Collection<?> c3 = new ArrayList<Cat>();
		Collection<?> c4 = new ArrayList<Object>();

		Collection<? extends Animal> c5 = new ArrayList<Animal>();
		Collection<? extends Animal> c6 = new ArrayList<Dog>();
		Collection<? extends Animal> c7 = new ArrayList<Cat>();
//		Collection<? extends Animal> c8 = new ArrayList<Object>(); 因为 Object类型,不是Animal类型或Animal的子类型

		Collection<? super Animal> c9 = new ArrayList<Animal>();
//		Collection<? super Animal> c10 = new ArrayList<Dog>();// 因为Dog 不是 Animal类型 或者 Animal的父类型
//		Collection<? super Animal> c11 = new ArrayList<Cat>();// 因为Cat 不是 Animal类型 或者 Animal的父类型
		Collection<? super Animal> c12 = new ArrayList<Object>();
	}
}
</span></span></span>

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"></span> </span></span>


 

 

增强for的概述和使用:
 增强for概述 jdk1.5出现的新特性
  简化数组和Collection集合的遍历


 
 格式:
  for(元素数据类型 变量 : 数组或者Collection集合) {
   使用变量即可,该变量就是元素
  }
  
 好处:简化遍历
  注意事项:增强for的目标要判断是否为null
  把前面的集合代码的遍历用增强for改进

 注意:
  如果需要使用索引, 请使用传统for
  如果不需要使用索引,推荐是使用增强for(), 也可以使用迭代器

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><pre class="java" name="code">package cn.itcast_12_ForEach;

import java.util.ArrayList;

/*
 * 需求:请使用ArrayList集合存储多个自定义对象,并遍历(泛型, 增强for)
 */
public class ForEachTest2 {
	public static void main(String[] args) {
		
		ArrayList<Person> list = new ArrayList<Person>();
		
		list.add(new Person("赵日天"));
		list.add(new Person("啦啦"));
		list.add(new Person("哈哈"));
		
		for(Person p : list) {
			System.out.println(p.getName());
		}
		
	}
}
</span></span></span>

(了解)静态导入:
 静态导入概述
  格式:import static 包名….类名.方法名;
  可以直接导入到方法的级别
 注意事项
  方法必须是静态的
  
(了解)可变参数
 变参数概述
  定义方法的时候不知道该定义多少个参数
 格式
  修饰符 返回值类型 方法名(数据类型…  变量名){}
 注意:
  这里的变量其实是一个数组
  如果一个方法有可变参数,并且有多个参数,
  那么,可变参数肯定是最后一个,并且一个方法中只能有一个可变参数
  
(了解)Set:一个不包含重复元素的集合

(重点)HashSet:
 底层: 哈希表结构
 特点:
  不包含重复元素
  无序(元素的存与取的顺序不一致)
  线程不同步--不安全--效率高
 (重点)HashSet如何保证元素唯一性:
  重写 hashCode()方法 与 equals()方法

(了解)LinkedHashSet:
 底层:哈希表结构 + 链表结构
 特点:
  不包含重复元素
  由链表保证元素有序
  由哈希表保证元素唯一
  线程不同步--不安全--效率高
 
(了解)TreeSet:
 底层:二叉树结构(红黑树结构)
 线程不同步--不安全--效率高
 TreeSet是如何保证元素的排序和唯一性的:
  1: 元素对应的类,实现自然排序接口[Comparable],重写compareTo(obj1)方法
  2: 或创建TreeSet集合对象时,实现比较器接口[Comparator], 重写compare(obj1, obj2)方法
 
(注意)Collection集合总结:
 Collection
  |- List
   |- ArrayList(重点)
   |- Vector (了解) 
   |- LinkedList (了解)
  |- Set
   |- HashSet (重点)
   |- TreeSet(了解)
 
以后对于Collection集合,掌握如下:
 考虑元素唯一 使用HashSet
 可以有重复元素 使用ArrayList
 
 
案例:
 ArrayList集合 嵌套 ArrayList集合
 HashSet集合存储自定义对象并遍历
 TreeSet集合存储自定义对象并遍历
 编写一个程序,获取10个1至20的随机数,要求随机数不能重复
 键盘录入3个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台

(了解)静态导入: 静态导入概述  格式:import static 包名….类名.方法名;  可以直接导入到方法的级别 注意事项  方法必须是静态的

 

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_01_StaticImport;

/*
 * 静态导入
 * import static 包名….类名.方法名;
		可以直接导入到方法的级别
 */
import static java.lang.Math.abs;

public class StaticImportDemo {
	public static void main(String[] args) {
		
		System.out.println(Math.abs(-3.14));
		
		System.out.println(abs(-3.5));
	}
}
</span></span></span>


  
(了解)可变参数
 变参数概述
  定义方法的时候不知道该定义多少个参数
 格式
  修饰符 返回值类型 方法名(数据类型…  变量名){}
 注意:
  这里的变量其实是一个数组
  如果一个方法有可变参数,并且有多个参数,
  那么,可变参数肯定是最后一个,并且一个方法中只能有一个可变参数


 

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_02_Args;

import java.util.Arrays;
import java.util.List;

/*
 * Arrays数组工具类中方法
 * 		public static <T> List<T> asList(T... a) 可以把多个参数中的数据,存储到List集合中
 * 
 * 		用法:
 * 		List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");	
 */
public class AsListDemo {
	public static void main(String[] args) {
		//这种用法常见
		List<String> list = Arrays.asList("Java", "Hello","JavaEE");
		System.out.println(list);
		
		//不常见
		String[] arr = {"aaa","bbb","ccc"};
	 	List<String> list2 =  Arrays.asList(arr);
	 	System.out.println(list2);
	}
}
</span></span></span>


  
Set:一个不包含重复元素的集合

HashSet:
 底层: 哈希表结构
 特点:
  不包含重复元素
  无序(元素的存与取的顺序不一致)
  线程不同步--不安全--效率高
 HashSet如何保证元素唯一性:
  重写 hashCode()方法 与 equals()方法

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_05_HashSet;

public class Person {
	private String name;
	private int age;
	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Person(String name, int age) {
		super();
		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;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	/*
	@Override
	public int hashCode() {
		return 0;
	}
	*/
	
	@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;
		Person other = (Person) 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;
	}
	
	
	
	
}
</span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><pre class="java" name="code">package cn.itcast_05_HashSet;

import java.util.HashSet;

/*
 * 案例: 使用HashSet集合存储自定义对象 并遍历
 * 
 * 通过查找源代码得知: HashSet集合中的add方法,底层会调用 hashCode() 与 equals()方法
 * 
 * 由于 String类中 覆盖了Object类中的hashCode() 与 equals()方法 ,所以可以保证元素的唯一
 * 
 * 我们可以通过重写 Object类中的hashCode() 与 equals()方法, 来保证HashSet集合中元素的唯一性
 * 		注意: 自定义类Person 中, 重写 hashCode() 与 equals()方法
 * 
 */
public class HashSetDemo2 {
	public static void main(String[] args) {
		//创建HashSet集合
		HashSet<Person> set = new HashSet<Person>();
		//创建Person元素对象
		Person p1 = new Person("周瑜", 28);
		Person p2 = new Person("诸葛亮", 30);
		Person p3 = new Person("郭嘉", 33);
		Person p4 = new Person("周瑜", 28);
		//添加到集合
		set.add(p1);	
		set.add(p2);	
		set.add(p3);	
		set.add(p4);	
		//遍历
		for (Person p : set) {
			System.out.println(p.getName() + "--" +p.getAge());
		}
	}
}
</span></span></span>

 

 

LinkedHashSet: 底层:哈希表结构 + 链表结构 特点:   不包含重复元素  由链表保证元素有序  由哈希表保证元素唯一  线程不同步--不安全--效率高

 

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_07_LinkedHashSet;

import java.util.LinkedHashSet;

/*
 * LinkedHashSet:
 * 		它是HashSet的子类
 * 		有序(元素存与取顺序一致)
 * 		底层存储: 哈希表结构  加上 链表结构
 * 		通过哈希表结构 保证LinkedHashSet元素唯一
 * 		通过 链表结构 保证元素有序
 * 		线程不同步--不安全-- 效率高
 */
public class LinkedHashSetDemo {
	public static void main(String[] args) {
		//创建集合对象
		LinkedHashSet<String> set = new LinkedHashSet<String>();
		//添加元素
		set.add("大湿兄");
		set.add("二师兄");
		set.add("小师妹");
		set.add("小师妹");
		//遍历
		for (String s : set) {
			System.out.println(s);
		}
	}
}</span></span></span>


 
(了解)TreeSet:
 底层:二叉树结构(红黑树结构)
 线程不同步--不安全--效率高
 TreeSet是如何保证元素的排序和唯一性的:
  1: 元素对应的类,实现自然排序接口[Comparable],重写compareTo(obj1)方法
  2: 或创建TreeSet集合对象时,实现比较器接口[Comparator], 重写compare(obj1, obj2)方法
 

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_08_TreeSet;

import java.util.TreeSet;

/*
 * TreeSet:
 * 		底层结果:二叉树结构
 * 		保证元素的唯一与元素进行排序
 * 		TreeSet集合对元素的排序提供两种方式
 * 			a: 自然排序 接口   Comparable<T>
 * 			b: 比较器排序 接口 Comparator<T>
 * 
 * 		通过compareTo()方法为0,来保证元素的唯一性
 * 		通过compareTo()方法不为0,来进行大小排序
 * 
 * 用TreeSet存储Integer类型数据进行排序和唯一。
		20,18,23,22,17,24,19,18,24
 */
public class TreeSetDemo {
	public static void main(String[] args) {
		//创建TreeSet集合对象
		TreeSet<Integer> ts = new TreeSet<Integer>();
		//添加Integer元素到集合
		ts.add(20);
		ts.add(18);
		ts.add(23);
		ts.add(22);
		ts.add(17);
		ts.add(24);
		ts.add(19);
		ts.add(18);
		ts.add(24);
		
		//TreeMap
		//遍历
		//for (Integer in : ts) {
		for (int in : ts) {
			System.out.println(in);
		}</span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">         }</span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">}</span></span></span>

 


 

<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_08_TreeSet;

//实现自然排序接口 Comparable, 重写 compareTo()方法
public class Person implements Comparable<Person> {
	private String name;
	private int age;

	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Person(String name, int age) {
		super();
		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;
	}

	//重写自然比较方法
	@Override
	public int compareTo(Person p) {
		//return 0;
		//return -1;
		//return 1;
		
		//采用年龄进行比较
		//this -- 代表着集合中的每一个对象
		//Person p -- 代表着要参与比较的对象
		//return this.getAge() - p.getAge();
		//先判断年龄
		int num = this.getAge() - p.getAge();
		//再判断姓名
		int result= (num == 0) ?( this.getName().compareTo(p.getName()) ): num;
		return result;
	}

}
</span></span></span>
<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_08_TreeSet;

import java.util.TreeSet;

/*
 * 案例: 使用TreeSet集合存储自定义对象,并遍历 
 * 
 * 分析:
 * 	1: 定义自定义类 Person
 * 		?? 没有重写 HashCode 和 equals方法
 *      答: 当前集合是TreeSet集合,底层使用的是二叉树结构,所以不用重写 HashCode 和 equals方法
 * 
 *  2:创建集合对象
 *  3:创建元素对象
 *  4:添加元素到集合
 *  5:遍历
 *  
 *  java.lang.ClassCastException: cn.itcast_08_TreeSet.Person cannot be cast to java.lang.Comparable
 *  
 *  public interface Comparable<T>
 *  	此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
 *  	
 *  	方法:
 *  	int compareTo(T o)
 *  		比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
 *  			
 *  			字符串1.compareTo (字符串2) 小于0
 *  				字符串1小  ,  字符串2大
 *  			
 *  			字符串1.compareTo (字符串2) 等于0
 *  				字符串1和字符串2一样
 *  
 *  			字符串1.compareTo (字符串2) 大于0
 *  				字符串1大  ,  字符串2小
 *   

 */
public class TreeSetDemo2 {
	public static void main(String[] args) {
		//创建集合对象
		TreeSet<Person> ts = new TreeSet<Person>();
		//3:创建元素对象
		Person p1 = new Person("d大师兄",28);
		Person p2 = new Person("d大师姐",18);
		Person p3 = new Person("x小师姐",18);
		Person p4 = new Person("x小师姐",18);
		//4:添加元素到集合
		ts.add(p1);
		ts.add(p2);
		ts.add(p3);
		ts.add(p4);
		//5:遍历
		for (Person p : ts) {
			System.out.println(p.getName() +"--"+ p.getAge());
		}
		
	}
}
</span></span></span>


<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_10_TreeSet_Test;

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

/*
 * TreeSet集合存储自定义对象并遍历
		如果对象的成员变量值相同即为同一个对象
		按照年龄进行从小到大进行排序
		
	完成排序和元素的唯一: 有两个方式
		1: 自然排序接口  Comparable, 实现 compareTo(o1) 方法
		2: 比较器接口    Comparator, 实现 compare(o1, o2)方法//推荐
	
 */
public class TreeSetTest {
	public static void main(String[] args) {
		//1: 自然排序接口  Comparable, 实现 compareTo(o1) 方法
		//创建集合对象
		//TreeSet<Person> ts = new TreeSet<Person>();
		
		//2: 比较器接口    Comparator, 实现 compare(o1, o2)方法
		TreeSet<Person> ts = new TreeSet<Person>(new Comparator<Person>() {

			@Override
			public int compare(Person p1, Person p2) {
				System.out.println("12345");
				
				
				//年龄
				int num = p1.getAge() - p2.getAge();
				//名字
				int result = (num == 0) ? (p1.getName().compareTo(p2.getName())) : num ;
				return result;
			}
		});
				
		//添加元素到集合
		ts.add(new Person("z张三", 18));
		ts.add(new Person("w王五", 18));
		ts.add(new Person("z赵六", 28));
		ts.add(new Person("z赵六", 28));
		ts.add(new Person("z赵六", 28));
		
		//TreeMap
		
		//遍历
		for (Person p : ts) {
			System.out.println(p.getName() + "--" + p.getAge());
		}
	}
}
</span></span></span>


 

 

 
 Collection 集合  与 Map集合的区别?
   Collection:
   单个元素:光棍
     Collection中的Set集合中,元素唯一

  Map:
    成对元素:夫妻,通常叫做 键值对
     Map集合中的键唯一, 值可以重复
    

Map :
 存储的是成对出现的元素
 
 特点:
  有键与值 组成是双列集合
  键唯一, 值可以重复
  Map集合的数据结构值针对键有效,跟值无关
 
 方法:
  V put(K key,V value) 添加键值对元素到集合
  V remove(Object key) 根据指定的键,在集合中删除对应的键值对元素,返回键对应的值
  void clear() 清空集合
  boolean containsKey(Object key) 判断集合中是否包含给定的键
  boolean containsValue(Object value) 判断集合中是否包含给定的值
  boolean isEmpty() 判断集合是否为空
  int size() 获取集合中键值对元素的个数
  V get(Object key) 根据给定的键,获取对应的值
  Set<K> keySet() 获取集合中所有的键
  Collection<V> values() 获取集合中所有的值
  Set<Map.Entry<K,V>> entrySet() 获取集合中所有的键值对元素对象
 
 Map集合的遍历方式
  方式1:根据键找值
   获取所有键的集合
   遍历键的集合,获取到每一个键
   根据键找值

<span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_02_Map_print;

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

/*
 * 通过Map 存储 多个String类型的键值对元素,并遍历
 * 		键String, 值 String
 * 
 * 	遍历方式:
 * 		1: 键找值     通过指定的键,获取对应的值
 * 			//a: 获取到Map集合中所有的键的Set集合
			//b: 遍历键的集合,得到每一个键
			//c: 通过当前的键,获取对应的值
 * 			
 */
public class MapDemo {
	public static void main(String[] args) {
		//创建Map集合
		Map<String,String> map = new HashMap<String,String>();
		//添加元素
		map.put("谢霆锋", "张柏芝");
		map.put("李亚鹏", "王菲");
		map.put("汪峰", "章子怡");
		//遍历
		//a: 获取到Map集合中所有的键的Set集合
		Set<String> keys = map.keySet();
		//b: 遍历键的集合,得到每一个键
		for (String key : keys) {
			//c: 通过当前的键,获取对应的值
			String value = map.get(key);	
			//显示
			System.out.println( key +"--" + value );
		}
		
	}
}
</span></span>


 


  方式2:根据键值对对象找键和值
   获取所有键值对对象的集合
   遍历键值对对象的集合,获取到每一个键值对对象
   根据键值对对象找键和值

 

<span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_02_Map_print;

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

/*
 *  通过Map 存储 多个String类型的键值对元素,并遍历
 * 		键String, 值 String
 * 
 * 	遍历方式:
 * 		1: 键找值
 * 
 * 		2: 通过键值对元素对象,找对应的键, 找对应的值     结婚证方式
 * 			//a:获取所有键值对元素的Set集合
			//b:遍历Set集合,得到每一个键值对元素对象
			//c:通过键值对元素对象,获取键,获取值
 * 
 * 	方法:
 * 		Set<Map.Entry<K,V>> entrySet(): 获得一个包含多个键值对元素的Set集合 
 * 
 * 	 Map.Entry<K,V>  等价    结婚证<男的,女的>
 *   class 结婚证<男的,女的> {
 *   	private 男的 man;
 *   	private 女的 woman;
 *   
 *   	public 男的   getMan(){
 *   		return man;
 *   	}
 *   
 *   	public 女的  getWoman(){
 *   		return woman;
 *   	}
 *   } 
 *   
 *   Set<Map.Entry<K,V>> entrySet = map.entrySet();
 *   Set<   结婚证<男的,女的>> entrySet = map.entrySet();	
 * 		
 */
public class MapDemo2 {
	public static void main(String[] args) {
		//创建Map集合
		Map<String,String> map = new HashMap<String,String>();
		//添加元素
		map.put("谢霆锋", "张柏芝");
		map.put("李亚鹏", "王菲");
		map.put("汪峰", "章子怡");
		//遍历
		//a:获取所有键值对元素的Set集合
		Set<Map.Entry<String,String>> entrySet = map.entrySet();
		//b:遍历Set集合,得到每一个键值对元素对象
		for ( Map.Entry<String,String> entry : entrySet) {
			//c:通过键值对元素对象,获取键,获取值
			String key = entry.getKey();//获取键
			String value = entry.getValue();//获取值
			
			System.out.println(key +"--"+ value);
		}
	}
}
</span></span>


 

HashMap:
 底层: 哈希表结构


 

<span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_03_HashMap;

public class Student {
	private String name;
	private int age;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		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;
	}
	@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;
		Person other = (Person) 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;
	}
	
	
}
</span></span>
<span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_03_HashMap;

import java.util.HashMap;
import java.util.Set;

/*
 * HashMap集合键是String值是Student的案例
 * 		键是String
 * 		值是Student
 * 
 * 底层的结构  只针对 键 有效, 与值无关
 */
public class HashMapDemo2 {
	public static void main(String[] args) {
		//创建集合对象
		HashMap<String,Student> map = new HashMap<String,Student>();
		//添加元素
		Student s1 = new Student("周瑜", 28);
		Student s2 = new Student("小乔", 18);
		Student s3 = new Student("大乔", 19);
		
		map.put("itcast001", s1);
		map.put("itcast002", s2);
		map.put("itcast003", s3);
		map.put("itcast004", s1);
		
		//遍历
		//方式1 键找值
		Set<String> keys = map.keySet();
		//获取到每一个键
		for (String key : keys) {
			//通过当前的key, 获取对应的值 Student
			Student s = map.get(key);
			System.out.println(key +"---" + s.getName() +"---"+ s.getAge());
		}
		
	}
}
</span></span>

 

<span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_03_HashMap;

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

/*
 * HashMap:
 * 		底层: 哈希表结构
 * 		存储允许使用 null 值和 null 键
 * 		线程不同步-- 效率高-- 不安全
 * 		
 * 		Map集合中的键要求保证唯一, 那么,HashMap集合中,如何保证 键 的唯一呢?
 * 			重写 hashCode() 与 equals()方法
 * 
 * 		注意: 这里面的唯一指的是 键唯一, 针对键有效,  与 值 无关
 * 
 * 使用HashMap存储字符串 并遍历
 * 		键 String  值  String
 */
public class HashMapDemo {
	public static void main(String[] args) {
		//创建HashMap集合
		HashMap<String,String> hm = new HashMap<String,String>();
		
		//添加键值对元素 到集合
		hm.put("谢霆锋", "张柏芝");
		hm.put("李亚鹏", "王菲");
		hm.put("汪峰", "章子怡");
		
		//遍历方式1  键找值
		//a: 获取到Map集合中所有的键
		Set<String> keys = hm.keySet();
		//b: 获取到每一个键
		for (String key : keys) {
			//c: 通过键,找对应的值
			String value = hm.get(key);
			System.out.println(key+"---"+value);
		}
		
		//遍历方式2 键值对  找键 找值
		//a: 获取所有的键值对元素对象
		Set<Entry<String, String>> entrySet = hm.entrySet();
		//b: 获取到每一个键值对元素对象
		for (Entry<String, String> entry: entrySet) {
			//c: 通过当前的键值对元素对象, 获取键,获取值
			String key = entry.getKey();// 获取键
			String value = entry.getValue(); //获取值
			System.out.println(key+"---"+value);
		}
	}
}
</span></span>


 
TreeMap:
 底层: 二叉树结构

<span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_05_TreeMap;

public class Student {
	private String name;
	private int age;
	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Student(String name, int age) {
		super();
		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;
	}
}
</span></span>


 


package cn.itcast_05_TreeMap;

public class Student {
 private String name;
 private int age;
 public Student() {
  super();
  // TODO Auto-generated constructor stub
 }
 public Student(String name, int age) {
  super();
  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;
 }
}

<span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_05_TreeMap;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeMap;

/*
 * TreeMap集合键是Student值是String的案例
 * 		键是Student
 * 		值是String
 * 
 * 注意了, 键是自定义类对象, 需要实现自然排序接口,或者比较器接口(推荐)
 */
public class TreeMapDemo2 {
	public static void main(String[] args) {
		//创建TreeMap集合对象,  同时实现比较器
		TreeMap<Student,String> map = new TreeMap<Student,String>(new Comparator<Student>() {
				
			@Override
			public int compare(Student s1, Student s2) {
				//名字
				int num = s1.getName().compareTo(s2.getName());
				//年龄
				int result = (num==0) ? (s1.getAge() - s2.getAge()) : num ;
				return result;
			}
		});
		
		//添加元素到集合
		Student s1 = new Student("z周瑜", 28);
		Student s2 = new Student("x小乔", 18);
		Student s3 = new Student("d大乔", 19);
		
		map.put(s1, "itcast001");
		map.put(s2, "itcast002");
		map.put(s3, "itcast003");
		map.put(s1, "itcast110");
		
		//遍历 
		Set<Student> keys = map.keySet();
		//获取到每一个键
		for (Student key : keys) {
			//键 找 值
			String value = map.get(key);
			System.out.println(value +"---"+key.getName()+"---"+key.getAge() );
		}
	}
}
</span></span>


   
LinkedHashMap:
 底层: 哈希表结构 + 链表结构   


 

<span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_04_LinkedHashMap;

import java.util.LinkedHashMap;
import java.util.Set;

/*
 * LinkedHashMap<K,V>:
 * 		底层: 哈希表 + 链表
 * 		有序(元素的存与取顺序一致)
 *		线程不同步 -- 效率高-- 不安全 
 */
public class LinkedHashMapDemo {
	public static void main(String[] args) {
		//创建集合对象
		LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();
		//添加元素到集合
		map.put("谢霆锋", "张柏芝");
		map.put("李亚鹏", "王菲");
		map.put("汪峰", "章子怡");
		
		//遍历   键找值
		Set<String> keys = map.keySet();
		for (String key : keys) {
			//键 找 值
			String value = map.get(key);
			System.out.println(key +"---"+value);
		}
 		
	}
}
</span></span>


   
Collections:
 集合工具类 
 public static <T> void sort(List<T> list) 排序
 public static <T> int binarySearch(List<?> list,T key) 二分查找
 public static <T> T max(Collection<?> coll) 最大值
 public static void reverse(List<?> list) 反转
 public static void shuffle(List<?> list) 随机打乱
 public static <T> boolean replaceAll(List<T> list, T oldVal, T newVal) 替换 


 

<span style="font-size:18px;"><span style="font-size:18px;">package cn.itcast_07_Collections;

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

/*
 * 	Collections类概述
		针对集合操作 的工具类
	Collections成员方法
		public static <T> void sort(List<T> list) 排序
		public static <T> int binarySearch(List<?> list,T key) 二分查找
		public static <T> T max(Collection<?> coll) 最大值
		public static void reverse(List<?> list) 反转
		public static void shuffle(List<?> list) 随机打乱
		public static <T> boolean replaceAll(List<T> list, T oldVal, T newVal) 替换
			
 */
public class CollectionsDemo {
	public static void main(String[] args) {
		List<Integer> list = new ArrayList<Integer>();
		list.add(12);
		list.add(8);
		list.add(11);
		list.add(11);
		list.add(11);
		list.add(11);
		list.add(7);
		list.add(23);
		list.add(54);
		list.add(22);
		list.add(1);
		list.add(79);
		
		System.out.println(list);
		
		System.out.println("排序后:");
		Collections.sort(list);
		System.out.println(list);//[1, 7, 8, 11, 12, 22, 23, 54, 79]
		
		System.out.println("二分查找  12 索引:"+ Collections.binarySearch(list, 12));
		System.out.println("最大值:" + Collections.max(list));
		
		System.out.println("反转后");
		Collections.reverse(list);
		System.out.println(list);
		
		System.out.println("随机打乱后");
		Collections.shuffle(list);
		System.out.println(list);
		
		System.out.println("替换后:");
		System.out.println(Collections.replaceAll(list, 11, 111));
		System.out.println(list);
	}
}
</span></span>


   

 HashMap和Hashtable的区别?
  HashMap
   线程不同步-- 不安全--效率高
   可以使用null键  null值
  Hashtable
   线程同步 -- 安全 -- 效率低
   不能使用null键  null值

 


<span style="font-size:18px;">package cn.itcast_06_Map_Test;

import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

/*
 * "aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)
 * 
 * 分析:
 * 		通过结果可以看出 字母与次数之间有对应关系, 我们可以采用Map集合
 * 		又由于结果是一个有序的结果,我们最终决定采用 TreeMap集合
 * 		a(5)
 * 		TreeMap<Character, Integer> 
 * 					a		1++ ++ 
 * 					b       1
 * 
 * 		1: 定义一个字符串   "aababcabcdabcde"
 * 		2:定义一个集合  TreeMap<Character, Integer> 用来存储字母与次数
 * 		3:遍历字符串,得到每一个字母
 * 		4:判断当前字母在集合中是否存在
 * 			存在:
 * 				把当前字母 在集合中存储的次数获取出来, 次数加1后,再存进去
 * 			不存在:
 * 				把当前字母  与 次数1 存进去	 	
 * 		5: 组装结果字符串  a(5)b(4)c(3)d(2)e(1)
 * 			通过遍历Map集合得到每一个键与值 ,然后拼装
 */
public class TreeMapDemo {
	public static void main(String[] args) {
		//1: 定义一个字符串   "aababcabcdabcde"
		String str = "aababcabcdabcde";
		
		//2:定义一个集合  TreeMap<Character, Integer> 用来存储字母与次数
		TreeMap<Character, Integer> map = new TreeMap<Character, Integer>(); // 自然排序
		
		//3:遍历字符串,得到每一个字母
		for (int i =0; i< str.length(); i++) {
			//得到每一个字母
			char ch = str.charAt(i);
			//4:判断当前字母在集合中是否存在
			if (map.containsKey(ch)) {
				//把当前字母 在集合中存储的次数获取出来, 次数加1后,再存进去
				int count = map.get(ch);
				count++;
				map.put(ch, count);
				
			} else {
				//把当前字母  与 次数1 存进去	
				map.put(ch, 1);
			}
		}
		
		//System.out.println(map);
		//5: 组装结果字符串  a(5)b(4)c(3)d(2)e(1)
		//通过遍历Map集合得到每一个键与值 ,然后拼装
		StringBuilder sb = new StringBuilder();
		
		//方式2 键值对 找键 找值
		Set<Entry<Character, Integer>> entrySet = map.entrySet();
		//得到每一个键值对元素
		for (Entry<Character, Integer> entry : entrySet) {
			//找键  --- 字母
			Character c = entry.getKey();
			//找值  --- 次数
			Integer n = entry.getValue();
			sb.append(c).append("(").append(n).append(")");//a(5)
		}
		//打印结果
		System.out.println(sb.toString());
		
	}
}
</span>

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值