java复习笔记————集合和泛型小总结

集合

Java中的集合,指一系列存储数据的接口和类,可以解决复杂的数据存储问题.
导包:import java.util.*;

简化的集合框架图:

在这里插入图片描述

集合框架图:

在这里插入图片描述

这里只终结经常用的ArrayList,LinkedList、HashSet以及HashMap,有的内容会以仿写源码的方式来实现一些经常用到的方法

集合框架是一个用来代表和操纵集合的统一架构。所有的集合框架都包含如下内容:

  • 接口:是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。之所以定义多个接口,是为了以不同的方式操作集合对象
  • 实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap。
  • 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现

List

在这里插入图片描述

ArrayList

类似于数组但是ArrayList的长度是动态增加的,所以也被称为动态数组

这里我们通过仿写源码的方法来了解下是怎么实现的

在eclipse中按F3可以查看相关的源码

import java.util.List;

//模仿标准库提供的 ArrayList
class ArrayList_02 < E > {//泛型类
	
	// 默认容量
	private static final int DEFAULT_CAPACITY = 10;
 
	// 存放数据的空间
	transient Object[] elementData; 

	// 实际存放元素的个数
	private int size;
 
 
	// 默认构造
	public ArrayList_02() {

		elementData = new Object[DEFAULT_CAPACITY];
	}
 
	// 有参构造
	public ArrayList_02( int capacity ) {

		if ( capacity < 0 ) {
			
			throw new RuntimeException("容器的容量不能为负数!");
		}
		else if ( capacity == 0 ) {
			
			elementData = new Object[DEFAULT_CAPACITY];
		}
		else {
			
			elementData = new Object[capacity];
		}
	}
 
	// 在末尾添加一个元素
	public void add( E element ) {//泛型方法
		
		// 什么情况下需要扩容
		if ( size == elementData.length ) {
			
			// 如何扩容
			// 1. 在一个新的地方重新开辟一块内存空间,大小为原来的 1.5倍
			Object[] newArray = new Object[ elementData.length + (elementData.length>>1) ]; 
			
			// 2. 将原来的容器的内容 全部按顺序 复制到新容器中
			System.arraycopy( elementData, 0, newArray, 0, elementData.length);
			
			// 3. 将新的空间交给 elementData 来引用
			elementData = newArray;
		}
		
		elementData[size++] = element;
	}
 
 
	// toString 重写
	@Override
	public String toString() {

		StringBuffer strbuf = new StringBuffer();
 	
		// [1, 2, 3]
		strbuf.append("[");
		if(size!=0) {
 	
			for ( int i=0; i<size; i++ ) {
	 		
				strbuf.append( elementData[i] + ", " );
			}
			strbuf.setCharAt(strbuf.length()-2, ']');
		}else {
			strbuf.append("]");
		}
		return strbuf.toString();
	}
	
	
	// get 
	public E get( int index ) {
		
		// 判断 index 是否在  容器的长度范围内
		if ( index < 0 || index >= size ) {
			
			// 不合法,需要抛异常
			throw new RuntimeException( "需要访问的 ["+ index +"] 索引(下标)访问超出容器的实际长度!" );
		}
				
		return (E)elementData[index];
	}
	
	// set
	public void set( int index, E element ) {
		
		// 判断 index 是否在  容器的长度范围内
		if ( index < 0 || index >= size ) {
			
			// 不合法,需要抛异常
			throw new RuntimeException( "需要访问的 ["+ index +"] 索引(下标)访问超出容器的实际长度!" );
		}
		
		elementData[index] = element;
	}
	
	
	// 按位置
	public void remove( int index ) {
		
		// 判断 index 是否在  容器的长度范围内
		if ( index < 0 || index >= size ) {
			
			// 不合法,需要抛异常
			throw new RuntimeException( "需要访问的 ["+ index +"] 索引(下标)访问超出容器的实际长度!" );
		}
		
		// 计算后面有多少的个元素需要向前挪动一格
		int needmovenum = elementData.length-index-1;
		
		// 当 删除的位置不是最后一个的时候
		if ( needmovenum > 0 ) {
			
			System.arraycopy(elementData, index+1, elementData, index, needmovenum);
		}
		
		// 将原容器最后一个位置上的元素 置空
		elementData[--size] = null;
	}
	
	// 按内容
	public void remove( E element ) {
		// 遍历容器找到和 element 一样的元素
		for ( int i=0; i<size; i++ ) {
			
//			if ( element.equals( get(i) )) {
			if ( element.equals( elementData[i] )) {
				
				// 将该位置上的元素 删除
				remove(i);
				
				return;
			}
		}
		
		throw new RuntimeException(" 需要删除的内容,不在当前容器中!");
	}

