javaSE_day16

  • 集合
  • 1. Collection常用方法
  • 2. 遍历集合
  • 3. List-ArrayList(数组)
  • 3.1 常用方法:
  • 3.2 和集合相关的方法:
  • 4. 集合和数组的相互转换
  • 5. 集合排序的两种方式
  • 练习:实现ArrayList
  • List集合
  • ArrayList、LinkedList 和 Vector
  • 实现LinkedList
  • Set集合
  • HashSet 和 TreeSet
  • Map集合
  • 1. 常用方法
  • 2. 遍历Map结合的三种方法
  • 3. HashMap和HashTable区别
  • 集合总结


集合

java从set中取一个元素_键值对

1. Collection常用方法

java从set中取一个元素_java从set中取一个元素_02

2. 遍历集合

  • 第一种方法: 增强for循环
    for(String str : coll){
    System.out.println(str);
    }
  • 第二种方法: 迭代器
    Iterator it = coll.iterator();
    while(it.hasNext()){
    String str = it.next();
    System.out.println(str);
    }
  • 第三种方法: lambda表达式
    coll.forEach(a->System.out.println(a));

3. List-ArrayList(数组)

3.1 常用方法:

java从set中取一个元素_键值对_03

3.2 和集合相关的方法:

java从set中取一个元素_java从set中取一个元素_04

4. 集合和数组的相互转换

  • 集合转换成数组 toArray()
  • 数组转换成集合 Arrays.asList()

5. 集合排序的两种方式

  • 方法一: 实现Comparator接口,重写compare方法
    在外部排序,改变默认排序规则
  • 方法二: 实现Comparable接口,重写compareTo方法
    嵌入到排序的类中

Arrays.sort(数组排序)
Collections.sort(集合排序)

练习: 按照学生成绩排序

  1. 定义Student类
    两个变量:name,score
    方法:get、set、toString、构造方法
  2. 定义集合,3个student对象,添加到集合
  3. 使用sort方法排序,排序是指定排序规则
  4. 输出排序后的集合

java从set中取一个元素_数组_05


java从set中取一个元素_List_06


java从set中取一个元素_java从set中取一个元素_07

练习:实现ArrayList

package cn.tedu.collection;

import java.util.Arrays;

public class MyArray {
	private int size;//表示集合的元素个数
	private String[] strArray;
	
	//1.定义无参的构造方法  默认给数组10个
	public MyArray() {
		strArray = new String[10];
	}
	//2.定义一个带参的构造方法
	public MyArray(int length) {
		strArray = new String[10];
	}
	
	//3.判断元素的个数和数组的长度之间的关系  size>=strArray 扩容
	//添加元素
	public void add(String str) {
		if (size>strArray.length) {
			grow();
		}
		strArray[size] = str;
		size++;
	}
	
	//4.规则:数组长度的一半(如果数组长度为1 ,扩容应该是+1)
	public void grow() {
		if (strArray.length<=1) {
			strArray = Arrays.copyOf(strArray, strArray.length+1);
		}else {
			strArray = Arrays.copyOf(strArray, strArray.length+strArray.length/2);
		}
	}
	
	//5.判断元素的个数和数组的长度之间的关系  size>=strArray 扩容
	//		当前的数组元素后移
	//		插入元素
	public void add(int index,String str) {
		if (size>=strArray.length) {
			grow();
		}
		//{1,2,3}  index = 1        3-index
		//{1,1,2,3}
		System.arraycopy(strArray, index, strArray, index+1, size-index);
		strArray[index] = str;
		size++;
	}
	
	//6.当前的数组元素前移
	public void remove(int index) {
		System.arraycopy(strArray, index+1, strArray, index, size-index-1);
		size--;
	}
	
	//7.修改
	public void set(int index,String str) {
		strArray[index] = str;
	}
	
	//8.获取元素
	public String get(int index) {
		return strArray[index];
	}
	
	//9.返回集合中的元素个数
	public int size() {
		return size;
	}
	public static void main(String[] args) {
		MyArray myArray = new MyArray();
		myArray.add("hello");
		myArray.add("abc");
		myArray.add("admin");
		myArray.remove(1);
		myArray.set(1, "admin!!!");
		myArray.add(1,"222");
		for (int i = 0; i < myArray.size(); i++) {
			System.out.println(myArray.get(i));
		}
	}
}

List集合

ArrayList、LinkedList 和 Vector

  • LinkedListArrayList都是线程不安全
  • Vector线程安全

实现LinkedList

package cn.tedu.Li;
public class LinkList {
	private int size = 0; // 节点个数
	private Node first; // 第一个节点
	private Node last; // 最后一个节点

	//无参构造方法
	public LinkList() {	}
	
	//添加元素
	public void add(String str) {
	     Node node = new Node(null, str, null); // 以尾部元素为前继节点创建一个新节点
	        if (size == 0) {
			    // 如果空链表的情况:同时更新first节点也为需要插入的节点。(也就是说:该节点既是头节点first也是尾节点last)
	            this.first = node;
	        	this.last = node;
	        }else {
	        	this.last.next = node;
	        	node.prev = this.last;
	        	this.last = node;
	        }
	        size++; // 更新链表大小和修改次数,插入完毕	       
	}
       
