java 集合 知识复习+课后小练习

集合体系概述Java的集合框架是由很多接口、抽象类、具体类组成的

泛型:基本类型不能作为类型参数

在这里插入图片描述

参数化类型,也就是说所操作数据类型指定为一个参数

Collection 接口-定义了存取一组对象的方法,其子接口Set和List分别定义了存储方式。

List:链表中元素可以重复出现

List继承了Collection接口,有三个实现的类分别为:

**1

ArraysList

  • 数组列表,数据采用数组方式存储,底部由数组实现,查询快,中间增删慢,可以通过get(index)直接获取当前位置的值;add扩容 元素移位; remove可以移除元素.
 ArrayList    arrlist = new ArrayList();

  arrlist.add("2223");

collection.addAll(list,"a","b","c");

collection.sort(list);

ArraysList动态数组当底层满了之后将进行自动扩容,扩容为之前的1.5倍

ArrayList实现了长度可变的数组,在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高

在这里插入图片描述

**2.

LinkedList

😗* 底部为双向链表,从头到尾进行查询,速度较慢; 增删快只需要改变指针域,元素在内存中不发生改变

LinkedList采用链表存储方式。插入、删除元素时效率比较高

LinkedList<String> list = new LinkedList<>();
		                    list.add("a");

在这里插入图片描述
在这里插入图片描述

List接口的循环迭代

**

Vector

: 底部也为数组, 查询快,中间增删慢, 线程安全**
vector也继承了Collection接口

 Vector<String> v = new Vector<>();
        v.add("a");
        System.out.println(v);

Set接口

*继承了Collection接口。 Set中所存储的元素是不重复的,但是是无序的

  不可以重复,值没有索引
   HashSet:无序  底层使用哈希表+链表+红黑树
   TreeSet:有序(按照值(编码)的顺序排序)  底层是红黑树
 public static void main(String[] args) {
	 HashSet<Integer> set=new HashSet<>();
	                  set.add(2);
	                  set.add(1);
	                  set.add(4);
	                  set.add(11);
	                  set.add(23); 
	                  set.add(23); 
	                  set.add(null); 
	  System.out.println(set);
	  /*
	     HashSet添加时如何判断值是否重复 
	            添加时会调用hashCode(),equals()
	             添加时要比较内容是否相等,既要保证效率,又要保证安全
	             先调用hashCode()计算出一个哈希值,比较哈希值非常快,但是不安全
	             当哈希值相同时,再调用equals()方法比较                      
	   */
	
	      int h = "通话".hashCode();
	      int h1 = "重地".hashCode();
	    System.out.println(h+"::::"+h1);
	    System.out.println(h==h1);
	  HashSet<String> set1 = new HashSet<>();
				  set1.add("a");
				  set1.add("通话");
				  set1.add("重地");
				  set1.add("a");
				  set1.add("c");
				  set1.add("b");
		System.out.println(set1);
 }
}
		 
	 public static void main(String[] args) {
     HashSet<Student> set = new HashSet<>();
	 /*
	       我们的Student类中没有重写hashCode()和equals(),会调用Object中的方法
	  */
	 Student s1 = new Student("jim1", 21);   
	 Student s2 = new Student("jim2", 22);
	 Student s3 = new Student("jim3", 23);
	 Student s4 = new Student("jim4", 24);
	 Student s5 = new Student("jim2", 22);
	 	 set.add(s1);
				 set.add(s2);
				 set.add(s3);
				 set.add(s4);
				 set.add(s5);
				 System.out.println(set.size());
	     
	     //"s".hashCode();//字符串.Integer....这些类重写了hashCode()都是根据对象中包含的内容来计算哈希值
}
}
	   public static void main(String[] args) {
	 HashSet<Integer> set=new HashSet<>();
	                  set.add(2);
	                  set.add(1);
	                  set.add(4);
	                  set.add(11);
	                  set.add(23); 
	                  set.add(23); 
	 /*
	  增强for
	  */
	   /*for(Integer it : set){
		   System.out.println(it);
	   }*/
	   	 /*
	   listIterator()和iterator()区别
	   listIterator()只能遍历实现了List接口的类
	   iterator() 遍历list,set
	  */
	  Iterator<Integer> it =  set.iterator();
              while(it.hasNext()){
            	Integer n = it.next();
                   System.out.println(n);
            	   // it.remove();
              }
	  
	 /*
	   Stream
	  */
      Stream<Integer> stream =  set.stream();
      stream.forEach(new Consumer<Integer>(){
    	  @Override
        	public void accept(Integer t) {
                      System.out.println(t);	               		
        	}
      });
}
}     

Map集合 双列存储Key键不能重复,每个键只能映射一个值

 Map<String, String> map = new HashMap<>();
map.put("a","a");
System.out.println(map.isEmpty());//判断map是否为空
		                   System.out.println(map.containsKey("a"));//输出主键为a的map数组的值
		                   System.out.println(map.containsValue("c"));//输出值为c的主键
		                   System.out.println(map.size());//输出map数组的长度

Map集合遍历

方式1:根据键找值

