集合基础知识梳理

一 、Collection 接口

1、List接口

​ 不唯一,有序的序列

1.1ArrayList
  • 集合的概念:集合就是对象的容器,存储对象的对象,可代替数组。位于java.util包

  • 特点

    • ArrayList实现类底层是一个Object数组
    • Array List实现类有下标 ,元素可以重复
    • Array List实现线程不安全
    • ArrayList实现类增删效率低,因为会移动元素的位置。查询的效率高,因为有下标,访问方便。
  • 构造方法的变化

    • 在JDK 1.7版本之前,ArrayList的无参构造默认的创建一个容量为10的一个Object数组。
    • 在JDK1.8版本的时候,做了改进,刚创建ArrayList的时候,只给他一个变量名,避免过多的浪费内存空间。当进行添加元素的时候,再给他一个容量为十的数组。
  • 遍历方式

    • 普通的for循环便历

      利用ArrayList的size()方法获取有效元素个数

    • for-each循环便历

    • 使用迭代器遍历

      1. 先获取迭代器 ArrayList.iterator()
      2. 利用迭代器的hasNext()方法作为while循环的判断
      3. 利用迭代器的Next()方法打印元素
    		List<Integer> number = new ArrayList<Integer>();
    		
    		number.add(24 );
    		number.add(121 );
    		number.add(224 );
    		number.add(244 );
    		number.add(1224 );
    		number.add(214 );
    		
    		//遍历的方法1:
    		for(int i = 0 ; i < number.size() ; i++ ) {
    			System.out.println(number.get(i));
    		}
    		System.out.println("==============");
    		//遍历的方式2:
    		for(Integer i : number) {	
    			System.out.println(i);
    		}
    		System.out.println("==============");
    		//遍历的方式3:
    		Iterator<Integer> iterator = number.iterator();  //获得一个迭代器
    		while(iterator.hasNext()) {  //hasNext()判断的是集合是否有下一个元素,有就是true
    			System.out.println(iterator.next());  //next()方法返回迭代器的下一个元素
    		}
    
  • ArrayList 常用的方法 最好参考API

    • add
      • add(Object obj)
      • add(int index ,Object obj)
    • size()
    • get(int index)
    • contains(Object obj) 查找集合中obj是否存在
    • remove
      • remove(int index)
      • remove(Object obj)
    • Collection中常被用的方法
      • isEmpty() 集合是否为空
      • iterator() 返回一个迭代器
      • clear() 清空
      • toArray() 返回一个数组
1.2Vector
  • 1.0版本就出现了,线程安全。在1.2版本中,添加了ArrayList,方法和Vector 相似,线程不安全。
  • 底层也是数组,扩容为2倍
  • Vector与Array List的区别
    • vector线程安全,ArrayList线程不安全
    • vector扩容两倍,ArrayList扩容1.5倍
    • 初始化容量都是10,但是ArrayList刚创建 的时候,初始容量为0,只有添加元素的时候,才会初始化容量10。vector创建时就是10.
1.3LinkedList
  • 介绍:

    双向链表结构,线程不安全,

  • 特点

    • 增删快(因为空间不连续,链表中的元素都是分为三部分组成的:值、上一个元素的引用,下一个元的引用(即地址)。因此,当增删的时候,只需要改变元素中的索引就能完成)。查询慢。
    • LinkedList因为元素中的组成比较多,因此他比ArrayList占用更多的空间
    • 但是也因为LinkedList空间不连续,所以可以更好的利用内存中的碎片空间。
  • 循环:也可以有三种循环方式

    • 普通的for循环便历 (但是,LinkedList没有下标,因此不推荐使用,因为他太慢了)
    • for-each循环便历
    • 使用迭代器遍历
		List<Integer> list = new LinkedList<Integer>();
		for(int i  = 0 ; i < 100000 ; i++) {
			list.add(i);
		}
		//为了统计一下所用的时间,定义的一个开始参数
		long start = System.currentTimeMillis() ;
		//使用迭代器
		Iterator<Integer> iterator = list.iterator();
		while(iterator.hasNext()) {
			System.out.println(iterator.next());
		}
		//使用for-each
//		for(Integer i : list) {
//			System.out.println(i);
//		}
		//使用for循环,效率太低
//		for(int i = 0 ; i < list.size() ; i++) {
//			System.out.println(list.get(i));
//		}
		//为了统计一下所用的时间,定义的一个结束参数
		long end = System.currentTimeMillis() ;
		System.out.println(end - start);
1.4 ArrayList与LinkendList的比较
  • ArrayList 集合底层是一个数组
  • LinkedList底层是上链表结构实现的

2、Set接口

​ 唯一,无序,