	//获取长度
	public int  size() {		
		return size;
	}

	//判断是否为空。空则返回true,否则返回false
	public boolean isempty() {
		// TODO Auto-generated method stub
		if(size<=0)
			return true;
		else
			return  false;
	}

	//清空集合
	public void clear() {
		// TODO Auto-generated method stub
		for ( int i=0; i<size; i++ ) {
			elementData[size] = null;
		}
		size=0;
	}

	//判断是否包含某个元素
	public boolean contains(String str) {
		for ( int i=0; i<size; i++ ) {
			if ( str.equals( elementData[i] )) {
				return true;
				}
			
		}
		return false;
	}
}





public class Code_004 {

	public static void main(String[] args) {
		ArrayList_02 arr_02 = new ArrayList_02(5);
		
		arr_02.add("qwer");
		arr_02.add("asdw");
		arr_02.add("qwer_01");
		arr_02.add("asdw_01");
		arr_02.add("qwer_02");
		arr_02.add("asdw_02");
		
	//	System.out.println(arr_02);

		
//		arr_02.set(7, "777");
		
//		arr_02.remove(6);
//		arr_02.remove("777");
		
//		arr_02.remove(5);
		//arr_02.remove("qwer");
		
		System.out.println(arr_02.contains("qwer"));
		System.out.println(arr_02.size());
		System.out.println(arr_02.isempty());
		System.out.println(arr_02);
		arr_02.clear();
		System.out.println(arr_02);
	}
}
遍历ArrayList的方法
import java.util.*;
    public class ListTraversal {
        public static void main(String[] args) {
            m010Traversal();
            m020线程安全版();
        }
        private static void m010Traversal() {
            System.out.println("=====遍历");
            List<String> lst = new ArrayList<String>();
            lst.add("西藏");
            lst.add("拉萨");
            lst.add("土耳其");
// (1)
            for (int i = 0; i < lst.size(); i++) {
                System.out.println("for遍历集合:" + lst.get(i));
            }
// (2)
            for (String s : lst) {
                System.out.println("foreach遍历集合:" + s);
            }
// (3)Iterator,迭代器。用于遍历(迭代访问)集合中的元素
            Iterator<String> it = lst.iterator();
            while (it.hasNext()) {
                System.out.println("Iterator遍历:" + it.next());
            }
// (4)Java 8:调用forEach()方法遍历集合
            lst.forEach(s -> System.out.println("Lambda表达式遍历集合:" + s));
        }
    // API文档上说ArrayList不是同步的,即多线程环境下不安全
// Collections.synchronizedList(...)将其转为线程安全的列表
            private static void m020线程安全版() {
                System.out.println("=====线程安全版");
                List<String> lst = new ArrayList<String>();
                lst.add("西藏");
                lst.add("拉萨");
                lst.add("土耳其");
        // 解决线程安全问题
                List<String> synList = Collections.synchronizedList(lst);
                for (String s : synList) {
                    System.out.println("foreach遍历集合:" + s);
                }
            }
}

LinkedList

LinkedList原理图示

在这里插入图片描述
LinkedList特有的方法:

在这里插入图片描述

import java.util.LinkedList;
    public class TestLinkedList {
        public static void main(String[] args) {
            LinkedList<String> link = new LinkedList<String>();
// addFirst:头部添加数据
            link.addFirst("A");
            link.addFirst("B");
            link.addFirst("C");
            link.removeFirst();
            System.out.println(link);
// addLast:尾部添加数据
            link.addLast("A");
            link.addLast("B");
            link.addLast("C");
            link.removeLast();
            System.out.println(link);
            link.clear();// 清空
// push:将元素推入栈,等效于addFirst()
            link.push("A");
            link.push("B");
            link.push("C");
// pop:出栈,调用的是removeFirst()
            link.pop();
            System.out.println("栈" + link);
            link.clear();// 清空
// 将指定元素添加到此列表的末尾(最后一个元素)。
// offer:入队列:调用的是add方法,add又调用linkLast,和addLast  一样
            link.offer("A");
            link.offer("B");
            link.offer("C");
// poll:出队列:调用的是removeFirst()
            link.poll();
            System.out.println("队列" + link);
        }
    }

在终端的结果

[B, A]

[B, A, A, B]

栈[B, A]

队列[B, C]

Hash表

Java8之前:Hash表使用数组+链表
Java8之后加入了红黑树,查询速度加快