•获取所有键的集合

•遍历键的集合,获取到每一个键

•根据键找值

方式2:根据键值对对象找键和值

•获取所有键值对对象的集合

•遍历键值对对象的集合,获取到每一个键值对对象

•根据键值对对象找键和值

HashMap

HashMap中元素的key值不能重复, 排列顺序是不固定的,可以存储一个为null的键

TreeMap

TreeMap中所有的元素都保持着某种固定的顺序,如果需要得到一个有序的Map就应该使用TreeMap,key值所在类必须实现Comparable接口, 重写compareTo方法。TreeMap根据compareTo的逻辑,对 key进行排序。键是红黑树结构,可以保证键的排序和唯一性

  public class TreeMapDemo {
        public static void main(String[] args) {
            TreeMap<String, String> tmap = new TreeMap<>();
            tmap.put("b", "b");
            tmap.put("a", "a");
            tmap.put("d", "d");
            tmap.put("c", "c");
            tmap.put("c", "c");
            System.out.println(tmap);
        }
    }

在这里插入图片描述

HashTable

实现了同步。但其中 不能存储为null的键

 public class HashtableDemo {
        public static void main(String[] args) {
            Hashtable<String, String> htable = new Hashtable<>();
            htable.put("a", "a");
            htable.put("b", "a");
            htable.put("c", "a");
            System.out.println(htable);
        }
    }

在这里插入图片描述

哈希表+链表+红黑树哈希表默认长度16负载因子为0.75 扩容时为原来的2倍链表长度为8时转化为红黑树

练习习题

public class demo3 {
   /* 有2个数组,第一个数组内容为:[黑龙江省,浙江省,江西省,广东省,福建省],第二个数组为:[哈尔滨,杭州,南昌,广州,福州],
    将第一个数组元素作为key,第二个数组元素作为value存储到Map集合中。如{黑龙江省=哈尔滨, 浙江省=杭州, …}。*/
    public static void main(String[] args) {
        String []src1={"黑龙江省","浙江省","江西省","广东省","福建省"};
        String []src2={"哈尔滨","杭州","南昌","广州","福州"};
        HashMap<String,String>map=new HashMap<>();
        for (int i=0;i<=4;i++){
            map.put(src1[i],src2[i] );
        }
        System.out.println(map);
    }
}
//通过输入年份判断那一年中是否有比赛,有的话输出国家名称
//通过输入国家名称,输出该国家在哪几年有过冠军
public class demo1 {
    public static void main(String[] args) {
        HashMap<Integer, String> map = new HashMap<>();
        map.put(1930, "乌拉圭");
        map.put(1934, "意大利");
        map.put(1938, "意大利");
        map.put(1950, "乌拉圭");
        map.put(1954, "西德");
        map.put(1958, "巴西");
        map.put(1962, "巴西");
        map.put(1966, "英格兰");
        map.put(1970, "巴西");
        map.put(1974, "西德");
        map.put(1978, "阿根廷");
        map.put(1982, "意大利");
        map.put(1986, "阿根廷");
        map.put(1990, "西德");
        map.put(1994, "巴西");
        map.put(1998, "西德");
        map.put(2002, "巴西");
        map.put(2006, "意大利");
        map.put(2010, "西班牙");
        map.put(2014, "德国");
        map.put(2018, "法国");
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个年份");
        int a = sc.nextInt();
        if (map.get(a) == null) {
            System.out.println("这年没有世界杯");
        }
        {
            System.out.println("获得冠军的队伍为" + map.get(a));
        }
        Scanner sc1 = new Scanner(System.in);
        System.out.println("请输入一个国家查看大力神杯的年份:");
        String b=sc1.next();
        System.out.println("年份是");
        for(Integer key: map.keySet()){
            if(b.equals(map.get(key))){
                System.out.print(key+",");
            }
        }
    }
}

巩固拓展练习

判读正误 :
1. ConcurrentHashMap使用synchronized关键字保证线程安全
错误,JDK1.8 的 ConcurrentHashMap 采用CAS+Synchronized保证线程安全。 JDK1.7及以前采用segment的分段锁机制实现线程安全,其中segment继承自ReentrantLock,因此采用Lock锁来保证线程安全。
:
2.HashMap实现了Collction接口
*错误,**由代码可知

public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable

下面程序运行完之后,t2与t3的关系为()

 Object obj = new Object();
    List aList = new ArrayList();
    List bList = new LinkedList();
    long t1 = System.currentTimeMillis();        
     for(int i = 0;i<50000;i++)
    {
        aList.add(0, obj);
    }
    long t2 = System.currentTimeMillis() - t1;
    t1=System.currentTimeMillis();         for(
    int i = 0;
    i<50000;i++)

    {
        bList.add(0, obj);
    }

    long t3 = System.currentTimeMillis() - t1;

答案: t2>t3
ArrayList内部是动态数组实现,在增加空间时会复制全部数据到新的容量大一些的数组中。而LinkedList内部为双向链表,可以按需分配空间,扩展容量简单,因此LinkedList用时少。
请添加图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值