java学习第十六天

一. List集合

1. ArrayList

  • 底层:是一个Object[]
  • 长度:0–10–
  • 扩容时机:数组不够用的时候(长度10,添加第11个时)
  • 扩容后的长度:new = old + old >> 1 1.5倍

2. LinkedList

LinkedList是List集合一种实现类,底层是链表

  • 有三个属性, size, Node first, Node last
  • Node 表示就是链表,有三个属性 item(保存值),Node next(下一个), Node prev(上一个)
  • 每一个添加数组
    • 创建一个Node 对象使用item属性保存值
    • 获取原来的最后一个节点,把当前节点的上一个节点设置原来的最后一个节点
    • 把当节点设置最后节点
public class LinkedList<E> extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable {

    //集合中元素个数
	int size = 0;
    
    //头节点  (第一个环)
    Node<E> first;
    
    //未节点 (最后一个环)
    Node<E> last;


    /*
     * 这就是链子上每个环(节点)的类
     * 我们每保存一个值,就会创建一个Node对象
     */
    private static class Node<E> {
        E item;			//保存我们添加的值
        Node<E> next;   //下一个节点
        Node<E> prev;   //上一个节点

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
        
    }
    
    //添加方法
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    
    void linkLast(E e) {
        //获取最后一个节点
        final Node<E> l = last;
        //使用有参构造方法创建一个Node对象,把原来的最后节点设置为当前节点上一个节点
        final Node<E> newNode = new Node<>(l, e, null);
        //把当前节点设置为最后一个节点
        last = newNode;
        //如果是第一次添加,也把当前节点设置为第一个节点
        if (l == null) {
            first = newNode;
        } else {
            //如果不是第一次添加,把原来的最后一个节点后面节点设置为当前节点
             l.next = newNode;  
        }
        //元素个数加1
        size++;
        modCount++;
    }

}
package com.qfedu;

import java.util.LinkedList;
import java.util.List;

public class Demo01 {

	public static void main(String[] args) {
		List<String> list = new LinkedList<String>();
		
		list.add("jackma");
		list.add("pony");
		list.add("robin");
		
		list.set(1, "pony teng");
		
		String name = list.get(1);

		
		list.remove(1);
	}
}

3. 比较ArrayList和LinkedList的区别

  • ArrayList的底层是数组,LinkedList底层是链表
  • ArrayList的查询速快,但是插入和删除的效率低下
  • LinkedList插入和删除的速度快,查询的速度比较慢

4. Vector

Vector是List集合的一个实现类

  • 底层是一个数组,可以看做是一个低配版的ArrayList
  • Vector的方法,都使用synchronized进行修饰,表示的是线程安全的意思
    • 如果在多线程的编程情况下,必须使用线程安全的集合
  • ArrayList和LinkedList都是线程不安全的

二. Set集合

Set集合是Colletion集合的子接口,表示的是无序且不可重复的集合

  • HashSet
  • LinkedHashSet
  • TreeSet

1. HashSet

HashSet是Set集合的一个现实类

  • 底层是HashMap
  • 当保存一个值时,就往HashMap中一个键值对,保存的值作为键值对的key,值就是new出来的Object对象
package com.qfedu;

import java.util.HashSet;
import java.util.Set;

public class Demo03 {

	public static void main(String[] args) {
		
		Set<String> set = new HashSet<String>();
		
		set.add("jackma");
		set.add("pony");
		set.add("pony");
        set.add("robin");
		
		
		Set<A> set2 = new HashSet<A>();
		
		set2.add(new A(1, 1));
		set2.add(new A(2, 1));  //如果出现重复数据,则不会添加成功(不会覆盖前面的值)
		
		System.out.println(set2);
	}
}

class A {
	int b;
	int c;
	
	public A() {
	}
	
	public A(int b, int c) {
		super();
		this.b = b;
		this.c = c;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + c;
		return result;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		A other = (A) obj;
		if (c != other.c)
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "A [b=" + b + ", c=" + c + "]";
	}
	
}

2. LinkedHashSet

LinkedHashSet是Set集合的一个现实类,会保存元素添加的顺序。

package com.qfedu;

import java.util.LinkedHashSet;
import java.util.Set;

public class Demo04 {

