黑马程序员_java_集合(下)

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

        集合(下)


 Map接口的实现类
   Map皆空常用的实现类有Hashtable,HashMap和TreeMap,通常建议使用HashMap结合实现Map集合,因为HashMap类实现Map集合对于天价和删除
映射关系效率更高.HashMap是给予哈希表的Map接口的实现,HashMap通过哈希吗对其内部的映射关系进行快速查找;由HshMap类实现Map集合对于天价或者删除
映射关系效率高;而TreeMap中的映射关系存在一定的顺序,如果希望Map集合中的对象存在一定的顺序,应该使用TreeMap类实现Map集合.Map和Set很像。
Set底层就是使用了Map集合。

 

Map与Collection:
 Map与Collection在集合框架中属并列存在
 Map存储的是键值对
 Map存储元素使用put方法,Collection使用add方法
 Map集合没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素
 Map集合中键要保证唯一性


Map集合特点:

该集合存储键值对。一对一对往里存。而且要保证键的唯一性。
Map
   |--Hashtable
:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。jdk1.0.效率低。
   |--HashMap:底层是哈希表数据结构,允许使用 null 值和 null 键,该集合是不同步的。将hashtable替代,jdk1.2.效率高。
   |--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。
//-----------------------------华丽的分割线------------------------------------


Map集合的共性方法:

 

1,添加。
 put(K key, V value)
 putAll(Map<? extends K,? extends V> m)


2,删除。
 clear()
 remove(Object key)


3,判断。
 containsValue(Object value)
 containsKey(Object key)
 isEmpty()


4,获取。
 get(Object key)
 size()
 values()
 entrySet()
 keySet()
//-----------------------------华丽的分割线------------------------------------

import java.util.*;
class  MapDemo
{
 public static void main(String[] args) 
 {
  //建立Map集合
  Map<String,String> map=new HashMap<String,String>();
  添加元素,添加元素,如果出现添加时,相同的键。那么后添加的值会覆盖原有键对应值。
  map.put("01","zhangsan1");
  map.put("02","zhangsan2");
  map.put("03","zhangsan3");
  map.put("04","zhangsan4");
  
  sop(map.containsKey("02"));//判断键是否存在
  sop(map.get("01"));//可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断。 
  sop(map);
  Collection<String> coll=map.values();//用values获取map集合中所有的值.
  sop(coll);
 }
 public static void sop(Object obj)//为了打印方便建立一个函数
 {
  System.out.println(obj);
 }
}



//-----------------------------华丽的分割线------------------------------------


map集合的两种取出方式:


1,Set<k> keySet:

将map中所有的键存入到Set集合。因为set具备迭代器。
 所有可以迭代方式取出所有的键,在根据get方法。获取每一个键对应的值。


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


示例:

import java.util.*;
class MapDemo2
{
 public static void main(String[] args)
 {
  Map<String,String> map=new HashMap<String,String>();

  map.put("01","zhansan01");
  map.put("02","zhansan02");
  map.put("03","zhansan03");
  map.put("04","zhansan04");

  Set<String> s=map.keySet();//先获取map集合的所有键的Set集合,keySet();
  System.out.println(map);//有了Set集合。就可以获取其迭代器。

  for(Iterator<String> it=s.iterator(); it.hasNext();)
  {
   String key=it.next();
   //有了键可以通过map集合的get方法获取其对应的值。
   String value=map.get(key);
   System.out.println(key+"..."+value);
  }
 }
}


 

2,Set<Map.Entry<k,v>> entrySet:

    将map集合中的映射关系存入到了set集合中,
    而这个关系的数据类型就是:Map.Entry

    Entry其实就是Map中的一个static内部接口。
    为什么要定义在内部呢?
    因为只有有了Map集合,有了键值对,才会有键值的映射关系。
    关系属于Map集合中的一个内部事物。
    而且该事物在直接访问Map集合中的元素。


示例:

import java.util.*;
class MapDemo3
{
 public static void main(String[] args)
 {
  Map<Integer,String> map=new HashMap<Integer,String>();

  map.put(01,"java01");
  map.put(02,"java02");
  map.put(03,"java03");
  map.put(04,"java04");

  //将Map集合中的映射关系取出。存入到Set集合中。
  Set<Map.Entry<Integer,String>> entrySet=map.entrySet();

  for(Iterator<Map.Entry<Integer,String>> it=entrySet.iterator();it.hasNext();)
  {
   Map.Entry<Integer,String> me=it.next();
   Integer key=me.getKey();
   String value=me.getValue();
   System.out.println(key+"...."+value);
  }
 }
}



//-----------------------------华丽的分割线------------------------------------
HashSet示例:

/*
1.描述学生.
2.定义map容器.将学生作为键.住址作为值,存入.
3.获取map集合中的元素
*/
import java.util.*;
class Student implements Comparable<Student>//为了以后方便可能存进去TreeSet集合中去实现Comparable.将学生具备比较性
{
 private String name;
 private int age;
 Student(String name,int age)//将学生name和age初始化
 {
  this.name=name;
  this.age=age;
 }
 public int compareTo(Student s)//覆盖Comparable中的compareTo方法.来比较,先比较age在比较name.
 {
  int num=new Integer(this.age).compareTo(new Integer(s.age));//Integer是因为age是基本数据类型不具备比较.要转成Integer来实现compareTo方法
  if(num==0)
   return this.name.compareTo(s.name);//name是字符串本身就比较比较性.直接使用compareTo方法就哦了
  return num;
 }
 public int hashCode()//复写hashCode.来让存进去的学生保证唯一.为什么要覆盖因为默认比较是比较hash值.和内容是否一样.因为存的是hash值所以每次建立对象的时候都不一样
       //所以要复写hashCode,来比较年龄和姓名是否是相同.这样就能保证学生的唯一性了.
 {
  return name.hashCode()+age*34;
 }
 public boolean equals(Object obj)//如果年龄相同的话在比较年龄.
 {
  if(!(obj instanceof Student))//如果穿进去不的不是学生类.抛异常
   throw new ClassCastException("类型不匹配");
  Student s=(Student)obj;
  return this.name.equals(s.name) && this.age==s.age;
 }

 public String getName()
 {
  return name;
 }
 public int getInt()
 {
  return age;
 }
 public String toString()
 {
  return name+".."+age;
 }
}

class MapTest
{
 public static void main(String[] args)
 {
  HashMap<Student,String> hm=new HashMap<Student,String>();//穿件Map集合中的 HashMap集合

  hm.put(new Student("zhangsan01",21),"beijing");//往里面添加键值对.将学生作为键.住址作为值
  hm.put(new Student("zhangsan02",22),"tianjing");
  hm.put(new Student("zhangsan03",23),"sahgnhan");
  hm.put(new Student("zhangsan01",23),"sahgnhan");

  //第一种去取出方式
  Set<Student> s=hm.keySet();
  for(Iterator<Student> it=s.iterator();it.hasNext();)
  {
   Student key=it.next();
   String value=hm.get(key);
   System.out.println(key+"...."+value);
  }
  //第二种取出方式
  System.out.println("-----------------------------------------------------");
  Set<Map.Entry<Student,String>> entrySet=hm.entrySet();
  for(Iterator<Map.Entry<Student,String>> it=entrySet.iterator();it.hasNext();)
  {
   Map.Entry<Student,String> me=it.next();
   Student key1=me.getKey();
   String value1=me.getValue();
   System.out.println(key1+"..."+value1);
  }
 }
}



//-----------------------------华丽的分割线------------------------------------


集合方法方法类


Collections类:集合框架的工具类。
Collections:集合框架的工具类。里面定义的都是静态方法。
Collections.方法(  );


Collections和Collection有什么区别?
Collection
 是集合框架中的一个顶层接口,
 它里面定义了单列集合的共性方法。它有两个常用的子接口,List:对元素都有定义索引。有序的。
 可以重复元素。Set:不可以重复元素。无序。
Collections
 是集合框架中的一个工具类。该类中的方法都是静态的
 1提供的方法中有可以对list集合进行排序,二分查找等方法。
 2通常常用的集合都是线程不安全的。因为要提高效率。
 3如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。


