我的java笔记(集合)

数据结构:按照某种方式组织数据的格式.

 栈:先进后出.
 队列:先进先出.
 数组:存入和取出可以看成是无序的,但是如果顺序获取的话,它的存入和取出是一一对应的.
  查询速度快,增删速度慢.
 链表:链表数据结构是由一个个存储单元上非连续的节点组成.每个节点又由数据域和指针域组成.
  查询速度慢,增删效率高.

一: 
对象多了用集合存,数据多了用对象存.
集合是用于存储对象的一个工具,所以,也被称为容器.
数组和集合同是容器,不同点是:
 1:数组是固定长度的,集合是可变长度的.
 2:数组存储同一种类型,集合可以存储不同类型对象.
 3:数组可以存储对象类型,也可以存储基本数据类型.
   集合只能存储对象类型  .
相同点:都是容器,都可以存储多个数据.

数据结构:按照某种结构存储数据.
各种容器由于数据结构不同,所以,存储数据的方式不一样.

Collection:List-->ArrayList,LinkedList,Vector
    Set--->HashSet,TreeSet

Collection:
1:存储数据:
 boolean add(Object obj);增加一个元素.
 boolean addAll(Collection c):增加一个集合的元素
2:删除数据:
 void clear();删除集合中的所有元素.
 boolean remove(Object o);移出单个元素.
 boolean removeAll(Collection c);移出一个集合中和另一个集合相同的元素.
4:获取数据:
 Iterator iterator();获取数据的迭代器
5:判断:
 boolean contains(Object o):判断集合中是否包含某个元素.
  contains底层是调用的equals方法.会自动调用.如果要按自己的需求判断,要覆写equals方法.
 boolean containsAll(Collection c);判断集合是否包含某个小集合.
 boolean isEmpty();判断集合是否为空.
6:长度:
 int size();
7:交集:
 boolean retainAll(Collection c):判断是否有交集,并把交集元素赋值给调用对象.
  只要调用对象变化就返回true.A和B集合中的交集赋值给A,B不变.并且只要A集合中的元素有改变,那么,结果就是true,否则是false.
  例如:如果A和B中没有相同的元素,那么会把空赋值给A集合,并返回true.
       如果A和B中的元素相同,那么,A中的元素不变,返回值为false.
8:转换成数组:
 Object[] toArray();集合转换成数组. 

二:什么是迭代器?
  其实迭代器是集合的取出元素的方式.
  每一个容器的数据结构不同,所以取出元素的方式也不一样,这些取出方式被定义为内部类,但是他们都有
 共性内容就是判断和取出,那么就可以将这些共性抽取.这些内部类都符合一个规则,该规则就是Iterator(内部类),
 Iterator提供了一个对外方法:iterator();
  迭代器返回的都是Object类型.
 Iterator it=a1.iterator();其实返回的是接口的子类对象.

Iterator接口中的方法:
 boolean hasNext():如果仍有元素可迭代则返回true;
 Object next():获取元素.
 
例:
import java.util.ArrayList;
import java.util.Iterator;

public class Interator迭代器 {
 public static void main(String args[]){
  baseDemo();
 }
 public static void baseDemo(){
  ArrayList a1=new ArrayList();
  a1.add("java-1");
  a1.add("java-2");
  a1.add("java-3");
  a1.add("java-4");
  
  //此种方法在结束后迭代器不能及时回收
  /*Iterator it=a1.iterator();//获取迭代器,用于取出集合中的元素.
  while(it.hasNext()){    //判断集合中是否还有元素,如果有则返回true,
   
   sop(it.next());      //it.next()方法是取出元素.
  }*/
  for(Iterator it=a1.iterator();it.hasNext();){   //工作中应该用这中,如果迭代器用完可以及时回收
   String s=(String)it.next();    //需要强制类型转换,因为next()返回的是Object类型.
   sop(s);
  }
 }
 public static void sop(Object obj){
  System.out.println(obj);
 }
}

将自定义对象作为元素存到ArrayList集合中,并去除重复元素.
 比如:存人对象,同姓名,同年龄,视为同一个人.为重复元素.
 迭代器中返回的都是Object类型,需要强制类型转换.
 例:String s=(String)it.next();    //需要强制类型转换,因为next()返回的是Object类型.
 List 集合中判断元素是否相同用的是equals方法
 remove和contains方法底层都是默认调用equals方法.