2.1HashSet
  • 特点:

    • 无序,无下标 ,元素不容许重复
    • 底层是HashMap集合
    • 线程不安全
    • 元素不能重复,原理是通过调用元素本身的equals做了比较
  • 方法:继承Collection 因此方法和Array List相似

  • 循环的方法:Set接口没有get方法、

    • 第一种:for-each循环

    • 第二种:迭代器

      Set<String> set = new HashSet<String>();
      set.add("1");
      set.add("1");
      set.add("31");
      
      //第一种:for-each循环
      for(String s : set){
          System.out.println(s);
      }
      System.out.println("======");
      //第二种:迭代器
      Iterator<String> it = set.iterator();
      while(it.hasNext()){
          System.out.println(it.next());
      }
      

二、Map接口

​ 键值对的形式

1、HashMap

  • HashMap的数据结构
  1. JDK7之前的是数组+单项链表的形式
  2. JDk8之后采用的是数组+链表的结构,当链表的元素个数超过8个的时候,链表结构会被扩展为变成红黑树的结构模式。
  3. 1.2版本开始,无参构造方法,会创建一个初始容量为16(可以自定义,但是最好是2的倍数)的Node<k,y>类型的数组,他的默认负载系数是0.75。
  4. 负载系数就是,当使用超过0.75的时候,就会进行两倍的扩容。
  • 特点:

    • 键值对的存储形式
    • 无下标,无序
    • 键和值允许为空,但是键不可以重复,值可以重复
    • 线程不安全
  • 扩容为2倍

  • 常用的方法:

    • put(K key, V value) 添加元素
    • remove(Object key) 移除元素,返回移除的值
    • clear() 清空
    • contains 返回Boolean
      • containsKey(Object key) 集合是否含有这个键
      • containsValue(Object value) 集合是否含有这个值
    • set 返回Set集合
      • entrySet() 返回所有的set视图(键和值),
      • keySet() 返回所有的key视图
      • values() 返回一个collection集合,含有所有的值
    • get(Object key) 根据键返回值
    • isEmpty() 判断是否为空
    • size() 返回键值对的数量
  • 遍历的方式:Map集合和Set集合都是无序的,没有get(Object key)方法,不能用for循环,只能用for-each

    • 第一种 :这种方式的效率比较低

      • 利用keySet() 方法返回key的set集合
      • 再循环用key值返回value
    • 第二种 :

      • 利用values () 方法返回value的collection集合
      • 再循环遍历collection集合,就能得到所有的value值
    • 第三种:

      • 利用entrySet得到一个Set<Entry<k,v>>集合
      • 再利用循环打印entry.getKey() 以及 entry.getValue()
    • 第四种

      • 利用entrySet().iterator() 获得迭代器
      • 然后迭代器中的每一个元素都是Entry类型的元素,所以可以使用entry.getKey() 以及 entry.getValue()
      //第一种;凡是根据key值查找的效率都比较低
      Set<Integer> keySet = map.keySet();
      for(Integer i : keySet) {
      System.out.println("key:" +i);
      System.out.println("值为:" + map.get(i));
      }
      //第二种
      System.out.println("=========");
      Collection<String> values = map.values();
      for(String s : values) {
      	System.out.println("值为:" + s);
      }
      //第三种
      Set<Entry<Integer, String>> entrySet = map.entrySet();
      for(Entry<Integer , String> e : entrySet) {
      	System.out.println(e.getKey() + "+ " + e.getValue());
      }
      //第四种
      Iterator<Entry<Integer, String>> it = map.entrySet().iterator();
      while(it.hasNext()) {
      	Entry<Integer, String> e = it.next() ; 
      //注意:不能在一个循环中直接用it.next()分别调用getKey()和getValue(),不然key和value值不匹配
      //错误的示范:System.out.println(it.next().getKey() + "=" + it.next().getValue());
      	System.out.println(e.getKey() + "=" + e.getValue());
      }
      
  • 注:entry是一个接口

    • Map.entrySet方法返回地图的集合视图,其元素属于此类。 获取对映射条目的引用的唯一方法是从该集合视图的迭代器。 这些Map.Entry对象在迭代期间有效; 更正式地,如果在迭代器返回条目之后已经修改了背景映射,则映射条目的行为是未定义的,除非通过映射条目上的setValue操作。

    • 常用的方法:

    • booleaequals(Object o)将指定的对象与此条目进行比较以获得相等性。
      KgetKey()返回与此条目相对应的键。
      VgetValue()返回与此条目相对应的值。
      inthashCode()返回此映射条目的哈希码值。
      VsetValue(V value)用指定的值替换与该条目相对应的值(可选操作)。

2、Hashtable

  • 特点:
    • 键值都不支持null
    • 初始容量为11
    • 线程安全 ,效率低。 1.0版本出现的Hashtable
    • 扩容的时候,扩大两倍+1
  • 常用的方法:常用的方法和HashMap方法相似,如果不为了保证线程的安全,推荐使用HashMap
  • 遍历的方式与HashMap的遍历方式一样