在这里插入图片描述

HashSet

没有重复数据,数据不按存入顺序。

由Hash表结构(实际上是一个HashMap实例)支持。

不支持set的迭代顺序,不保证顺序恒久不变。

Hash表结构查询速度快。

HashSet的遍历

public static void main(String[] args) {
    Set s = new HashSet();
    // 存
    s.add("a");
    s.add("a"); // 只会显示一个 a
    s.add("sss");
    s.add(1);
    s.add(2);
    s.add("你好");
    s.add(true);
    System.out.println(s);
    /**
     * set 没有所以你的概念,因此只能使用迭代器 或者 增加的 for 循环来遍历
     * */
    // 取
    System.out.println("=============== iterator 迭代 ===========");
    Iterator it = s.iterator();
    // 迭代过程不可以移除数据
    while (it.hasNext()) { // 查看是否有下一个
        System.out.println(it.next());
    }

    System.out.println("=========== 增强的 for 循环 ==============");
    // foreach (迭代的过程不能移除元素)
    for (Object o: s) {
        System.out.println(o);
    }

    System.out.println("=========== Lambda表达式 ==============");
    // (3)*Java 8新增遍历方法
    s.forEach(elm -> System.out.println("Lambda:" + elm));

    // 移除
    s.remove("aaa");
}

HashMap

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

存储K-V,使用key来区分

    import java.util.*;
    public class TestHashMap {
        public static void main(String[] args) {
            Map<Integer, String> map = new HashMap<>();
// 新k返回null,旧k返回旧v
            String put = map.put(1, "A");
            System.out.println("之前没有此K的V:" + put);
            put = map.put(1, "B");
            System.out.println("之前有同K的V:" + put);
            System.out.println(map);
// get:有k返回v,无k返回null
            String v = map.get(2);
            System.out.println(v);
            v = map.get(1);
            System.out.println(v);
// containsKey/containsValue
            boolean containsKey = map.containsKey(2);
            boolean containsValue = map.containsValue("B");
// remove:删k返回v;删无可删,返回null
            String remove = map.remove(2);
            System.out.println(remove);
            remove = map.remove(1);
            System.out.println(remove);
        }
    }

HashMap的遍历

import java.util.*;
    public class TestMap1Hash {
        public static void main(String[] args) {
            Map<String, String> _map = new HashMap<String, String>();
            _map.put("1", "悟空");
            _map.put(null, "白龙");
            _map.put("2", "悟能");
            _map.put("3", "悟净");
            System.out.println("------foreach语法遍历map(输出K-V)------ ");
            for (String _key : _map.keySet()) {
                System.out.print("key = " + _key);
                System.out.println(" value = " + _map.get(_key));
            }
            System.out.println("------Java 8.forEach:Lambda------");
            _map.forEach((k, v) -> System.out.println(k + ":" + v));
            System.out.println("------使用迭代器迭代map(输出V)------");
// 1.获取值的Collection
            Collection<String> _values = _map.values();
// 2.通过Collection获得迭代器
            Iterator<String> it = _values.iterator();
// 3.输出值
            while (it.hasNext()) {
                String next = it.next();
                System.out.println(next);
            }
            
            System.out.println("-----Map.Entry<K,V>-----");
// Map.Entry<K,V>是Map的内部接口,称为映射项(键-值对)
            Set<Map.Entry<String,String>> entrySet = _map.entrySet();
            System.out.println("=====Map.Entry<K,V>:for循环=====");
            for (Map.Entry<String, String> entry : entrySet) {
                System.out.println(entry.getKey() + ":" +
                        entry.getValue());
            }
            System.out.println("=====Map.Entry<K,V>:迭代器=====");
            Iterator<Map.Entry<String, String>> iterator =
                    entrySet.iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, String> next = iterator.next();
                System.out.println(next.getKey() + ":" +
                        next.getValue());
            }
        }
    }

泛型

泛型类和泛型方法在ArrayList中都有就不再举例

泛型接口

    public interface Plane<T> {
        void getP();
        void setP(T t);
    }
    static class WarmPlane<T> implements Plane<T>{
        String fun = "运输";
        @Override
        public void getP() {
                System.out.println(fun);
        }

        @Override
        public void setP(T t) {
            fun += "-----" + (String) t;
        }

    }

    public static void main(String[] args) {
        WarmPlane wl=new WarmPlane();
        wl.getP();
        wl.setP("预警");
        wl.getP();
    }
原创文章 73 获赞 64 访问量 2719

猜你喜欢

转载自blog.csdn.net/qq_42147171/article/details/105401506