什么是集合?

定义:

存储多个同一类型的元素。

所属包:

java.util

与数组的对比:

什么是集合?_第1张图片

浅谈数据结构

什么是集合?_第2张图片

  • 栈:先进后出,后进先出

什么是集合?_第3张图片

  • 队列:先进先出

什么是集合?_第4张图片

  • 数组:查询快(根据索引值找元素),增删慢

什么是集合?_第5张图片

  • 链表:查询慢,增删快

什么是集合?_第6张图片

红黑树:查询、增删都比较快

什么是集合?_第7张图片

集合的分类:

1.双列集合(Map接口):一个元素由K,V两部分组成;

  • HashMap:底层是哈希表。无序

  • LinkedHashMap:底层是双向链表+哈希表。有序

  • TreeMap:底层是红黑树。可排序

  • Hashtable:线程安全,效率低

    HashMap:线程不安全,效率高

2.单列集合(Collection接口);

List接口(子接口):有索引值、可以重复、有序

  • ArrayList(实现类):底层是数组,特点,查询快 增删慢

  • LinkedList(实现类):底层是链表,特点,查询慢 增删快

  • Vector(较少使用)(实现类):底层是数组,线程安全

    Vector:线程安全,效率低。

    ArrayList:线程不安全,效率高

Set接口(子接口):没有索引值,不可以重复

  • HashSet(无序)(实现类):底层是哈希表、是HashMap

  • LinkedHashSet(有序)(实现类):底层是链表+哈希表、是LinkedHashMap

  • TreeSet(可排序)(实现类):底层是红黑树,是TreeMap

什么是集合?_第8张图片

List与Set的区别:

什么是集合?_第9张图片

Collection接口:

collection接口中的方法:

  • boolean add(E e);//在集合中添加元素,添加在最后一位

    public static void main(String[] args) {
            Collection c = new ArrayList<>();
            c.add("盖伦");
            c.add("拉克丝");
            c.add("奎因");
            c.add("塔里克");
            c.add("瑞萌萌");
            c.add("瑞萌萌");
            c.add("德莱厄斯");
            c.add("锤石");
            System.out.println(c);
        }

         

  • boolean remove(Object obj);//删除与传入参数相同的元素,删除并返回一个布尔值

    删除以后后面的元素集体前移一位,元素的数量-1;

什么是集合?_第10张图片