三:
List:元素是有序的(存入和取出顺序一样),元素可以重复.因为该集合体系有脚标索引
Set:元素无序,元素不可以重复.
LIst集合特有的方法:凡是可以操作角标的方法都是该体系特有的方法.
1:增加元素:add(element);向列表尾部添加指定的元素.
   add(index,element);在指定位置插入指定元素.
   addAll(index,Collection); 将Collection中的所有元素插入到列表中的指定位置.
 2:删除元素:Object remove(index);移出指定位置的元素.
 
**3:改:set(index,element);把index位置上的元素用element替换
 
**4:获取元素:
 get(int index);  返回指定位置上的元素
 int indexof(Object obj);获取元素的位置
截取字符串:
 List subList(begin,end);从List中取得一个小List.
     大列表和子列表在内存中是有关联的:如果,你删除大列表中的某个元素,而这个元素
     已经在子列表中获取过了,就会报ConcurrentModificationException异常.

     在使用迭代器的时候最好不要在迭代器中删除元素,迭代器是根据集合来的,所以,你的修改回对集合产生影响.但是这样不好,最好在集合中操作.
 


** 5:listIterator():迭代元素
   List集合特有的迭代器.ListIterator是Iterator的子接口.
   在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生并发修改异常(ConcurrentModificationException).
 所以,在迭代时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作.
 如果想要其他的操作如添加,修改等,就需要使用其子接口ListIterator,该接口只能通过ListIterator集合的listIterator()方法获取.
    boolean hasPrevious()如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。(从后往前判断)
    E previous() 返回列表中的前一个元素(从后往前取)。

