java容器总结

java容器总结

容器分类:
在这里插入图片描述
容器与集合的相似点:

  • 都可以存储多个对象,对外作为一个整体。

数组的缺点:

  • 长度必须在初始化时指定,固定不变。
  • 采用连续存储空间,删除和添加效率低下。
  • 数组无法直接保存映射关系。
  • 数组缺乏封装,操作繁琐。

集合架构

  • collection接口存储一组不唯一无序的对象
  • List接口存储不唯一、有序(索引顺序)的对象
  • set接口存储一组唯一、无序的对象
  • map接口存储一组键值对象,提供key到value的映射。key唯一无序,value不唯一无序。

List

在这里插入图片描述

  • 特点:有序、不唯一。

  • ArrayList线性表中的顺序表:
    在这里插入图片描述

    • 内存中分配连续的空间,长度可变的数组。
    • 优点:遍历元素和随机访问元素的效率高
    • 缺点:添加、删除、需要大量的移动元素效率低。
public class SxtArrayList01 {
	
	private Object[]  elementData;
	private int  size;
	
	private static final int DEFALT_CAPACITY = 10 ;
	
	
	public SxtArrayList01(){
		elementData = new Object[DEFALT_CAPACITY]; 
	}
	
	public SxtArrayList01(int  capacity) {
		elementData  = new Object[capacity];
	}
	
	public  void  add(Object  obj){
		elementData[size++] = obj;
	}
	
	@Override
	public String toString() {
		
		StringBuilder  sb = new StringBuilder();
		
		//[a,b,c]
		sb.append("[");
		for(int i=0;i<size;i++){
			sb.append(elementData[i]+",");
		}
		sb.setCharAt(sb.length()-1, ']'); 
		
		return  sb.toString();
	}
	
	
	public static void main(String[] args) {
		SxtArrayList01  s1 = new SxtArrayList01(20);
		s1.add("aa");
		s1.add("bb");
		
		System.out.println(s1);
		
	}
	
	
}

  • LinkedList线性表中双向链表:
    在这里插入图片描述

    • 采用双向链表存储
    • 缺点:遍历和随机访问效率低
    • 优点:插入、删除效率高
  • List常用方法:
    相对collection增加了关于位置的操作方法。

  • List遍历方法:

    • for、foreach、迭代器。
    • 使用equals进行集合内容的比较
public class SxtLinkedList01 {
	
	private   Node  first;
	private  Node  last;
	
	private  int size;
	

	public  void  add(Object  obj) {
		Node  node  = new Node(obj);
		
		if(first==null){
//			node.previous = null;
//			node.next = null;
			first = node;
			last = node;
		}else{
			
			node.previous = last;
			node.next = null;
			
			last.next = node;
			last = node;
			
		}
		
		
	}
	
	@Override
	public String toString() {
		//[a,b,c]     first=a,    last=c
		//a,b,c
		StringBuilder   sb = new StringBuilder("[");
		Node  temp = first;
		while(temp!=null){
			sb.append(temp.element+",");
			temp = temp.next;
		}
		sb.setCharAt(sb.length()-1, ']'); 
		
		return sb.toString();
	}	
	
	public static void main(String[] args) {
		SxtLinkedList01  list = new SxtLinkedList01();
		
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		list.add("e");
		list.add("f");
		
		System.out.println(list);
		
		
	}
	
	
}

定义节点:

public class Node {
	
	
	Node  previous;		//上一个节点
	Node next;				//下一个节点
	
	
	Object element;		//元素数据
	
	
	
	public Node(Node previous, Node next, Object element) {
		super();
		this.previous = previous;
		this.next = next;
		this.element = element;
	}



	public Node(Object element) {
		super();
		this.element = element;
	}
	
	
	
	
}
  • Set

  • 特点:无序、唯一

  • HashSet:
    在这里插入图片描述
    - 采用Hashtable哈希表存储结构
    - 缺点:无序
    - 优点:添加速度快、查询、删除速度快。

public class SxtHashSet {
	
	HashMap map;
	
	private static final Object  PRESENT = new Object();
	
	public SxtHashSet() {
		map = new HashMap();
	}
	
	public  int  size(){
		return  map.size();
	}
	
	public void add(Object o){
		map.put(o, PRESENT);
	}
	
	@Override
	public String toString() {
		
		StringBuilder   sb = new StringBuilder();
		sb.append("[");
		
		for(Object key:map.keySet()){
			sb.append(key+",");
		}
		sb.setCharAt(sb.length()-1, ']');  
		return  sb.toString();
		
	}
	