public class jihe {
    public static void main(String[] args) {
        Collection c = new ArrayList<>();
        c.add("盖伦");
        c.add("拉克丝");
        c.add("奎因");
        c.add("塔里克");
        c.add("瑞萌萌");
        c.add("瑞萌萌");
        c.add("德莱厄斯");
        c.add("锤石");
        System.out.println(c);
        
        boolean a = c.remove("瑞萌萌");
        System.out.println(a);
        a = c.remove("雷克塞");
        System.out.println(a);
        System.out.println(c);
        
    }
}
 
  
  • boolean contains(Object obj);//判断集合中是否存在与传入参数相同的元素,返回布尔值

    public class jihe {
        public static void main(String[] args) {
            Collection c = new ArrayList<>();
            c.add("盖伦");
            c.add("拉克丝");
            c.add("奎因");
            c.add("塔里克");
            c.add("瑞萌萌");
            c.add("瑞萌萌");
            c.add("德莱厄斯");
            c.add("锤石");
            System.out.println(c);
            
            boolean a = c.contains("锤石");
            System.out.println(a);
            a = c.remove("卡莉斯塔");
            System.out.println(a);
        }
    }

        什么是集合?_第11张图片

  • boolean isEmpty();//是否有元素,有元素false,没有元素是true

    public class jihe {
        public static void main(String[] args) {
            Collection c = new ArrayList<>();
            c.add("盖伦");
            System.out.println(c);
            
            Collection x = new ArrayList<>();
            
            boolean a = c.isEmpty();
            System.out.println(a);
            a = x.isEmpty();
            System.out.println(a);
            
        }
    }

        什么是集合?_第12张图片

  • int size();//可以知道集合中元素的个数

    public class jihe {
        public static void main(String[] args) {
            Collection c = new ArrayList<>();
            c.add("盖伦");
            c.add("拉克丝");
            c.add("奎因");
            c.add("塔里克");
            c.add("瑞萌萌");
            c.add("瑞萌萌");
            c.add("德莱厄斯");
            c.add("锤石");
            System.out.println(c);
            
            int size = c.size();
            System.out.println(size);
        }
    }

  • void clear();//清空集合

    public class jihe {
        public static void main(String[] args) {
            Collection c = new ArrayList<>();
            c.add("盖伦");
            c.add("拉克丝");
            c.add("奎因");
            c.add("塔里克");
            c.add("瑞萌萌");
            c.add("瑞萌萌");
            c.add("德莱厄斯");
            c.add("锤石");
            System.out.println(c);
            
            c.clear();
            System.out.println(c);
        }
    }

  • Object[] toArray();//转化为Object[]数组

    public class jihe {
        public static void main(String[] args) {
            Collection c = new ArrayList<>();
            c.add("盖伦");
            c.add("拉克丝");
            c.add("奎因");
            c.add("塔里克");
            c.add("瑞萌萌");
            c.add("瑞萌萌");
            c.add("德莱厄斯");
            c.add("锤石");
            
            
            Object[] h =c.toArray();
            System.out.println(Arrays.toString(h));
        }
    }

  • Collection的遍历迭代器(Iterator)与增强for遍历

    为什么要有迭代器

    使用普通for循环对集合进行迭代时,需要该集合是可以通过下标进行索引的才可以使用该元素,如果是set的话,那么将不能使用for循环进行迭代,而使用增强for循环对集合进行迭代时,需要预先知道集合中的元素类型才能较好的进行迭代,但是某些情况中,集合中的类型可能有多种。而迭代器iterator可以使用大部分的集合。

    Iterator接口

  • E next();//获取下一个元素

  • boolean hasNext();//判断是否有元素 有true 没有false

public class jihe {
    public static void main(String[] args) {
        Collection c = new ArrayList<>();
        c.add("盖伦");
        c.add("拉克丝");
        c.add("奎因");
        c.add("塔里克");
        c.add("瑞萌萌");
        c.add("瑞萌萌");
        c.add("德莱厄斯");
        c.add("锤石");
        
        Iterator iterator = c.iterator();
        //如果有元素返回值为true,循环开始。否则循环结束
        while(iterator.hasNext()) {
            String e = iterator.next();
            System.out.println(e);
                
        }
        
    }

什么是集合?_第13张图片

增强for

public class jihe {
    public static void main(String[] args) {
        Collection c = new ArrayList<>();
        c.add("盖伦");
        c.add("拉克丝");
        c.add("奎因");
        c.add("塔里克");
        
        for(String str:c) {
            System.out.println(str);
        }
        
    }
}

注意:

Map类的话不能直接使用iterator进行遍历,可以先通过使用map内部提供的EntrySet将其转换为一个Entry的set,再可以使用通过对set进行遍历的方法对Map进行遍历。

List接口

List接口中常用的方法:

  • void add(int index,E e);往对应索引值位置添加元素

    public class jihe {
        public static void main(String[] args) {
            List c = new ArrayList<>();
            c.add("盖伦");
            c.add("拉克丝");
            c.add("奎因");
            System.out.println(c);
            
            c.add(2,"塔里克");
            System.out.println(c);
            
        }
    }

    什么是集合?_第14张图片

  • E remove(int index);删除对应索引值位置上的元素,并返回对应类型的值,也就是得到把谁删了

    public class jihe {
        public static void main(String[] args) {
            List c = new ArrayList<>();
            c.add("盖伦");
            c.add("拉克丝");
            c.add("奎因");
            c.add("塔里克");
            System.out.println(c);
            
            String a = c.remove(2);
            System.out.println(a);
            System.out.println(c);
        }
    }

什么是集合?_第15张图片

  • E get(int index);获取对应索引值位置上的元素

    public class jihe {
        public static void main(String[] args) {
            List c = new ArrayList<>();
            c.add("盖伦");
            c.add("拉克丝");
            c.add("奎因");
            c.add("塔里克");
            System.out.println(c);
            
            String a = c.get(3);
            System.out.println(a);
        }
    }

