List和Map集合框架

遍历ArrayList

public class Test{
 public static void main(String[] args) {
     List<String> list=new ArrayList<String>();
     list.add("Hello");
     list.add("World");
     list.add("HAHAHAHA");
     //第一种遍历方法使用 For-Each 遍历 List
     for (String str : list) {            //也可以改写 for(int i=0;i<list.size();i++) 这种形式
        System.out.println(str);
     }
 
     //第二种遍历,把链表变为数组相关的内容进行遍历
     String[] strArray=new String[list.size()];
     list.toArray(strArray);
     for(int i=0;i<strArray.length;i++) //这里也可以改写为  for(String str:strArray) 这种形式
     {
        System.out.println(strArray[i]);
     }
     
    //第三种遍历 使用迭代器进行相关遍历
     
     Iterator<String> ite=list.iterator();
     while(ite.hasNext())//判断下一个元素之后有值
     {
         System.out.println(ite.next());
     }
 }
}

遍历Map

public class Test{
     public static void main(String[] args) {
      Map<String, String> map = new HashMap<String, String>();
      map.put("1", "value1");
      map.put("2", "value2");
      map.put("3", "value3");
      
      //第一种:普遍使用,二次取值
      System.out.println("通过Map.keySet遍历key和value:");
      for (String key : map.keySet()) {
       System.out.println("key= "+ key + " and value= " + map.get(key));
      }
      
      //第二种
      System.out.println("通过Map.entrySet使用iterator遍历key和value:");
      Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
      while (it.hasNext()) {
       Map.Entry<String, String> entry = it.next();
       System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
      }
      
      //第三种:推荐,尤其是容量大时
      System.out.println("通过Map.entrySet遍历key和value");
      for (Map.Entry<String, String> entry : map.entrySet()) {
       System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
      }
    
      //第四种
      System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
      for (String v : map.values()) {
       System.out.println("value= " + v);
      }
     }
}

删除链表中的元素:

LinkedList<String> lList = new LinkedList<String>();
      lList.add("1");
      lList.add("8");
      lList.add("6");
      lList.add("4");
      lList.add("5");
      System.out.println(lList);
      lList.subList(2, 4).clear();
      System.out.println(lList);

类型通配符:
类型通配符一般是使用?代替具体的类型参数。例如 List<?> 在逻辑上是List<String>,List<Integer> 等所有List<具体类型实参>的父类

public class GenericTest {     
    public static void main(String[] args) {
        List<String> name = new ArrayList<String>();
        List<Integer> age = new ArrayList<Integer>();
        List<Number> number = new ArrayList<Number>();        
        name.add("icon");
        age.add(18);
        number.add(314);
        getData(name);
        getData(age);
        getData(number);     
   }
   public static void getData(List<?> data) {
      System.out.println("data :" + data.get(0));
   }
}

Java的集合对象可以调用toArray()方法将集合中所有数据提取到一个新的数组中:

public<T>T[] toArray(T[] array);

array:保存集合数据的数组

ArrayList提供了一个将List转为数组的一个非常方便的方法toArray。toArray有两个重载的方法:
(1)list.toArray();//将list直接转为Object[]数组
(2)list.toArray(T[] a);

HashMap存储过程:

当程序执行map.put(“语文”,80)时。系统将调用"语文"的hashCode()方法得到其hashCode(每个java对象都有hashCode()方法),然后根据hashCode值决定该元素的存储位置

int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);//搜索指定hash值在对应table中的索引

其实每个Map.Entry就是一个key-value对,如果两个Entry的key的通过equals比较返回true,则value将覆盖原有Entry的value,如果返回false,则新添加的Entry将与集合中原有Entry形成Entry链当程序执行map.get(“key”)时,系统通过key的hashCode()返回值找出key在table数组中的索引,然后取出该索引处的Entry,最后返回对应的value
总结:
HashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Entry对象,HashMap底层采用一个Entry[]数组来保存所有的key-value对,根据Hash算法来决定其存储位置

HashSet:

HashSet是基于HashMap实现的,HashSet底层封装了一个HashMap对象来保存所有集合元素,所有放入HashSet中的集合元素实际上由HashMap的key来保存,而HashMap的value则存储了一个静态Object对象,因此HashMap和HashSet在实现本质上是相同的。
将某个类的对象放入HashSet中保存时,需要重写该类的equals(Object obj)和hashCode()方法,而且这两个方法的返回值必须保持一致
例如果重写类的hashCode()和equals():

class Name{
private String first;
private String last;
public Name(String first,String last){
this.first = first;
this.last = last;
}
//根据first判断2个Name是否相等
public boolean equals(Object o){
if(this == 0){
return true;
}
if(o.getClass() == Name.class){
Name n = (Name)o;
return n.first.equals(first);
}
return false;
}
//根据first计算Name对象的hashCode()返回值
public int hashCode(){
return first.hashCode();
}
}
public class HashSetTest{
public static void main(String[] args)
{
HashSet<Name> set = new HashSet<Name>();
set.add(new Name("abc","123"));
set.add(new Name("abc","456"));
System.out.println(set);
}
}

TreeSet底层也是使用TreeMap来包含Set集合:

对于TreeMap而言,它采用一种被称为“红黑树”的排序二叉树来保存Map中的每个Entry—每个Entry都被当成“红黑树”的一个节点对待,保证了TreeMap中所有key总是由小到大地排列;因此TreeMap添加元素和取出元素的性能都比HashMap低,而且是有序排序。

红黑树是一种自平衡二叉查找树,数中每个节点的值都大于或等于在它的左子树中的所有节点的值,并且小于或等于在它的右子树中的所有节点的值

总结:不管是HashMap还是TreeMap,它们的values()方法都可返回其所有value组成的Collection集合,也就是个List集合,实际上就是遍历Map对象的value
Vector为什么是线程安全的类:
Vector有一个Stack子类,并增加了几个方法,这些方法使用了synchronized修饰

ArrayList和LinkedList:
List代表一种线性表的数据结构,ArrayList则是一种顺序存储的线性表。ArrayList底层采用数组来保存每个集合元素,LinkedList则是一种链式存储的线性表,其本质就是一个双向链表,因为它实现了List接口和Deque接口;
区别:
LinkedList在添加集合元素时只要对链表在指定节点之前添加一个新节点就行,对于ArrayList而言,由于底层采用数组来保存集合元素,因此可以直接根据数组索引取出index位置的元素,但LinkedList必须一个个元素地搜索,直到找到第index个元素为止。

迭代器模式:
对于Iterator迭代器而言,它只是个接口,Java要求各种集合都提供一个iterator()方法,该方法可以返回一个Iterator用于遍历该集合中元素,至于返回的Iterator到底是哪种实现类程序并不关心。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值