	public static void main(String[] args) {
		SxtHashSet   set = new SxtHashSet();
		set.add("aaa");
		set.add("bbb");
		set.add("ccc");
		
		System.out.println(set);
		
	}
	
}
  • LinkedHashSet:

    • 采用哈希表存储结构,同时使用链表维护次序,有序。
  • TreeSet:
    在这里插入图片描述

    • 采用二叉树的存储结构
    • 优点:有序、查询速度比list快
    • 缺点:查询速度没有HashSet快
    • Set常用方法:
      相对cellection没有增加任何方法
    • Set的遍历方法:
      for、foreach、迭代器
public class TestTreeSet {
	public static void main(String[] args) {
		Set<Integer>  set = new TreeSet<>();
		
		set.add(300);
		set.add(200);
		set.add(600);
		
		//按照元素递增的方式排好序
		for(Integer m:set){
			System.out.println(m);
		}
		
		Set<Emp2>  set2 = new TreeSet<>();
		set2.add(new Emp2(100,"张三",3000));
		set2.add(new Emp2(50,"李四",2000));
		set2.add(new Emp2(150,"王五",8000));
		set2.add(new Emp2(30,"赵六",20000));
		
		for(Emp2 m:set2){
			System.out.println(m);
		}
		
	}
}



class Emp2  implements Comparable<Emp2>  {
	int id;
	String name;
	double salary;
	
	public Emp2(int id, String name, double salary) {
		super();
		this.id = id;
		this.name = name;
		this.salary = salary;
	}

	@Override
	public String toString() {
		return  "id:"+id+",name:"+name+",salary:"+salary;
	}
	
	@Override
	public int compareTo(Emp2 o) {		//负数:小于,0:等于,正数:大于
		
		if(this.salary>o.salary){
			return 1;
		}else if(this.salary<o.salary){
			return -1;
		}else{
			if(this.id>o.id){
				return 1;
			}else if(this.id<o.id){
				return -1;
			}else{
				return 0;
			}
		}
		
	}
	
}


 -  HashSet、HashMap、Hashtable对象唯一性判断: 重写hashcode()、equals()方法。
  • Map:

    • 特点:key-value映射
    • HashMap:
      • key无序,唯一(set)
      • value无序、不唯一(collection)
public class HashMap04<K,V> {
	
	Node3[]  table;    //位桶数组。bucket  array
	int size;				//存放的键值对的个数
	
	public SxtHashMap04() {
		table = new Node3[16];    //长度一般定义成2的整数幂
	}
	
	
	public  V  get(K  key){
		
		int  hash = myHash(key.hashCode(), table.length);
		V value = null; 
		
		if(table[hash]!=null){
			Node3  temp = table[hash];
			
			while(temp!=null){
				
				if(temp.key.equals(key)){   //如果相等,则说明找到了键值对,返回相应的value
					value = (V)temp.value;
					break;
				}else{
					temp = temp.next;
				}
			}
			
		}
		
		return value;
	}
	
	
	public  void   put(K key,  V   value){
		
		//如果要完善,还需要考虑数组扩容的问题!!!
		
		//定义了新的节点对象
		Node3    newNode = new Node3();
		newNode.hash = myHash(key.hashCode(),table.length);
		newNode.key =  key;
		newNode.value = value;
		newNode.next = null;
		
		Node3 temp = table[newNode.hash];
		
		Node3  iterLast = null;  //正在遍历的最后一个元素
		boolean  keyRepeat = false;  
		if(temp==null){
			//此处数组元素为空,则直接将新节点放进去
			table[newNode.hash] = newNode;
			size++;
		}else{
			//此处数组元素不为空。则遍历对应链表。。
			while(temp!=null){
				
				//判断key如果重复,则覆盖
				if(temp.key.equals(key)){
					keyRepeat = true;
					temp.value =  value;  //只是覆盖value即可。其他的值(hash,key,next)保持不变。
					
					break;
					
				}else{
					//key不重复,则遍历下一个。
					iterLast = temp;
					temp = temp.next;
					
				}
			}
			
			if(!keyRepeat){   //没有发生key重复的情况,则添加到链表最后。
				iterLast.next = newNode;
				size++;
			}
			
		}
		
		
		
	}

	
	@Override
	public String toString() {
		//{10:aa,20:bb}
		StringBuilder  sb = new StringBuilder("{");
		
		//遍历bucket数组
		for(int i=0;i<table.length;i++){
			Node3  temp = table[i]; 
			
			//遍历链表
			while(temp!=null){
				sb.append(temp.key+":"+temp.value+",");
				temp  = temp.next;
			}
		}
		sb.setCharAt(sb.length()-1, '}'); 
		return sb.toString();
		
	}
	
	
	public static void main(String[] args) {
		SxtHashMap04<Integer,String>  m = new SxtHashMap04<>();
		m.put(10, "aa");
		m.put(20, "bb");
		
		System.out.println(m.get(85));  
		
	}
	
	
	public static  int  myHash(int  v, int length){
//		System.out.println("hash in myHash:"+(v&(length-1)));		//直接位运算,效率高
//		System.out.println("hash in myHash:"+(v%(length-1)));		//取模运算,效率低
		return  v&(length-1);
	}
	
	
}