  • E set(int index,E e);替换索引值对应位置上的元素,返回被替换的元素

    public class jihe {
        public static void main(String[] args) {
            List c = new ArrayList<>();
            c.add("盖伦");
            c.add("拉克丝");
            c.add("奎因");
            c.add("塔里克");
            System.out.println(c);
            
            String a = c.set(3,"阿兹尔");
            System.out.println(a);
            System.out.println(c);
        }
    }
    

什么是集合?_第16张图片

  • List subList(int beginIndex,int endIndex);截取从哪到哪的(左闭右开)元素,返回一个集合

    public class jihe {
        public static void main(String[] args) {
            List c = new ArrayList<>();
            c.add("盖伦");
            c.add("拉克丝");
            c.add("奎因");
            c.add("塔里克");
            c.add("瑞萌萌");
            c.add("瑞萌萌");
            c.add("德莱厄斯");
            c.add("锤石");
            
            List d = c.subList(2, 5);
            System.out.println(d);
        }
    }

什么是集合?_第17张图片

  • int indexOf(Object o);获取元素在集合中首次出现的索引值位置,如果此列表不包含元素,则返回 -1。

  • int lastIndexOf(Object o);获取元素在集合中最后一次出现的索引值位置,如果此列表不包含元素,则返回 -1。

public class jihe {
    public static void main(String[] args) {
        List c = new ArrayList<>();
        c.add("盖伦");
        c.add("拉克丝");
        c.add("奎因");
        c.add("塔里克");
        c.add("锐萌萌");
        c.add("德莱厄斯");
        c.add("锐萌萌");
        c.add("锤石");
        
        int d = c.indexOf("锐萌萌");
        int x = c.lastIndexOf("锐萌萌");
        System.out.println(d);
        System.out.println(x);
        d = c.indexOf("德玛西亚");
        x = c.lastIndexOf("诺克萨斯");
        System.out.println(d);
        System.out.println(x);
    }
}

什么是集合?_第18张图片

ArrayList(实现类):

常用的集合实现类,因为ArrayList实现了List接口,List接口又实现了Collection 接口,所以ArrayList具有他们的方法。ArrayList底层是数组,如果存不下,会自动扩容。

扩容:

初始为零的数组,进行add添加元素后,变成长度为10的数组,存不下元素后,每次扩容原来的1.5倍。

什么是集合?_第19张图片

LinkedList(实现类):

集合实现类,因为LinkedList实现了List接口,List接口又实现了Collection接口,所以LinkedListt的常用方法和他们一样。但是因为LinkedList底层是双向链表,所以涉及到索引值的方法,他还是得一个一个找,所以LinkedList中索引值也可以说是一个假索引值。

什么是集合?_第20张图片

LinkedList独有的成员方法:

  • void addFirst(E e);在集合头插入元素

  • void addLast(E e);在集合尾插入元素

    public class jihe {
        public static void main(String[] args) {
            LinkedList c = new LinkedList<>();
            c.add("盖伦");
            c.add("拉克丝");
            c.add("奎因");
            System.out.println(c);
            
            c.addFirst("卡布达");
            c.addLast("鲨鱼辣椒");
            System.out.println(c);
                
        }
    }

什么是集合?_第21张图片

  • String removeFirst();删除集合中开头的第一个元素,并返回删除了谁

  • String removeLast();删除集合中结尾的最后一个元素,并返回删除了谁

    public class jihe {
        public static void main(String[] args) {
            LinkedList c = new LinkedList<>();
            c.add("盖伦");
            c.add("拉克丝");
            c.add("奎因");
            c.add("锐萌萌");
            c.add("德莱厄斯");
            c.add("锐萌萌");
            c.add("锤石");
            System.out.println(c);
            
            String a = c.removeFirst();
            String f = c.removeLast();
            System.out.println(c);
            System.out.println(a);
            System.out.println(f);      
            
        }
    }

什么是集合?_第22张图片

  • String getFirst();获取集合的第一个元素,返回获取了谁