Collections的常用方法:
 sort:对List集合排序
 public static <T extends Comparable<? super T>> void sort(List<T> list)
 根据元素的自然顺序 对指定列表按升序进行排序。列表中的所有元素都必须实现 Comparable 接口

 

  Collections.sort(list);
  不可以给Set排序因为Set里面有TreeSet.用它也没什么用
  如果出现了重复元素也可以排序,因为是数组结构有索引.


  Collections.sort(list,new 比较器Comparator);
  如果不喜欢默认的排序可以自定义比较器(比如最大长度
  
 max:获取最大值
  public static <T> T max(Collection<? extends T> coll,Comparator<? super T> comp)
  根据指定比较器产生的顺序,返回给定 collection 的最大元素。collection 中的所有元素都必须可通过指定比较器相互比较
  (也就是说,对于 collection 中的任意 e1 和 e2 元素,comp.compare(e1, e2) 不得抛出 ClassCastException)。
  String max=Collection.max(list);
  String max=Collection.max(list,new 比较器Comparator);
  也可以放比较器.最大程度等

 

 binarySearch:对list集合二分查找(必须是有序的)
  public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key)
  使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据列表元素的自然顺序
  对列表进行升序排序(通过 sort(List) 方法)。如果没有对列表进行排序,则结果是不确定的。如果列
  表包含多个等于指定对象的元素,则无法保证找到的是哪一个。

 

  返回:
  如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。
  插入点 被定义为将键插入列表的那一点:即第一个大于此键的元素索引;如果列表中的所有元素都
  小于指定的键,则为 list.size()。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。
  Collection.sort(list);//对list集合进行排序
  int index =Collection.binarySearch(list,"aaa");//查找"aaa"所在位置.返回插入点-1
  System.out.println("index"+index);
  (也可以加入比较器.比如长度排序,传比较器)
  Collection.sort(list,new 比较器Comparator);//对list集合进行长度排序
  int index =Collection.binarySearch(list,"aaa"new 比较器Comparator);//查找"aaa"所在位置.(按长度来了)返回插入点-1
  System.out.println("index"+index);

 

 fill:将集合中的部分元素替换成指定元素
  public static <T> void fill(List<? super T> list,T obj)使用指定元素替换指定列表中的所有元素。
  Collection.fill(list,"pp");

 

 replaceAll:替换
  public static <T> boolean replaceAll(List<T> list,T oldVal,T newVal)
  使用另一个值替换列表中出现的所有某一指定值。更确切地讲,使用 newVal 替换 list 中
  满足 (oldVal==null ? e==null : oldVal.equals(e)) 的每个 e 元素。(此方法对列表的大小
  没有任何影响。)
  Collection.replaceAll(list,"aaa","PP");//将"aaa"替换成"pp"

 

 reverse:反转.
  Collection.reverse(list);//将list反转

 

 reverseOrder:逆转排序
  返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
  TreeSet<String> ts=new TreeSet<String>(Collection.reverseOrder(new 比较器());
 
 synchronizedList:给不同步.返回同步的
  public static <T> List<T> synchronizedList(List<T> list)
  返回指定列表支持的同步(线程安全的)列表。为了保证按顺序访问,必须通过返回的列表完成所有对底层实现列表的访问。
  在返回的列表上进行迭代时,用户必须手工在返回的列表上进行同步:
 synchronizedMap
  public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)
 synchronizedSet
  public static <T> Set<T> synchronizedSet(Set<T> s)

 

 swap:在指定列表的指定位置处交换元素。
  public static void swap(List<?> list,int i,int j)
  在指定列表的指定位置处交换元素。(如果指定位置相同,则调用此方法不会更改列表。)
  Collection.swap(list,1,2);//将list集合的角标1和角标2互换

 

 shuffle:把集合中的元素随机的排放
  public static void shuffle(List<?> list)
  使用默认随机源对指定列表进行置换。所有置换发生的可能性都是大致相等的。
  Collection.shuffle(list);//将list集合的元素随机排放

//-----------------------------华丽的分割线------------------------------------
Arrays:
 用于操作数组的工具类里面都是静态方法
 详情请查看API问的 java util Arrays