定义节点:

public class Node3<K,V> {
	
	int  hash;
	K  key;
	V  value;
	Node3  next; 
	
}
  • LinkedHashMap:
    有序的HashMap,速度快

  • TreeMap:
    有序、速度没有hash快

public class TestTreeMap {
	public static void main(String[] args) {
		Map<Integer,String>  treemap1 = new TreeMap<>();
		treemap1.put(20, "aa");
		treemap1.put(3, "bb");
		treemap1.put(6, "cc");
		
		//按照key递增的方式排序
		for(Integer  key:treemap1.keySet()){
			System.out.println(key+"---"+treemap1.get(key)); 
		}
		
		
		Map<Emp,String>  treemap2 = new TreeMap<>();
		treemap2.put(new Emp(100,"张三",50000), "张三是一个好小伙");
		treemap2.put(new Emp(200,"李四",5000), "李四工作不积极");
		treemap2.put(new Emp(150,"王五",6000), "王五工作还不错");
		treemap2.put(new Emp(50,"赵六",6000), "赵六是个开心果");
		
		//按照key递增的方式排序
		for(Emp  key:treemap2.keySet()){
			System.out.println(key+"---"+treemap2.get(key)); 
		}		
		
	}
}

class Emp  implements Comparable<Emp>  {
	int id;
	String name;
	double salary;
	
	public Emp(int id, String name, double salary) {
		super();
		this.id = id;
		this.name = name;
		this.salary = salary;
	}

	@Override
	public String toString() {
		return  "id:"+id+",name:"+name+",salary:"+salary;
	}
	
	@Override
	public int compareTo(Emp o) {		//负数:小于,0:等于,正数:大于
		
		if(this.salary>o.salary){
			return 1;
		}else if(this.salary<o.salary){
			return -1;
		}else{
			if(this.id>o.id){
				return 1;
			}else if(this.id<o.id){
				return -1;
			}else{
				return 0;
			}
		}
		
	}
	
}

set和map的关系:采用了相同的数据结构、只用于map的key,存储数据为set。

  • Iterator:
    • 产生的原因:集合类均未提供相应的遍历方法,将遍历交给迭代器

    • 方法:

      • boolean hasNext():判断是否存在另一个可访问的元素
      • Object next(): 返回要访问的下一个元素
      • void remove(): 删除上次访问返回的对象
    • For-each循环

      • 增强的for循环,遍历array 或 Collection的时候相当简便。
      • 无需获得集合和数组长度,无需使用索引访问元素,无需循环条件。
      • 遍历集合时底层调用Iterator完成操作。
      • For-each缺陷:
        • 数组:不能方便的访问下标值,不要在for-each中尝试对变量赋值,只是一个临时变量。
        • 集合:与使用Iterator相比,不能方便的删除集合中的内容。
    • ListIterator和Iterator的关系:
      public interface ListIterator extends Iterator,都可以遍历List。

    • ListIterator和Iterator的区别:

      • 使用范围不同:Iterator可以应用于更多的集合,Set、List和这些集合的子类型。而ListIterator只能用于List及其子类型。
      • 遍历顺序不同:Iterator只能顺序向后遍历; ListIterator还可以逆序向前遍历。Iterator可以在遍历的过程中remove();ListIterator可以在遍历的过程中remove()、add()、set()。
      • ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
public class TestIterator {
	public static void main(String[] args) {
//		testIteratorList();
//		testIteratorSet();
//		testIteratorMap();
		
		testRemove();
	}
	
	public static void testIteratorList(){
		List<String>  list = new ArrayList<>();
		list.add("aa");
		list.add("bb");
		list.add("cc");
		
		//使用iterator遍历List
		for(Iterator<String> iter=list.iterator();iter.hasNext();){
			String  temp = iter.next();
			System.out.println(temp);
		}
		
	}
	
	public static void testIteratorSet(){
		Set<String>  set = new HashSet<>();
		set.add("aa");
		set.add("bb");
		set.add("cc");
		
		//使用iterator遍历Set
		for(Iterator<String> iter=set.iterator();iter.hasNext();){
			String  temp = iter.next();
			System.out.println(temp);
		}
		
	}
	