	public static void main(String[] args) {
		
		/*
		 * 保存 添加元素顺序的set集合
		 */
		Set<String> set = new LinkedHashSet<String>();
		
		set.add("jackma");
		set.add("pony");
		set.add("pony");
		set.add("robin");
		
		for(String str : set) {
			System.out.println(str);   //按照保存顺序  jackma  pony  robin
		}
	}
}

3. TreeSet

TreeSet是Set集合的一个现实类,可以根据自动规则对数据进行排序

  • 泛型必须实现Comparable接口
  • 判断两个元素是否重复的依据为重写后compareTo方法的结果是否为零
    • 整数 大于
    • 零 等于 后面的元素则会添加失败
    • 负数 小于
  • TreeSet底层为TreeMap
package com.qfedu;

import java.util.Arrays;
import java.util.Set;
import java.util.TreeSet;

public class Demo05 {

	public static void main(String[] args) {

		/*
		 * 1. 把学生信息(对象) 保存在Set集合 2. 根据成绩排序 2.1如果成绩相同,就根据姓名排序 2.2如果成绩和姓名都相同,就根据学号降序
		 * 
		 */

		Student stu1 = new Student("jackma", 96, "1100");
		Student stu2 = new Student("pony", 89, "1200");
		Student stu3 = new Student("jaaes", 96, "1300");
		Student stu4 = new Student("kobe", 91, "1400");

		Student[] arr = { stu1, stu2, stu3, stu4 };

		Arrays.sort(arr);

		for (Student stu : arr) {
			System.out.println(stu);
		}

		System.out.println("===========================================");

		/*
		 * TreeSet会自动为添加的元素排序
		 * 
		 * 1. TreeSet的泛型类,必须实现Comparable接口 2. 判断元素是否重复的标准就是compareTo接口是否为0 3.
		 * 我们使用一定要谨慎使用,一定要比较到那个唯一的属性
		 */
		Set<Student> set = new TreeSet<Student>();
		set.add(stu1);
		set.add(stu2);
		set.add(stu3);
		set.add(stu4);

		for (Student s : set) {
			System.out.println(s);
		}
	}
}

class Student implements Comparable<Student> {

	String name;
	int score;
	String code;

	public Student(String name, int score, String code) {
		super();
		this.name = name;
		this.score = score;
		this.code = code;
	}

	/*
	 * 整数 大于 零 等于 负数 小于
	 */
	@Override
	public int compareTo(Student o) {

		
		  int r = score - o.score;
		  
		  if(r != 0) { return r; }
		  
		  r = this.name.compareTo(o.name);
		  
		  if (r != 0) { return r; }
		  
		  return this.code.compareTo(o.code);
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", score=" + score + ", code=" + code + "]";
	}

	
	/*
	 * 定义手机类
	 * 价格  double
	 * 重量  double
	 * 编号  String
	 * 
	 * 价格降序排列
	 * 价格相同,重量升序排
	 * 价格,重量都相同,则根据编号升序
	 */
	
}

三. Map

在java中使用集合,就这三种:List Set Map

Map是一种集合,是一种键值对的集合,说白了,就是在保存一个值的时候,给这个值起个名字

public interface Map<K,V> {

    //返回键值对的个数
    int size();
    //判断是否为空
    boolean isEmpty();
    //是否包含key或者value
	boolean containsKey(Object key);
    boolean containsValue(Object value);
    //
    V get(Object key);
    //添加
	V put(K key, V value);
    //根据key删除
    V remove(Object key);
    void putAll(Map<? extends K, ? extends V> m);
    //清空
    void clear();
    
    //获取所有键值对的key
    Set<K> keySet();
    Collection<V> values();
    /*
     * 每一个键值对,都可以看做一个Entry<K, V>对象
     * 我们可以通过获取每一个Entry<K, V>对象获取其中key和value值
     */
    Set<Map.Entry<K, V>> entrySet();
    
    
    interface Entry<K,V> { 
    	 K getKey();
    	 V getValue();
         V setValue(V value);
    }
    
}

1. 常用方法