  • String getLast();获取集合的最后一个元素,返回获取了谁

public class jihe {
    public static void main(String[] args) {
        LinkedList c = new LinkedList<>();
        c.add("盖伦");
        c.add("拉克丝");
        c.add("奎因");
        c.add("锐萌萌");
        c.add("德莱厄斯");
        
        System.out.println(c);
        
        String a = c.getFirst();
        String f = c.getLast();
        System.out.println(a);
        System.out.println(f);
        
    }
}

什么是集合?_第23张图片

set接口:

没有索引值,不可以重复

哈希表:

数组+链表+红黑树

优点:

  • 无论数据有多少,处理起来都特别的快

  • 能够快速地进行 插入修改元素删除元素查找元素 等操作

  • 代码简单(其实只需要把哈希函数写好,之后的代码就很简单了)

缺点:

  • 哈希表中的数据是没有顺序的

  • 数据不允许重复

HashSet(无序)(实现类):底层是哈希表

底层是HashMap;

什么是集合?_第24张图片

什么叫无序:

新增顺序和获取顺序不一定一致

public class jihe {
    public static void main(String[] args) {
        Set c = new HashSet<>();
        c.add("盖伦");
        c.add("拉克丝");
        c.add("奎因");
        c.add("锐萌萌");
        c.add("德莱厄斯");
        System.out.println(c);
            
    }
}

LinkedHashSet(有序)(实现类):底层是链表+哈希表

与HashSet类似,但是他是有序的,LinkedHashSet的底层是LinkedHashMap

public class jihe {
    public static void main(String[] args) {
        Set c = new LinkedHashSet<>();
        c.add("盖伦");
        c.add("拉克丝");
        c.add("奎因");
        c.add("锐萌萌");
        c.add("德莱厄斯");
        System.out.println(c);
            
    }
}

为什么没有重复?

1.计算新增元素的哈希值(十进制的地址值),调用hashCode();//Object父类的方法,比较地址值。

什么是集合?_第25张图片

2.通过哈希值%数组长度,去确定元素新增的索引值位置

什么是集合?_第26张图片

  • 如果该位置没有元素:直接新增

  • 如果该位置有元素:判断这两个元素是否相同

  • 如果不相同:挂到最后一个元素下面

  • 如果相同:不新增

    判断是否相同的标准:

    比较哈希值相同 && (地址值相同 || equals相同)

      final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                       boolean evict) {
            Node[] tab; Node p; int n, i;
            if ((tab = table) == null || (n = tab.length) == 0)
                n = (tab = resize()).length;
            if ((p = tab[i = (n - 1) & hash]) == null)
                tab[i] = newNode(hash, key, value, null);
            else {
                Node e; K k;
                if (p.hash == hash &&
                    ((k = p.key) == key || (key != null && key.equals(k))))
                    e = p;
                else if (p instanceof TreeNode)
                    e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value);
                else {
                    for (int binCount = 0; ; ++binCount) {
                        if ((e = p.next) == null) {
                            p.next = newNode(hash, key, value, null);
                            if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                                treeifyBin(tab, hash);
                            break;
                        }
                        if (e.hash == hash &&
                            ((k = e.key) == key || (key != null && key.equals(k))))
                            break;
                        p = e;
                    }
                }
                if (e != null) { // existing mapping for key
                    V oldValue = e.value;
                    if (!onlyIfAbsent || oldValue == null)
                        e.value = value;
                    afterNodeAccess(e);
                    return oldValue;
                }
            }
            ++modCount;
            if (++size > threshold)
                resize();
            afterNodeInsertion(evict);
            return null;
        }

    总结:如果自定义类 型的对象,我们希望添加到HashSet集合中

    我们认为成员变量的值相同,就为同一个元素,

    则需要覆盖重写hashCode方法和equals方法

  • String中就重写了HashCode,所以只要内容相同,地址值就相同

public class Test05 {
	public static void main(String[] args) {
		Set set = new HashSet<>();
		//String覆盖重写了Object父类的hashCode方法,只要内容相同,哈希值就相同。
		set.add(new String("张三"));
		set.add(new String("张三"));
		System.out.println(set.size());//1
		
		Set set2 = new HashSet<>();
		set2.add(new Student("张三",20));
		set2.add(new Student("张三",20));
		System.out.println(set2.size());//2
		
	}
}