asList:将数组变成list集合

 

把数组变成list集合有什么好处?

可以使用集合的思想和方法来操作数组中的元素。
 注意:将数组变成集合,不可以使用集合的增删方法。
 因为数组的长度是固定。


 contains。
 get
 indexOf()
 subList();
 如果你增删。那么会反生UnsupportedOperationException,
 String[] arr = {"abc","cc","kkkk"};
 List<String> list = Arrays.asList(arr);
 //sop("contains:"+list.contains("cc"));
 //list.add("qq");//UnsupportedOperationException,
 //sop(list);
 //int[] nums = {2,4,5};
 Integer[] nums = {2,4,5};  
 List<Integer> li = Arrays.asList(nums);
 如果数组中的元素都是对象。那么变成集合时,数组中的元素就直接转成集合中的元素。
 如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。

 

集合变数组:
 Collection接口中的toArray方法
 1.指定类型的数组到底是要定义多长呢?
  当指定类型的数组长度小于集合的size.那么该方法内部会创建一个新的数组.长度为集合的size.
  当指定类型的数据长度大于集合的size.就不会创建新的数组.而是使用传递进来的数组.
  所以创建一个刚刚好的数组最优.


 2.为什么要将集合变成数组呢?
  为了限定对元素的操作,不需要进行增删了.

//-----------------------------华丽的分割线------------------------------------


高级for循环


格式:
for(数据类型 变量名 : 被遍历的集合(Collection)或者数组)
{   
 
}

 对集合进行遍历。
 只能获取集合元素。但是不能对集合进行操作。
 迭代器除了遍历,还可以进行remove集合中元素的动作。
 如果是用ListIterator,还可以在遍历过程中对集合进行增删改查的动作。
 传统for和高级for有什么区别呢?
 高级for有一个局限性。必须有被遍历的目标。
 建议在遍历数组的时候,还是希望是用传统for。因为传统for可以定义脚标。

import java.util.*;

class ForEachDemo 
{
 public static void main(String[] args) 
 {  
  ArrayList<String> al = new ArrayList<String>();
  al.add("abc1");
  al.add("abc2");
  al.add("abc3");
  for(String s : al)
  {
   //s = "kk";
   System.out.println(s);
  }
  System.out.println(al);
  /*
  Iterator<String> it = al.iterator();
  while(it.hasNext())
  {
   System.out.println(it.next());
  }
  */
  int[] arr = {3,5,1};

  for(int x=0; x<arr.length; x++)
  {
   System.out.println(arr[x]);
  }
  for(int i : arr)
  {
   System.out.println("i:"+i);
  }
  HashMap<Integer,String> hm = new HashMap<Integer,String>();
  hm.put(1,"a");
  hm.put(2,"b");
  hm.put(3,"c");
  Set<Integer> keySet = hm.keySet();
  for(Integer i : keySet)
  {
   System.out.println(i+"::"+hm.get(i));
  }
//  Set<Map.Entry<Integer,String>> entrySet = hm.entrySet();
//  for(Map.Entry<Integer,String> me : entrySet)
  for(Map.Entry<Integer,String> me : hm.entrySet())
  {
   System.out.println(me.getKey()+"------"+me.getValue());
  }
 }
}


 


//-----------------------------华丽的分割线------------------------------------


JDK1.5版本出现的新特性。

方法的可变参数。
在使用时注意:可变参数一定要定义在参数列表最后面。

可变参数:
 其实就是上一种数组参数的简写形式。
 不用每一次都手动的建立数组对象。
 只要将要操作的元素作为参数传递即可。
 隐式将这些参数封装成了数组。

class  ParamMethodDemo
{
 public static void main(String[] args)
 {

  show("haha",2,3,4,5,6);
 }
 public static void show(String str,int... arr)
 {
  System.out.println(arr.length);
 }
//-----------------------------华丽的分割线------------------------------------
静态导入。
 import static
注意:
 当类名重名时,需要指定具体的包名。
 当方法重名是,指定具备所属的对象或者类。
 import java.util.*;//导入util包中的所有的类
 import static  java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值