package com.qfedu;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class Demo06 {

	public static void main(String[] args) {
		
		/*
		 * Map:表示的是一种键值对的集合:相当于在保存一个值时,给这个值起一个名
		 * 把保存的值成为value,把给这个值起的名字叫做键:key
		 * 在定义Map时,需要定义两个泛型,第一个泛型表示key的类型,第二个泛型表示保存值(value)的类型
		 */
		Map<Integer, String>  map = new HashMap<Integer, String>();
		
		/*
		 * isEmpty() 判断是否为空
		 */
		System.out.println(map.isEmpty());
		
		
		/*
		 * V put(K key, V value);    添加值,,修改值
		 * 1. key不能重复,如果出现出现的key,不会添加成功,但后面的value会覆盖掉前面的value。
		 * 		1.1 重复的条件:equals结果为ture,hashCode要相等
		 * 2. key,value都可以为null
		 */
		map.put(1, "鲁迅");
		map.put(2, "李敖");
		map.put(3, "莫言");
		map.put(3, "余华");
		map.put(null, null);
		
		/*
		 * int size();    获取保存值的个数
		 */
		int size = map.size();
		System.out.println(size);
		
		/*
		 *  V get(Object key);    根据key获取保存的值
		 */
		String v = map.get(3);
		System.out.println(v);
		
		
		/*
		 * boolean containsKey(Object key);
		 * boolean containsValue(Object value);
		 */
		System.out.println(map.containsKey(2));
		System.out.println(map.containsValue("莫言"));
		
		/*
		 * V remove(Object key);
		 */
		map.remove(null);
		System.out.println(map.size());
		
		
		/*
		 * 遍历map集合
		 * 1. 先获取所有的key,根据key获取所有的value
		 * 2. 获取Entry的集合,遍历得到每一个Entry对象
		 */
		Set<Integer> keySet = map.keySet();
		for (Integer key : keySet) {
			System.out.println("key:"+key+"  value:"+map.get(key));
		}
		
		/*
		 * 我们保存的每个键值对,都可以看做是一个Entry的对象
		 */
		Set<Entry<Integer, String>> entrySet = map.entrySet();
		
		for(Map.Entry<Integer, String> entry :  entrySet) {
			System.out.println(entry.getKey() +":"+entry.getValue());
		}
		
	}
}

2. 常用实现类

  • HashMap
  • Hashtable
  • TreeMap

2.1 HashMap

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable { 
    
    //添加键值对的个数
    transient int size;
    //默认初始化容量(长度)
	static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
	//最大容量
    static final int MAXIMUM_CAPACITY = 1 << 30;
    //默认加载因子(数组扩容的一个临界值)
    static final float DEFAULT_LOAD_FACTOR = 0.75f;
	//树化的阈值  (二叉树,红黑树)
    static final int TREEIFY_THRESHOLD = 8;
    //反树化的阈值  (二叉树,红黑树)
    static final int UNTREEIFY_THRESHOLD = 6;
    //最小树化容量
    static final int MIN_TREEIFY_CAPACITY = 64;
    
    int threshold;
    
    final float loadFactor;
    
    //就是添加键值对的位置
    transient Node<K,V>[] table;
    
    //我们往map集合中添加一个键值对时,实际上添加就是Node对象
    static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;  //保存的Key的hashCode值
        final K key;     //保存key值
        V value;		 //保存value值
        Node<K,V> next;  //保存下面的那个Node对象   单向链表

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public final K getKey()        { return key; }
        public final V getValue()      { return value; }
        public final String toString() { return key + "=" + value; }

        public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }

        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }

        public final boolean equals(Object o) {
            if (o == this)
                return true;
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                if (Objects.equals(key, e.getKey()) &&
                    Objects.equals(value, e.getValue()))
                    return true;
            }
            return false;
        }
    }
    
    /*
      *	有参构造方法
      * initialCapacity : 初始容量
      * loadFactor :加载因子
      */
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);
    }
    
    
    public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }
    
    public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
    }
    
}

2.2 Hashtable

Hashtable是Map集合的一个实现类,它是线程安全的

2.3 TreeMap

TreeMap是Map集合的一个实现类,它会显示对Key值的自动排序

package com.qfedu;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class Demo07 {

	public static void main(String[] args) {
		Map<String,String> map = new HashMap<String,String>(19,77);
		
		
		Map<String,String> map2 = new Hashtable<String,String>(19,77);
		
		
		Map<String,Integer> map3 = new TreeMap<String,Integer>();
		
		map3.put("jackma",88);
		map3.put("abert",99);
		map3.put("bean",33);
		map3.put("macke",21);
		map3.put("wade",56);
		
		Set<String> keySet = map3.keySet();
		for(String key : keySet) {
			System.out.println(key +":"+ map.get(key));
		}
		
	} 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值