6:如何从List集合遍历元素?
 (1):直接输出:System.out.println(list);
 (2):迭代器Iterator it=list.iterator();
 (3):for(int i=0;i<list.size(0;i++){
  String s=(String)list.get(i);
  System.out.println(s);
     }
 (4):ListIterator lit=list.listIterator();ListIterator是List特有的迭代器,提供了更多的方法操作.

四:
 List下常见的三个子类对象:ArrayList,LinkedList,Vector
  ArrayList:线程不是同步的,底层的数据结构使用的是数组结构.特点:查询速度很快,但是增删速度稍慢.
  LinkedList:线程不同步,底层的数据结构是使用的链表数据结构.特点:查询速度慢,但增删速度快.
  Vector:线程同步,底层是数组数据结构,功能和ArrayList相像,但是没有ArrayList效率高.被ArrayList替代了.
  枚举是Vector特有的取出方式.
   ArrayList是可变长度数组,初始容量为10,以50%增长.
   Vector也是可变长度数组,初始容量也为10,以100%增长.
1:ArrayList没有特殊的方法,和父接口List中的方法一致,所以我们就直接使用.

2:Vector特有功能:
 addElement(E) 增加元素
 Object ElementAt(int index) 获取index处的元素
 Enumeration elements():获取元素的枚举.

3:LinkedList的特有操作:
   void addFirst(E e)将指定元素插入此列表的开头
   void addLast(E e)将指定元素插入此列表的开头
   getFirst()返回列表的第一个元素
   getLast()返回列表的最后一个元素
   获取元素,但是不删除元素,如果集合中没有元素,会出现NoSuchElementException异常
   
   removeFirst()删除第一个元素
   removeLast()删除最后一个元素.
   获取元素,但是元素被删除,如果集合中没有元素,会出现NoSuchElementException异常
    
  在JDK1.6出现了替代方法:
   offerFirst(E e);
   offerLast(E e);
   在元素的开头或结尾插入指定的元素.
   
   peekFirst();
   peekLast();
   获取开头或结尾元素,如果集合中没有元素,会返回null
   
   pollFirst();
   pollLast();
   获取元素,但是元素被删除,如果集合中没有元素,会返回null 

Set
五:Set集合和Collection的功能是一致的.没有新功能.
   Set集合元素是无序(存入和取出的顺序不一定一致),元素不可以重复.
   只能用迭代器取出元素,元素无序的是因为根据元素的哈希值来存放元素的.
   Set最常用的子类是HashSet和TreeSet.
 
1:HashSet:底层数据结构是哈希表.存储的时候元素无序,但是集合本身内部
 有一定规律的.存取速度快.
 因为它是无序的所以不能依靠脚标获取元素.
 一般使用HashSet的时候会重写hashCode方法和equals方法.

2:HashSet是如何保证元素的唯一性的呢?
 由于HashSet地层数据结构是哈希表,它会根据哈希值进行存储.这个时候,我们如果要实现自己的需求,判断元素是否
 唯一,就必须重写hashCode方法,并且重写equals方法.
   如果元素的HashCode值相同,才会判断equals是否为true.
   如果元素的HashCode值不同,就不调用equals.
  这个结构叫做哈希表中的桶结构,当对象的哈希值相同的时候,它们是放在同一个地址处的,为了区分,它会自动根据equals进行判断.
  所以在哈希值相同的情况下,我们只要重写equals犯法,判断各个对象的属性是否相同即可.
  注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法.

3:LinkedHashSet保证集合元素的有序唯一.
 有序:读取和存储的顺序一致.
 唯一:元素不能重复.
 Linked用于保证元素的顺序有序.
 Hash用于保证元素的唯一性.


六:TreeSet
1:HashSet:数据结构是哈希表,线程不同步.
   保证元素唯一性的原理:判断元素的hashCode值是否相同.如果相同,还会继续判断元素的equals方法,是否为true.

 TreeSet:底层数据结构是二叉树,不可以重复元素,线程是非同步的.默认顺序是根据自然(字典)排序的.
   可以对Set集合中的元素进行排序.
 存储字符串之所以能够保证排序,是因为字符串类实现了Comparable接口。


2:TreeSet如何保证元素的有序的呢?
 (1):TreeSet元素需要实现Comparable接口中的compareTo方法,让元素自身具备比较性.这种方式也称为元素的自然排序,或者叫默认顺序.
 (2):当元素自身不具备比较性时,或者具备的比较性不是所需要的.这时就需要让集合自身具备比较性,即在集合初始化时(构造函数),
  实现Comparetor接口中的compare方法.(自定义比较器)
 就有了比较方式.
例:
public class HashSetDemo_保证元素的唯一性 {
 public static void main(String[] args) {
  HashSet<Per> hs=new HashSet<Per>();
  
  hs.add(new Per("lisi01",25));
  hs.add(new Per("lisi02",21));      //
  hs.add(new Per("lisi03",22));      //
  hs.add(new Per("lisi01",25));     //
  hs.add(new Per("lisi05",22));
  hs.add(new Per("lisi02",21));      //
  hs.add(new Per("lisi06",22)); 
  hs.add(new Per("lisi03",20));     //
  
  for(Iterator<Per> it=hs.iterator();it.hasNext();){
   Per p=it.next();
   System.out.println(p.getName()+"....."+p.getAge());
  }
 }
}
class Per{
 private String name;
 private int age;
 public Per(){}
 public Per(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(){              //覆写hashCode()方法.
  return this.name.hashCode()+this.age*19;      //this.age*19是为了防止意外出错:例如:hashCode=20,age=30;和hashCode=10,age=40;
 }
 public boolean equals(Object obj){   //覆写equals()方法.
  if(this==obj){
   return true;
  }
  if(!(obj instanceof Per)){
   return false;
  }
  Per p=(Per)obj;
  return this.getName().equals(p.getName())&&this.getAge()==p.getAge();
 }
}

 


3:
TreeSet的第一种排序方式:让元素本身具备比较性,让Person类实现Comparable接口,覆写compareTo()方法.
  Comparable接口:
  此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
  此接口只有一个方法:
  int compareTo(T t) 比较此对象与指定对象的顺序。
   返回:负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。
  
   记住:排序时,当主要条件相同时,一定要判断一下次要条件.
例:
public class TreeSet_保证集合元素有序的方法一 {
 public static void main(String[] args) {
  TreeSet<Stu> tr=new TreeSet<Stu>();
  
  tr.add(new Stu("z三",23));
  tr.add(new Stu("李四",20));
  tr.add(new Stu("王五",28));
  tr.add(new Stu("赵六",21));
  tr.add(new Stu("qianqi",40));
  tr.add(new Stu("李四",20));
  tr.add(new Stu("w五",23));
  
  for(Iterator<Stu> it=tr.iterator();it.hasNext();){
   Stu s=it.next();
   System.out.println(s.getName()+"....."+s.getAge());
  }
 }
}
class Stu implements Comparable<Stu>{
 private String name;
 private int age;
 public Stu(){}
 public Stu(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 compareTo(Stu s) {     //重写compareTo方法;
  //判断主要条件
  int num=this.age-s.age;      //按年龄大小排序
  //判断次要条件
  return num==0?this.name.compareTo(s.name):num;   //如果主要条件相同,则判比较次要条件.
 }
}


4:
TreeSet的第二种排序方式:使用TreeSet带比较器的构造.
 当元素自身不具备比较性时,或具备的比较性不是所需要的,
  这时就需要集合自身具备比较性.这时就要集合初始化时就具备比较性.
  定义比较器,将比较器对象作为参数传递给TreeSet集合
  如果两种排序都存在时,以比较器为主.
 定义一个类实现Comparator接口,并覆写compare方法.如果return 0 则表示两个对象为同一对象.
  int compare(T o1, T o2)
           比较用来排序的两个参数。
  boolean equals(Object obj)
           指示某个其他对象是否“等于”此 Comparator。

例:
public class TreeSet_保证集合元素有序的方法二 {
 public static void main(String[] args) {
  //使用TreeSet的带比较器的构造
  TreeSet<People> tr = new TreeSet<People>(new ComparatorImp());  //将比较器作为参数传递到TreeSet中
  /*//使用匿名内部类
  TreeSet<People> tr=new TreeSet<People>(new Comparator<People>(){
   public int compare(People o1,People o2){
    int num1=o1.getName().length()-o2.getName().length();
    int num2=o1.getAge()-o2.getAge();
    
     int compareTo(String anotherString) 按字典顺序比较两个字符串。
    
    int num3=o1.getName().compareTo(o2.getName());
    return num1==0?(num2==0?num3:num2):num1;
    //如果名字的长度相同就按年龄排序,如果年龄相同就按名字的自然顺序排序.
   }
  });*/
  
  tr.add(new People("z三",23));
  tr.add(new People("李四",20));
  tr.add(new People("王五而热热",28));
  tr.add(new People("赵六而",21));
  tr.add(new People("qianqi",40));
  tr.add(new People("李四",20));
  tr.add(new People("w五",23));
  
  for(Iterator<People> it=tr.iterator();it.hasNext();){
   People s=it.next();
   System.out.println(s.getName()+"....."+s.getAge());
  }
 }
}
class People{
 private String name;
 private int age;
 public People(){}
 public People(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;
 }
}
class ComparatorImp implements Comparator<People>{       //定义一个比较器
 @Override
 public int compare(People o1, People o2) {
  int num1=o1.getName().length()-o2.getName().length();
  int num2=o1.getAge()-o2.getAge();
  /*
   int compareTo(String anotherString) 按字典顺序比较两个字符串。
   */
  int num3=o1.getName().compareTo(o2.getName());
  return num1==0?(num2==0?num3:num2):num1;
  //如果名字的长度相同就按年龄排序,如果年龄相同就按名字的自然顺序排序.
 }
}
//当添加第二个元素时,TreeSet集合会自动去调用比较器中的compare方法.

 

七:以后到底用哪个集合呢?
 1:如果元素唯一,就用Set.否则用List.
 2:如果元素唯一并且要排序用TreeSet,否则用HashSet.
 3:如果元素可重复,且考虑线程安全,用Vector.否则,用ArrayList或者LinkedList.
  如果要求,增删快,那么,考虑LinkedList.
  如果要求,查询快,那么,考虑ArrayList.
 4:当你什么都不清楚的时候,就使用ArrayList.

   Array:想到数组,就应该想到数据的索引.
   Link:想到链表,就应该想到增删快. 最好能想到addFrist.
   Hash:想到哈希表,就应该想到元素的hashCode和equals方法.
   Tree:想到二叉树


八:泛型
1:泛型:JDK1.5版本以后出现新特性,用于解决安全问题,是一个安全机制.
 好处:
 (1)将运行时期出现的问题ClassCastException,转移到了编译时期,
        方便于程序员解决问题,让运行事情问题减少,增加安全性.
 (2)避免了使用数据的时候强制转换的麻烦.

2:泛型格式:通过<>来定义要操作的"引用数据类型".<>是用来接收类型
 当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可.
3:什么时候使用泛型?:一般用于集合类中
 通常在集合框架中很常见,只要见到<>就要定义泛型
 当类中要操作的引用数据类型不确定的时候,定义泛型阿里完成扩展.
 早期没有泛型之前定义Object来完成扩展.
4:?通配符,也可以理解为占位符.
 ? extends E:可以接收E类型或者E的子类型.上限.
 ? super E:可以接收E类型或者E的父类型.下限.
5:泛型在类中的使用:
class Demo<T>{
 public void show(T t){}
}
6:泛型定义在方法中:
class Demo{
 public<T> void show(T t){
  System.out.println(bm);
 }
}
7:泛型定义在接口中
interface Inter<QQ>{
 public sbstract void show(QQ qq);
}
class InterImpl<QQ> implements Inter<QQ> {
 public void show(QQ qq) {
  System.out.println("show:" + qq);
 }

}
6:自定义泛型类:防止多态存在安全隐患.
例1:
 import java.util.*;
public class Fanxing {
 public static void main(String[] args) {
  TreeSet<String> ts=new TreeSet<String>(new MyComparator());
  
  ts.add("dfa");
  ts.add("fwoijf");
  ts.add("dsswo");
  ts.add("fdjow");
  ts.add("fwef");

  for(Iterator<String> it=ts.iterator();it.hasNext();){
   String s=it.next();
   System.out.println(s);
  }
 }
}
class MyComparator implements Comparator<String>   //默认的是Object类型
{
 public int compare(String o1,String o2){
  int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));    //把o1和o2调换则会反向输出.
  if(num==0){
   return o1.compareTo(o2) ; 
  }
  return num;
 }
}

例2:将泛型定义在类,和方法上
class Demo<QQ>
{
 public void show(QQ ss){
  System.out.println("show:"+ss);
 }
 
 //泛型加在方法上
 public <BM> void method(BM bm){
  System.out.println("method:"+bm);
 }
}

public class GenericDemo4 {
 public static void main(String[] args) {
  Demo<String> d = new Demo<String>();
  d.show("aa");
  
  Demo<Integer> d2 = new Demo<Integer>();
  d2.show(20);
  
  Demo<Float> d3 = new Demo<Float>();
  d3.show(20.5f);
  
  d3.method("aa");
  d3.method(20);
  d3.method(20.5f);
 }
}


九:Map接口:
 
 Map的体系结构:
  |--Hashtable
   底层是哈希表结构
   线程安全的,并且键和值不能为null。
  |--HashMap
   底层是哈希表结构
   线程不安全的,键和值可以为null。
   |--LinkedHashMap
    底层是链表和哈希表
    线程不安全
  |--TreeMap
   底层是二叉树
   线程不安全的

  1:Map接口和Collection接口的区别:
 Map是键值对的方式,是双列的方式
 Collection是单列的方式.

 (1): Map中一次存储是键值对。
      Collection中一次存储是单个元素。

 (2): Map的存储使用的put方法。
      Collection存储使用的是add方法。
 
 (3): Map的取出,是将Map转成Set,在使用迭代器取出。
      Collection取出,使用就是迭代器。
 
 (4): 如果对象很多,必须使用容器存储。
      如果元素存在着映射关系,可以优先考虑使用Map存储或者用数组,
      如果没有映射关系,可以使用Collection存储。

 
  2:
 Map<K,V>:K是存储的键,V是键对应的值.
  键是唯一的.
  3:Map的功能:
 (1):获取数据:
  Set<Map.Entry<K,V>> entrySet():返回键值对的Set视图.
  Object get(Object key):根据键得到值
  Set<K> keySet():返回键的Set集合.
   得到所有的键.
  Collection<V> values(); 返回的就是值的Collection集合.
   得到所有的值.
 (2):存储数据:
  Object put(K key,V value):存储元素
 (3):删除数据:
  clear():移出所有元素.
  Object remove(Object key):根据指定的键删除元素.
 (4):判断:
  boolean containsKey(Object key)如果此映射包含指定键的映射关系,则返回true.
  boolean containsValue(Object value)如果此映射将一个或多个键映射到指定值,则返回true.
  boolean isEmpty():判断是否为空.
 (5):int size():获取Map的键值对的个数.

  4:如何遍历Map:
 单独使用Map的键或值的集合的时候,可以分别使用:keySet和value方法
   
    真正意义上的遍历,有两种方式:
 第一种:
     思路:
  先获取键的集合.Set<K> keySet():返回键的Set集合.得到所有的键.
  遍历键的集合,获取到每一个键值.Collection<V> values(); 返回的就是值的Collection集合.
  根据每一个键值,调用Map的get方法,获取每一个键值对应的值
 
 第二种:
  Set<Map.Entry<K,V>> entrySet()
     思路:先获取键值对对象的集合.
   遍历这个对象的集合.
   根据遍历的每一个对象,获取键和值.  

 举例: 先获取夫妻的结婚证的集合.
  遍历这个集合,获取到每一张结婚证.
  按照结婚证上的名字获取每一个丈夫和妻子.
  
例:
public class MapDemo {
 public static void main(String[] args) {
  HashMap<String,Student> hmp=new HashMap<String,Student>();
  hmp.put("001", new Student("张三",29));
  hmp.put("004", new Student("赵六",23));
  hmp.put("003", new Student("网速",12));
  hmp.put("002", new Student("李四",30));
  hmp.put("005", new Student("钱起",56));
 
  //第一种方法:
  /*Set<String> keySets = hmp.keySet();
  Iterator<String> it3 = keySets.iterator();
  while(it3.hasNext()){
   String key = it3.next();
   Student value = hmp.get(key);
   System.out.println(key+"***"+value);
  }
  System.out.println("*************************");
  */

  //第二种方法:

  Set<Map.Entry<String,Student>> setmp=hmp.entrySet();
  
  for(Iterator<Map.Entry<String,Student>> it=setmp.iterator();it.hasNext();){
   Map.Entry<String,Student> mape=it.next();
   String s=mape.getKey();
   Student stu=mape.getValue();
   
   System.out.println(s+"..."+stu.getName()+"....."+stu.getAge());
  }
 }
}
class Student {
 private String name;
 private int age;
 public Student(){}
 public Student(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;
 }
}

5:HashMap
 基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用null值和null键
 此实现不是同步的
例:保证元素的唯一性:
public class HashMap_保证元素的唯一性 {
 public static void main(String[] args) {
  HashMap<String,Integer> hm=new HashMap<String,Integer>();
  
  hm.put("张三", 23);
  hm.put("李四", 24);
  hm.put("王五", 39);
  hm.put("朱丽叶", 19);
  hm.put("梁山泊", 23);
  hm.put("王五", 39);
  
  Set<String> set=hm.keySet();
  
  for(Iterator<String> it=set.iterator();it.hasNext();){
   String key=it.next();         //获取键
   Integer value=hm.get(key);     //获取值
   System.out.println(key+"....."+value);
  }
  
 }
}
class Stu {
 private String name;
 private int age;
 public Stu(){}
 public Stu(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 boolean equals(Object obj){       //覆写equals方法
  if(this==obj){
   return true;
  }
  if(!(obj instanceof Stu)){
   return false;
  }
  Stu s=(Stu)obj;
  return this.name.equals(s.name)&&this.age==s.age;
 }
 public int hashCode(){                   //覆写hashCode方法
  return this.name.hashCode()+this.age*17;
 }
}

例2:HashMap的嵌套:
/*
 传智播客:
  jc|基础班
   001   张三
   002   李四
  jy|就业班
   001   王五
   002   赵六
   
 分析:
 1:在大集合中嵌套小集合
 3:传智播客是一个大集合
 4:基础班和就业班又是一个集合.
 5:在小集合中学号为键,Student对象为值.
 */
public class HashMap_集合嵌套 {
 public static void main(String[] args) {
  HashMap<String,HashMap<String,String>> hm=new HashMap<String,HashMap<String,String>>();   //大集合
  HashMap<String,String> hm1=new HashMap<String,String>();         //小集合基础班
  hm1.put("001", "张三");
  hm1.put("002", "李四");
  HashMap<String,String> hm2=new HashMap<String,String>();         //小集合就业班
  hm2.put("001", "王五");
  hm2.put("002", "赵六");
  
  hm.put("基础班",hm1);
  hm.put("就业班",hm2);
  
  Set<String> set=hm.keySet();
  for(Iterator<String> it=set.iterator();it.hasNext();){
   String str1=it.next();                      //取得大集合的键
   HashMap<String,String> hp=hm.get(str1);     //取得大集合的值
   System.out.println(str1);
   
   Set<String> ss=hp.keySet();          //得到小集合的所有键
   for(Iterator<String> itt=ss.iterator();itt.hasNext();){
    String str2=itt.next();       //取得小集合的键
    String str3=hp.get(str2);     //取得小集合的值
    System.out.println("\t"+str2+"....."+str3);
   }
  }
 }
}

6:TreeMap:
 基于二叉树实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,
 具体取决于使用的构造方法。
例:
  1:按照年龄排序,如果年龄相同按姓名排,让元素本身具有比较性实现Comparable接口
  2:根据名字的长度排序,并且让集合本身具有比较性.
 */
public class TreeMap_保证元素的有序性 {
 public static void main(String[] args) {
 //内部类方式
 /* TreeMap<Person,String> tmp=new TreeMap<Person,String>(new Comparator<Person>() {

   @Override
   public int compare(Person p1, Person p2) {
    int num=p1.getAge()-p2.getAge();
    int num1=p1.getName().compareTo(p2.getName());
    return num==0?num1:num;
   }
  });*/
  
  //使用比较器,让集合具备比较性
  TreeMap<Person,String> tmp=new TreeMap<Person,String>(new ComImp());
  
  //让元素自身具有比较性
  //TreeMap<Person,String> tmp=new TreeMap<Person,String>();
  
  tmp.put(new Person("ly刘亦菲",22),"001");
  tmp.put(new Person("ls刘诗诗", 2),"002");
  tmp.put(new Person("杨幂",30),"003");
  tmp.put(new Person("李冰冰",25),"004");
  
  Set<Person> set=tmp.keySet();
  for(Iterator<Person> it=set.iterator();it.hasNext();){
   Person key=it.next();
   String value=tmp.get(key);
   System.out.println(key.getName()+"....."+key.getAge()+"..."+value);
  }
 }
}
class Person implements Comparable<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;
 }
 @Override
 public int compareTo(Person p) {
  int num=this.age-p.age;
  int num1=this.name.compareTo(p.name);
  return num==0?num1:num;
 }
}
class ComImp implements Comparator<Person>{
 @Override
 public int compare(Person p1, Person p2) {
  int num=p1.getAge()-p2.getAge();
  int num1=p1.getName().compareTo(p2.getName());
  return num==0?num1:num;
 }
}


7:Collections:  Collection的工具类.
 此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。

 排序:   sort();
 二分查找:  binarySearch();
 反转:   reverse();

8:Arrays:  数组操作的工具类.

 toString(基本数据类型[])把数组用字符串输出.
 sort();排序
 binarySearch();二分查找.

9:增强for循环:

格式:
 for(元素的数据类型 变量名:数组或Collection集合)
 {
  执行语句;
 }

好处:
 简化了对数组,集合的遍历.
例:for(int x:arr){
 System.out.println(x);//自动从数组arr中的0索引出开始,获取每一个值赋给x.
}


10:方法的另一种形式:可变参数方法
返回值类型 函数名(数据类型... 数组名){}

注意:假如有多个参数的时候,而且你的参数有可变参数,这个时候,可变参数必须置于方法参数的最后边.
例: int run(int b,int...a){}

11:静态导入:
import默认导入是导入到类级别.
而静态导入是导入到方法的级别.
格式:
 import static 类名.方法;

 

 


 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值