3、HashMap与Hashtable的区别

  • Hashmap是个线程不安全的类,Hashtable是一个线程安全的类
  • HashMap初始容量为16,Hashtable初始容量为11
  • 扩容时,前者扩大两倍,后者扩大两倍加1
  • 前者可以将null作为键值对的值,后者则不中

三、泛型

  • 泛型集合【重点-解决应用问题】:

    • 概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
    • 特点:
      • 编译时即可检查,而非运行时抛出异常。
      • 访问时,不必类型转换(拆箱)。
      • 不同泛型之间引用不能相互赋值,泛型不存在多态。
  • 泛型:常用名称:E = Element / T = Type / K = Key / V = Value

    • 概念:约束-规范类型
    • 泛型的应用场景
      • 实例泛型:
        • 类名后面:创建对象时,为类定义的泛型,进行参数化赋值
        • 接口名的后面:实现接口时,为接口所定义的泛型,进行参数化赋值
      • 静态泛型:
        • 方法的返回值类型的前面
        • 定义在方法的形参列表之中,不支持使用& 只能应用在形参列表上,规范泛型。
//1、定义在类之中的泛型:

public class Test {
	public static void main(String[] args) {
	//创建对象时,给泛型什么类型,那么在类中的实例方法中的引用就会是什么类型,能规范,统一类型
		Student<String> stu1 = new Student<String>();
		stu1.ma("afa");
		Student<Integer> stu = new Student<Integer>();
		stu.ma(45);
	}
}
class Student<T> {
	public void ma(T t) {
		t.toString() ;
	}
}

//2、定义在接口之中的泛型
interface Run<T>{
    //4、返回值的泛型
	public T ma();
}
//在接口实现的时候,需要给一个具体类型,那么这个实现类实现的方法中关于这个泛型,都会变成这个具体的类型
public class Test1 implements Run<String>{
	public String ma() {
		return "aafga";
	}
}
 
//3、定义在方法形参列表之中   <? extends Person>代表了父类Person以及他的所有子类。
public class Test {
	public static void ma(Set<?> set) {
		Iterator<?> it = set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
	public static void main(String[] args) {
		Set<String> set1 = new HashSet<String>();
		set1.add("a");set1.add("r");set1.add("qa");
		ma(set1);
		Set<Integer> set2 = new HashSet<Integer>();
		set2.add(1);set2.add(2);set2.add(3);
		ma(set1);
		
	}
}

四、Collections工具类:

  • 概念:集合工具类,定义了除了存取以外的集合常用方法。

    • public static <T extends Comparable<? super T>> void sort(List list) //排序,要求:必须实现Comparable,必须可与自身类型比,以及父类类型比
    • public static void reverse(List<?> list) //反转、倒置元素
    • public static void shuffle(List<?> list) //随机重置顺序
    • binarySearch(List<? extends Comparable<? super T>> list, T key) 查找
    • max( ) min()
  • Comparable<? super T>

    • 该接口对实现它的每个类的对象强加一个整体排序。 这个排序被称为类的自然排序 ,类的compareTo方法被称为其自然比较方法

      • comparableTo(T o)方法中定义了用sort()方法进行比较的方式
      • 他的规则就是当前的对象如果比o大,则返回1;
      • 当前的对象如果比o小,则返回-1;
      • 当前的对象如果与o相等,则返回0;
    • 只有实现了这个接口的类(重写compareTo方法)才能使用Collections.sort(List list)

      public class Test {
      
      	public static void main(String[] args) {
      		
      		List<Student> list = new ArrayList<Student>();
      		Student stu1 = new Student("afhhg" , 34);
      		Student stu2 = new Student("af" , 14);
      		Student stu3 = new Student("hg" , 24);
      		Student stu5 = new Student("afg" , 4);
      		list.add(stu1);list.add(stu2);list.add(stu3);list.add(stu5);
      		//排序
              Collections.sort(list);
      		for(Student s : list) {
      			System.out.println(s);
      		}
              //倒置
              System.out.println("======");
      		Collections.reverse(list);
      		for(Student s : list) {
      			System.out.println(s);
      		}
      		//随机重置顺序
      		System.out.println("======");
      		Collections.shuffle(list);
      		for(Student s : list) {
      			System.out.println(s);
      		}
      	}
      	
      }
      
      class Student implements Comparable<Student>{
      	private String name ;
      	private int age ;
      	public int compareTo(Student o) {
      		if(this.getAge() > o.getAge()) {
      			return 1;
      		}else if(this.getAge() == o.getAge()) {
      			return 0;
      		}else {
      			return -1 ;
      		}
      	}
      	@Override
      	public String toString() {
      		return "Student [name=" + name + ", age=" + age + "]";
      	}
      	public int getAge() {
      		return age;
      	}
      	public Student(String name , int age) {
      		this.name = name ;
      		this.age = age ;
      	}
      }
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值