class Student{
	private String name;
	private int age;
	public Student(String name,int age) {
		super();
		this.name = name;
		this.age = age;
	}
	//如果hashcode方法,认为成员变量 的值相同,则返回相同的结果
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
}

TreeSet(可排序)(实现类):底层是红黑树

可排序可不代表有序

TreeSet的底层是TreeMap

public class jihe {
	public static void main(String[] args) {
		Set c = new TreeSet<>();
		c.add("盖伦");
		c.add("拉克丝");
		c.add("奎因");
		c.add("锐萌萌");
		c.add("德莱厄斯");
		System.out.println(c);
		
		Set d = new TreeSet<>();
		d.add(10);
		d.add(50);
		d.add(30);
		d.add(20);
		d.add(40);
		System.out.println(d);
			
	}
}

什么是集合?_第27张图片

TreeSet构造方法:


                 public TreeSet();
                 public TreeSet(Comparator<> c);

 TreeSet进行排序的方法的方法有两种

1.类实现Comparable<>方法,重写compareTo(Object o)方法

2.Comparetor比较器

Comparable<>方法

类实现Comparable<类>接口,重写其中的compareTo方法

比较的规则
     *         升序:当前对象-参数对象
     *         降序:参数对象-当前对象

public class sm {
	public static void main(String[] args) {
		
		//TreeSet新增元素的时候,泛型必须是Comparable类型
		Set a = new TreeSet<>();
		a.add(new Person("盖伦"));
		a.add(new Person("德莱厄斯"));
		a.add(new Person("辛吉德"));
		a.add(new Person("弗拉基米尔伯爵"));
		
		System.out.println(a);
	}
}

class Person implements Comparable{
	private String name;
	public Person(String name) {
		super();
		this.name = name;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + "]";
	}
	//通过名字长度来排序
	@Override
	public int compareTo(Person o) {
		//升序
		//int result = this.name.length()-o.name.length();
		
		//降序
		int result = o.name.length()-this.name.length();
		return result;
	}
}

 Comparetor方法:


       升序:
                 参数1-参数2
       降序:
                 参数2-参数1
                 

public static void main(String[] args) {

		//创建Comparator类型的对象
		Comparator c = new Comparator() {
			@Override
			public int compare(Teacher t1, Teacher t2) {
				/*
				 * 	升序:
				 * 		参数1-参数2
				 * 	降序:
				 * 		参数2-参数1
				 */
				int result = t2.getName().length()-t1.getName().length();
				return result;
			}
		};
		
		Set a = new TreeSet<>(c);
		a.add(new Teacher("盖伦"));
		a.add(new Teacher("德莱厄斯"));
		a.add(new Teacher("辛吉德"));
		a.add(new Teacher("弗拉基米尔伯爵"));

		System.out.println(a);
	}
}

class Teacher{
	private String name;
	
	public String getName() {
		return name;
	}
	public Teacher(String name) {
		super();
		this.name = name;
	}
	@Override
	public String toString() {
		return "Teacher [name=" + name + "]";
	}
}

 Map:

特点:
            1.一个元素是有一个K,一个V两部分组成
            2.K  V可以是任意的引用数据类型
            3.一个K对应唯一的一个V。K不能重复

Map常用方法:

 *             V put(K k,V v);//如果K存在,则新的V替换旧的V,返回被替换的V。
                             //如果K不存在,则返回null

public class jihe {
	public static void main(String[] args) {
		Map a = new HashMap<>();
		Double v = a.put("西瓜", 20.0);
		System.out.println(v);
		v = a.put("草莓", 30.0);
		System.out.println(v);
		v = a.put("榴莲", 25.5);
		System.out.println(v);
		v = a.put("草莓", 37.8);
		System.out.println(v);
		
			
	}
}

什么是集合?_第28张图片


 *             V remove(Object key);//删除元素,根据key删除整个元素,返回被删除元素的V
                                   //如果Key不存在,则返回null