	//插入
	public void add(int index, String str) {
		//最后  this.add()
		if (index==size) {
			this.add(str);
			return;
		}
		Node node = new Node(null, str, null);
		if (index==0) {
			//在链表的最前边
			node.next = this.first.prev;
			this.first.prev = node;
			this.first = node;
		}else {
			//中间
			Node node1 = this.getNode(index);
			node1.prev.next = node;
			node.prev = node.prev;
			node.next = node1;
			node1.prev = node;
		}
		size++;
	}
        // 获取指定位置的节点
	private Node getNode(int index) {
		Node node  = this.first;
		for (int i = 0; i <index; i++) {
			node = node.next;			
		}
		return node;
	}
        //删除
	public void remove(int index) {
		//删除第一个
		if (index==0) {
			this.first.next.prev = null;
			this.first = this.first.next;
		}		
		//删除最后一个
		else if (index==size-1) {
			this.last.prev.next = null;
			this.last = this.last.prev;
		}
		//删除中间的
		else {
			Node node = this.getNode(index);
			node.prev.next = node.next;
			node.next.prev = node.prev;			
		}		
		size--;
	}
        //返回节点的内容
	public String get(int index){
		return this.getNode(index).data;
	}
	// 返回元素个数
	public int size(){
	      return size;
	}
	//利用节点存储数据
	private class Node {
		Node prev; // 上一个节点
		String data; // 元素
		Node next; // 下一个节点
		public Node(Node prev, String data, Node next) {
			super();
			this.prev = prev;
			this.data = data;
			this.next = next;
		}
	}
}

Set集合

不重复

先判断hashCode(); 若相同,还要判断equals方法,如果返回true,则表示一个对象,否则是不同对象

java从set中取一个元素_java从set中取一个元素_08

HashSet 和 TreeSet

  • HashSet基于HashMap的实现
  • HashSet的元素是map中的key。

java从set中取一个元素_List_09

  • TreeSet的元素必须是有排序规则的对象,否则会运行时异常

java从set中取一个元素_List_10

Map集合

1. 常用方法

java从set中取一个元素_键值对_11

2. 遍历Map结合的三种方法

java从set中取一个元素_List_12

3. HashMap和HashTable区别

  • 线程是否安全: HashTable安全, HashMap不安全的
  • key/value:HashTable不可以为null, HashMap可以为null

练习

接收键盘输入一个字符串,统计字符的个数。

java从set中取一个元素_List_13

集合总结

HashMap

HashSet

实现了Map接口

实现了Set接口

存储键值对

仅存储对象

使用put()方法将元素放入map中

使用add()方法将元素放入set中

使用键对象来计算hashcode值

使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false

比较快,因为是使用唯一的键来获取对象

HashSet较HashMap来说比较慢

有序

线程安全

原理及特性

线程同步

适用场景

Map

无序


1.是一个接口 2.主要用于存储键值对(key-value的形式),不允许键重复,允许值重复


HashMap

无序


1. 原理:实现了Map接口的实现类,基于hashing原理,通过put()和get()方法存储和获取对象。将键值对传递给put()方法时,调用见对象的hashCode()方法计算hashCode,然后找到bucket位置来存储键值对象。当获取对象时,通过equals()方法找到正确的键值对,然后返回值对象。2. HashMap的遍历速度和他的容量有关。3. HashMap底层是基于数组+链表。4. “碰撞”:当两个不同的键对象的hashcode相同时, 它们会储存在同一个bucket位置的链表中,Entry(包含有键值对的Map.Entry对象)会存储在链表中。使用键对象的equals()方法用来找到键值对。


在Map 中插入、删除和定位元素,HashMap 是最好的选择

TreeMap

有序


1. 实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。2. 对元素进行整体的自然排序,需要元素对应的类实现。3. 如果需要给某个TreeSet对象单独制定比较规则,则使用Comparable;若不指定,则使用Comparable进行整体的自然排序


自然顺序或自定义顺序遍历键,那么TreeMap会更好

set

无序


Set的集合里不允许对象有重复的值


HashSet

无序


1. 实现了Set接口,不允许集合中有重复的值。2. 在对象存储在HashSet之前要确保对象重写equals()和hashCode()方法,比较对象的值是否相等,以确保Set中没有存储相等的对象,若不重写,则使用该方法的默认实现。


List

有序


1list是接口。List允许有重复,它对集合中的对象进行索引。通过下标对指定位置上的元素进行操作


快速插入和删除

LinkList

有序


基于节点(Node)来实现的。利用节点来存储数据以及维系链表之间每一个节点的关系。内存空间不连续。


便于增删改

ArrayList

有序


1. 用数组实现的List的实现类2. 内存空间连续


便于查询

Vector

有序


1.依靠数组来存储数据,每次扩容默认增加一倍。


快速查找