	public static void testIteratorMap(){
		Map<Integer,String> map1 = new HashMap<>();
		map1.put(100, "aa");
		map1.put(200, "bb");
		map1.put(300, "cc");
		

		//第一种遍历Map的方式
		Set<Entry<Integer,String>>  ss =  map1.entrySet();
		for(Iterator<Entry<Integer,String>>  iter=ss.iterator();iter.hasNext();){
			Entry<Integer,String> temp = iter.next();
			
			System.out.println(temp.getKey()+"--"+temp.getValue());
			
		}
		System.out.println("++++++++++++++++++++++++");
		//第二种遍历Map的方式
		Set<Integer>  keySet = map1.keySet();
		for(Iterator<Integer> iter=keySet.iterator();iter.hasNext(); ){
			Integer key = iter.next();
			System.out.println(key+"----"+map1.get(key));
		}
		
		
	}
	
	//测试边遍历,边删除
	public static void testRemove(){
		List<String> list = new ArrayList<>();
		for(int i=0;i<20;i++){
			list.add("gao"+i);
		}
		
		for(int i=0;i<list.size();i++){
			String temp = list.get(i);
			if(temp.endsWith("2")){
				list.remove(i);
			}
			System.out.println(list.size()); 
			System.out.println(list.get(i));  
		}
		
		
	}
	
}

  • Collections:
    • 专门用来操作集合的工具类
    • 构造方法私有,禁止创建对象
    • 提供一系列静态方法实现对各种集合的操作
    • 具体操作:搜索、复制、排序、线程安全化等
    • 常用方法:
      • Collections.addAll(list, “aaa”,“bbb”,“ccc”,“ccc”);
      • int index = Collections.binarySearch(list, “ccc”);
      • Collections.copy(list2, list);
      • Collections.fill(list3, “888”);
      • String max = Collections.max(list4);
      • String min = Collections.min(list4); • Collections.reverse(list4); • List list5 = Collections.synchronizedList(list4);
    • Collection和Collections的区别:
      • Collection是Java提供的集合接口,存储一组不唯一,无序的对象。它有两个子接口 List和Set。
      • Java中还有一个Collections类,专门用来操作集合类 ,它提供一系列静态方法实现对 各种集合的搜索、排序、线程安全化等操作。
public class TestCollections {
	public static void main(String[] args) {
		List<String>  list  = new ArrayList<>();
		for(int i=0;i<10;i++){
			list.add("gao:"+i);
		}
		System.out.println(list);
		
		Collections.shuffle(list);	//随机排列list中的元素
		System.out.println(list);
		
		Collections.reverse(list); //逆序排列
		System.out.println(list);
		
		Collections.sort(list);		//按照递增的方式排序。自定义的类使用:Comparable接口。
		System.out.println(list);
		
		System.out.println(Collections.binarySearch(list, "gao:1")); 	//二分法查找,或者:折半查找
		
		
	}
}
  • vector:
    • 实现原理和ArrayList相同,功能相同,长度可变的数组结构。
    • 两者的主要区别如下:
      • Vector是早期JDK接口,ArrayList是替代Vector的新接口。
      • Vector线程安全,效率低下;ArrayList重速度轻安全,线程非安全。
      • 长度需增长时,Vector默认增长一倍,ArrayList增长50%。
public class TestVector {
	public static void main(String[] args) {
		List<String>  a = new Vector();
	}
}
  • Hashtable类:
    • 实现原理和HashMap相同,功能相同,底层都是哈希表结构,查询速度快,很多情况下可互用。
    • 两者的主要区别如下:
      • Hashtable是早期JDK提供的接口,HashMap是新版JDK提供的接口。
      • Hashtable继承Dictionary类,HashMap实现Map接口。
      • Hashtable线程安全,HashMap线程非安全。
      • Hashtable不允许null值,HashMap允许null值。
  • 集合和数组的比较:
    • 数组不是面向对象的,存在明显的缺陷,集合完全弥补了数组的一些缺点,比数组更灵活更实 用,可大大提高软件的开发效率而且不同的集合框架类可适用于不同场合。
    • 数组容量固定且无法动态改变,集合类容量动态改变。
    • 数组能存放基本数据类型和引用数据类型的数据,而集合类中只能放引用数据类型的数据。
    • 数组无法判断其中实际存有多少元素,length只告诉了array容量;集合可以判断实际存有多 少元素,而对总的容量不关心。
    • 集合有多种数据结构(顺序表、链表、哈希表、树等)、多种特征(是否有序,是否唯一)、 不同适用场合(查询快,便于删除、有序),不像数组仅采用顺序表方式。
    • 集合以类的形式存在,具有封装、继承、多态等类的特性,通过简单的方法和属性调用即可 实现各种复杂操作,大大提高软件的开发效率。
  • 集合总结在这里插入图片描述 在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值