public class jihe {
	public static void main(String[] args) {
		Map a = new HashMap<>();
		Double v = a.put("西瓜", 20.0);
		v = a.put("草莓", 30.0);
		v = a.put("榴莲", 25.5);
		v = a.put("草莓", 37.8);
		
		v = a.remove("榴莲");
		System.out.println(v);
		v = a.remove("榴莲");
		System.out.println(v);
			
	}
}

 
 *             V get(Object key);//根据key获取V,如果key不存在则返回null

public class jihe {
	public static void main(String[] args) {
		Map a = new HashMap<>();
		Double v = a.put("西瓜", 20.0);
		v = a.put("草莓", 30.0);
		v = a.put("榴莲", 25.5);
		v = a.put("草莓", 37.8);
		
		v = a.get("榴莲");
		System.out.println(v);
		v = a.remove("花椰菜");
		System.out.println(v);
			
	}
}

 
 *             boolean containsKey(Object key);是否存在k
 *             boolean containsValue(Object value);是否存在v

public class jihe {
	public static void main(String[] args) {
		Map a = new HashMap<>();
		Double v = a.put("西瓜", 20.0);
		v = a.put("草莓", 30.0);
		v = a.put("榴莲", 25.5);
		v = a.put("草莓", 37.8);
		
		boolean b = a.containsKey("榴莲");
		System.out.println(b);
		b = a.containsKey("花椰菜");
		System.out.println(b);
		
		
		b = a.containsValue(25.5);
		System.out.println(b);
		b = a.containsValue(25.5);
		System.out.println(b);	
	}
}

什么是集合?_第29张图片
 
 *             Set keySet();获取所有的k

 *             Collection values();获取所有的v

public class jihe {
	public static void main(String[] args) {
		Map a = new HashMap<>();
		Double v = a.put("西瓜", 20.0);
		v = a.put("草莓", 30.0);
		v = a.put("榴莲", 25.5);
		v = a.put("草莓", 37.8);
		
		Collection values = a.values();
		System.out.println(values);
		Set set = a.keySet();
		System.out.println(set);
	}
}

遍历Map集合的一种方法就是用Map.Entry接口方法;


 *             Set> entrySet();

public static void main(String[] args) {
		Map a = new HashMap<>();
		 a.put("西瓜", 20.0);
		 a.put("草莓", 30.0);
		 a.put("榴莲", 25.5);
		 a.put("草莓", 37.8);

		//获取所有的Entry
		Set> entrySet =  a.entrySet();
		Iterator> iterator = entrySet.iterator();
		while(iterator.hasNext()) {
			Entry entry = iterator.next();
			String key = entry.getKey();
			Double value = entry.getValue();
			System.out.println(key+"-+-"+value);
		}
	}

       什么是集合?_第30张图片

 
 *             boolean isEmpty();判断集合中是否有元素
 *             void clear();清空元素
 *             int size();//获取集合中元素的个数

public class jihe {
	public static void main(String[] args) {
		Map a = new HashMap<>();
		Double v = a.put("西瓜", 20.0);
		v = a.put("草莓", 30.0);
		v = a.put("榴莲", 25.5);
		v = a.put("草莓", 37.8);
		
		int c = a.size();
		System.out.println(c);
		boolean b = a.isEmpty();
		System.out.println(b);	
		a.clear();
		System.out.println(a);
	}
}

 

 

       HashMap:底层是哈希表。无序
       LinkedHashMap:底层是链表+哈希表。有序
      TreeMap:底层是红黑树。可排序

        HashSet的底层是HashMap
 *         LinkedHashSet的底层是LinkedHashMap
 *         TreeSet的底层是TreeMap

 TreeMap

TreeMap排序也可以用Comparator以及Comparable。

public class Test06 {
	public static void main(String[] args) {
		
		Comparator c = new Comparator() {
			@Override
			public int compare(Student o1, Student o2) {
				return o1.getName().length()-o2.getName().length();
			}
		};
		
		Map map = new TreeMap<>(c);
		map.put(new Student("张三丰","yjy0010"), 80.0);
		map.put(new Student("张三","yjy0020"), 90.0);
		map.put(new Student("张三疯了","yjy0030"), 90.0);
		System.out.println(map);
	
	}
}

你可能感兴趣的:(集合,java,数据结构,散列表)