第九章 容器(尚学堂java300集笔记,含自写编程题答案)

第九章 容器

(尚学堂java300集笔记到此结束,后面的内容用尚硅谷教程,使用IDEA开发)

DAY17

  • 容器的接口层次结构图:

图9-1容器的接口层次结构图.png

  • 泛型的本质就是“数据类型的参数化”。 我们可以把“泛型”理解为数据类型的一个占位符(形式参数),即告诉编译器,在调用泛型时必须传入实际类型

  • 我们可以在类的声明处增加泛型列表,如:<T,E,V>。 此处,字符可以是任何标识符,一般采用这3个字母

  • Collection接口中的方法

    表9-1 Collection接口中定义的方法.png

  • List是有序、可重复的容器

    • List中每个元素都有索引标记,允许加入重复的元素
    • 表9-2 List接口中定义的方法.png
  • List接口常用的实现类有3个:ArrayList、LinkedList和Vector

  • ArrayList底层是用数组实现的存储。特点:查询效率高,增删效率低,线程不安全。常用

package cn.sxt.mycollection;
/**
 * 
 * 自定义ArrayList
 *
 * @param <E>
 */
public class SxtArrayList<E> {
	
	private Object[] elementDate;
	private int size;
	
	private static final int DEFALT_CAPACITY = 10;
	
	public SxtArrayList() {
		elementDate = new Object[DEFALT_CAPACITY];
	}
	
	public SxtArrayList(int capacity) {
		//判断容量是否合法
		if (capacity<0) {
			throw new RuntimeException("容器的容量不能为负数");
		}else if(capacity==0) {
			elementDate = new Object[DEFALT_CAPACITY];
		}else {
			elementDate = new Object[capacity];
		}

	}
	
	public int size() {
		return size;
	}
	
	public boolean isEmpty() {
		return size==0?true:false;
	}
	
	public void add(E element) {
		//什么时候扩容
		if(size==elementDate.length) {
		//怎么扩容
			Object[] newArray = new Object[elementDate.length+(elementDate.length>>1)];//10+(10/2)=15
			System.arraycopy(elementDate, 0, newArray, 0, elementDate.length);
			elementDate = newArray;
		}
		elementDate[size++] = element;
	}
	
	//增加set和get方法
	public E get(int index) {
		checkRange(index);
		return (E)elementDate[index];//高类型转低类型要强制转换,即Object强转E
	}
	public void set(E element,int index) {
		checkRange(index);
		elementDate[index] = element;
	}
	
	//索引合法判断[0,size),即(0-size-1)
	public void checkRange(int index) {
		if(index<0||index>size-1) {
			throw new RuntimeException("索引不合法:"+index);
		}
	}
	
	//增加remove方法
	//移除指定元素
	public void remove(E element) {
		//将element和所有元素挨个比较,获得第一个比较为true的移除
		for(int i=0;i<size;i++) {
			if (element.equals(get(i))) { //容器中所有的比较操作,都是用的equals方法,而不是==
				//将该元素从此处移除
				remove(i);
			}
		}	
	}
	//移除指定位置的元素
	public void remove(int index) {
		int numMoved = elementDate.length-index-1;
		if(numMoved>0) {
			System.arraycopy(elementDate, index+1, elementDate, index,numMoved);	
		}
		elementDate[--size] = null;//elementDate[size-1] = null;size--;合并
	}
	
	//重写toString方法
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		//[a,b,c]
		sb.append("[");
		for(int i=0;i<size;i++) {
			sb.append(elementDate[i]+","); 
		}
		sb.setCharAt(sb.length()-1, ']');
		return sb.toString();
	}
	
	public static void main(String[] args) {
		SxtArrayList s1 = new SxtArrayList(10);
		for(int j=0;j<40;j++) {
			s1.add("a"+j);
		}
		s1.set("abc", 10);
		System.out.println(s1);
		System.out.println(s1.get(39));
		s1.remove(3);
		s1.remove("a0");
		System.out.println(s1);
		System.out.println(s1.size);
		System.out.println(s1.isEmpty());
	}
	
}

DAY18

  • LinkedList底层用双向链表实现的存储。特点:查询效率低,增删效率高,线程不安全。

  • 双向链表也叫双链表,是链表的一种,它的每个数据节点中都有两个指针,分别指向前一个节点和后一个节点。

  • 每个节点都应该有3部分内容:

    class  Node {
           Node  previous;     //前一个节点
           Object  element;    //本节点保存的数据
           Node  next;         //后一个节点
   }
  • 自定义一个链表
package cn.sxt.mycollection;

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;
	}

}
package cn.sxt.mycollection;
/**
 * 自定义一个链表
 * @author quanquan
 *
 */
public class SxtLinkedList<E> {
	
	private Node first;
	private Node last;
	private int size;
	
	//add插入方法
	public void add(int index,E element) {
		checkRange(index);
		Node newNode = new Node(element);
		Node temp = getNode(index);
		if(temp!=null) {
			Node up = temp.previous;
			if(up!=null) {
				up.next = newNode;
				newNode.previous = up;				
			}
			newNode.next = temp;
			temp.previous =newNode;
			if(index==0) {
				first = newNode;
			}
		}
	}
	
	//remove方法
	public void remove(int index) {
		checkRange(index);
		Node temp = getNode(index);
		if(temp!=null) {
			Node up = temp.previous;
			Node down = temp.next;
			if(up!=null) {
				up.next = down;				
			}
			if(down!=null) {
				down.previous = up;
			}
			if(index==0) { //被删除元素是第一个
				first = down;
			}
			if(index==size-1) { //被删除元素是最后一个
				last =up;
			}
			size--;
		}
	}
	
	//get方法
	public E get(int index) {
		checkRange(index);
		Node temp = getNode(index);
		 return temp!=null?(E)temp.element:null;
	}
	//getNode方法不需要外部知道,可私有
	private Node getNode(int index) {
		 Node temp = null;
		 if(index<=(size>>1)) {
			 temp = first;
			 for(int i=0;i<index;i++) {
				 temp = temp.next;
			 }
		 }else {
			 temp =last;
			 for(int i=size-1;i>index;i--) {
				 temp = temp.previous;
			 }
		 }
		 return temp;
	}
	
	//add添加方法
	public void add(E element) {
		Node node = new Node(element);
		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;
		}
		size++;
	}
	
	//toString方法
	public String toString() {
		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();
	}
	
	private void checkRange(int index) {
		if(index<0||index>=size) {
			throw new RuntimeException("索引数字不合法"+index);
		}
	}
	
	public static void main(String[] args) {
		SxtLinkedList<String> list =new SxtLinkedList<>();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		list.add("e");
		System.out.println(list);
		System.out.println(list.get(3));
		list.remove(4);
		System.out.println(list);
		list.add(0, "123");
		System.out.println(list);
	}
	
}
  • Vector底层是用数组实现的List,相关的方法都加了同步检查,因此“线程安全,效率低”

  • Map就是用来存储“键(key)-值(value) 对”的

  • Map类中存储的“键值对”通过键来标识,所以“键对象”不能重复(根据equals方法),否则新的会覆盖旧的

  • 表9-3 Map接口中常用的方法.png

  • Map 接口的实现类有HashMap、TreeMap、HashTable、Properties等

  • HashMap底层实现采用了哈希表,这是一种非常重要的数据结构

    • 哈希表的本质就是“数组+链表”

    • Entry[] table 就是HashMap的核心数组结构,我们也称之为“位桶数组”。一个Entry对象存储了:

      • key:键对象,value:值对象
      • next:下一个节点
      • hash: 键对象的hash值
    • Entry[]数组的结构:

      图9-15 Entry数组存储结构图.png

    • 存储数据过程put(key,value)

      图9-16 HashMap存储数据过程示意图.png

      当添加一个元素(key-value)时,首先计算key的hash值,以此确定插入数组中的位置,但是可能存在同一hash值的元素已经被放在数组同一位置了,这时就添加到同一hash值的元素的后面,他们在数组的同一位置,就形成了链表,同一个链表上的Hash值是相同的,所以说数组存放的是链表。

    • 根据hashcode计算出hash值

      • 一种极端简单和低下的算法是:

        ​ hash值 = hashcode/hashcode;

      • 一种简单和常用的算法是(相除取余算法):

        ​ hash值 = hashcode%数组长度

        这种算法可以让hash值均匀的分布在[0,数组长度-1]的区间。 早期的HashTable就是采用这种算法。但是,这种算法由于使用了“除法”,效率低下。JDK后来改进了算法。首先约定数组长度必须为2的整数幂,这样采用位运算即可实现取余的效果:hash值 = hashcode&(数组长度-1)

  • Java中规定,两个内容相同(equals()为true)的对象必须具有相等的hashCode。因为如果equals()为true而两个对象的hashcode不同;那在整个存储过程中就发生了悖论

  • 扩容问题

    • HashMap的位桶数组,初始大小为16。实际使用时,显然大小是可变的。如果位桶数组中的元素达到(0.75*数组 length), 就重新调整数组大小变为原来2倍大小
    • 扩容很耗时。扩容的本质是定义新的更大的数组,并将旧数组内容挨个拷贝到新数组中
  • JDK8中,HashMap在存储一个元素时,当对应链表长度大于8时,链表就转换为红黑树,这样又大大提高了查找的效率

DAY19

  • 手工实现HashMap
package cn.sxt.mycollection;
//用于SxtHashMap
public class Node2<K,V> {
	
	int hash;
	K key;
	V value;
	Node2 next;
	
}
package cn.sxt.mycollection;
/**
 * 自定义HashMap
 * @author quanquan
 *
 */
public class SxtHashMap<K,V> {
	
	Node2[] table;  //位桶数组,bucket array
	int size;  //键值对的个数
	
	public SxtHashMap() {
		table = new Node2[16];  //长度一般定义成2的整数幂
	}
	
	//put方法增加键值对,并解决了键重复的时候覆盖相应的节点
	public void put(K key,V value) {
		//如果要完善,还需要考虑数组扩容的问题!
		
		//定义新的节点对象
		Node2 newNode = new Node2();
		newNode.hash = myHash(key.hashCode(),table.length);
		newNode.key = key;
		newNode.value = value;
		newNode.next = null;
		
		Node2 temp = table[newNode.hash];
		Node2 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 = newNode.value;  //只覆盖value即可,其他值不变
					break;
				}else {
					//key不重复,则遍历下一个
					iterLast = temp;
					temp = temp.next;
				}
			}
			if(!keyRepeat) {  //没有发生key重复的情况,则添加到链表最后
				iterLast.next = newNode;
				size++;
			}
		}
	}
	
	//重写toString方法,方便查看Map中的键值对信息
	public String toString() {
		//{10:aa,20:bb}
		StringBuilder sb = new StringBuilder("{");
		
		for(int i=0;i<table.length;i++) {  //遍历bucket数组
			Node2 temp = table[i];
			while(temp!=null) {  //遍历链表
				sb.append(temp.key+":"+temp.value+",");
				temp = temp.next;
			}
		}
		sb.setCharAt(sb.length()-1, '}');
		return sb.toString();
	}

	//get方法
	public V get(K key) {
		int hash = myHash(key.hashCode(),table.length);
		V value = null;
		if(table[hash]!=null) {
			Node2 temp = table[hash];
			while(temp!=null) {
				if(temp.key.equals(key)) { //如果相等,则说明找到了键值对,返回相应的value
					value = (V)temp.value;
					break;
				}else {
					temp = temp.next;
				}
			}
		}
		return value;
	}
	
	public int myHash(int v,int length) {
		// System.out.println("hash in myHash"+(v&(length-1)));  直接位运算,效率高
		// System.out.println("hash in myHash"+(v%length));  取模运算,效率低
		return v&(length-1);
	}
	
	public static void main(String[] args) {
		SxtHashMap<Integer,String> m = new SxtHashMap<>();
		m.put(10, "aa");
		m.put(20, "bb");
		m.put(30, "cc");
		m.put(20, "ee");
		m.put(53, "1");
		m.put(69, "2");
		m.put(85, "3");
		System.out.println(m);
		System.out.println(m.get(53));
	}
	
}
  • TreeMap是红黑二叉树的典型实现
  • TreeMap和HashMap实现了同样的接口Map,因此,用法对于调用者来说没有区别。HashMap效率高于TreeMap;在需要排序的Map时才选用TreeMap
package cn.sxt.mycollection;

import java.util.Map;
import java.util.TreeMap;

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");
		
		Map<Emp,String> treemap2 = new 	TreeMap<>();
		treemap2.put(new Emp(100,"zhang",50000),"zhang好");
		treemap2.put(new Emp(200,"li",5000),"li差");
		treemap2.put(new Emp(150,"wang",20000),"wang平");
		treemap2.put(new Emp(120,"zhao",20000),"zaho平");
		
		//按照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;
	}
	
	public String toString() {
		return "id:"+id+",name:"+name+",salary"+salary;
	}

	@Override
	public int compareTo(Emp o) {
		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;
			}
		}
	}	
}
  • HashTable类和HashMap用法几乎一样

  • HashMap: 线程不安全,效率高。允许key或value为null

  • HashTable: 线程安全,效率低。不允许key或value为null

  • Set接口

    • Set接口继承自Collection,Set接口中没有新增方法,方法和Collection保持完全一致
    • 无序、不可重复(无序指Set中的元素没有索引,我们只能遍历查找;不可重复指不允许加入重复的元素)
    • Set常用的实现类有:HashSet、TreeSet等,我们一般使用HashSet
  • HashSet是采用哈希算法实现,底层实际是用HashMap实现的(HashSet本质就是一个简化版的HashMap),因此,查询效率和增删效率都比较高

    • 往set中加入元素,本质就是把这个元素作为key加入到了内部的map中
    • 由于map中key都是不可重复的,因此,Set天然具有“不可重复”的特性
  • 使用Iterator迭代器遍历容器元素(List/Set/Map)

    • 迭代器遍历List

      public class Test {
          public static void main(String[] args) {
              List<String> aList = new ArrayList<String>();
              for (int i = 0; i < 5; i++) {
                  aList.add("a" + i);
              }
              System.out.println(aList);
              for (Iterator<String> iter = aList.iterator(); iter.hasNext();) {
                  String temp = iter.next();
                  System.out.print(temp + "\t");
                  if (temp.endsWith("3")) {// 删除3结尾的字符串
                      iter.remove();
                  }
              }
              System.out.println();
              System.out.println(aList);
          }
      }
    • 迭代器遍历Map

      public class Test {
          public static void main(String[] args) {
              Map<String, String> map = new HashMap<String, String>();
              map.put("A", "高淇");
              map.put("B", "高小七");
              Set<Entry<String, String>> ss = map.entrySet();
              for (Iterator<Entry<String, String>> iterator = ss.iterator(); iterator.hasNext();) {
                  Entry<String, String> e = iterator.next();
                  System.out.println(e.getKey() + "--" + e.getValue());
              }
          }
      }
      public class Test {
          public static void main(String[] args) {
              Map<String, String> map = new HashMap<String, String>();
              map.put("A", "高淇");
              map.put("B", "高小七");
              Set<String> ss = map.keySet();
              for (Iterator<String> iterator = ss.iterator(); iterator.hasNext();) {
                  String key = iterator.next();
                  System.out.println(key + "--" + map.get(key));
              }
          }
      }
  • Collections工具类,提供了对Set、List、Map进行排序、填充、查找元素的辅助方法

    • void sort(List) //对List容器内的元素排序,排序的规则是按照升序进行排序。
    • void shuffle(List) //对List容器内的元素进行随机排列。
    • void reverse(List) //对List容器内的元素进行逆续排列 。
    • void fill(List, Object) //用一个特定的对象重写整个List容器。
    • int binarySearch(List, Object)//对于顺序的List容器,采用折半查找的方法查找特定对象。

DAY19

  • 使用容器存储表格数据

    ID姓名薪水入职日期
    1001张三200002018.5.5
    1002李四300002005.4.4
    1003王五30002020.5.4
    • 每一行数据使用一个Map;整个表格使用一个List。(ORM思想:对象关系映射)
    package cn.sxt.mycollection;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * 测试表格数据的存储
     * ORM思想的简单实验:map表示一行数据,多行数据是多个map;将多个map放到list中
     * @author quanquan
     *
     */
    public class TestStoreData {
    	public static void main(String[] args) {
    
    		Map<String,Object> row1 = new HashMap<>();
    		row1.put("id",1001);
    		row1.put("姓名","张三");
    		row1.put("薪水",20000);
    		row1.put("入职日期","2018.5.5");
    		
    		Map<String,Object> row2 = new HashMap<>();
    		row2.put("id",1002);
    		row2.put("姓名","李四");
    		row2.put("薪水",30000);
    		row2.put("入职日期","2005.4.4");
    		
    		Map<String,Object> row3 = new HashMap<>();
    		row3.put("id",1001);
    		row3.put("姓名","王五");
    		row3.put("薪水",3000);
    		row3.put("入职日期","2020.5.4");
    		
    		List<Map<String,Object>> table1 = new ArrayList<>();
    		table1.add(row1);
    		table1.add(row2);
    		table1.add(row3);
    		for(Map<String,Object> row:table1) {
    			Set<String> keyset = row.keySet();
    			for(String key:keyset) {
    				System.out.print(key+":"+row.get(key)+"\t");
    			}
    		System.out.println();	
    		}
    	}	
    }
    • 每一行数据使用一个javabean对象;整个表格使用一个Map/List
    package cn.sxt.mycollection;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * 测试表格数据存储
     * 体会ORM思想
     * 每一行数据使用javabean对象存储,多行使用放到map或list中
     * @author lenovo
     *
     */
    public class TestStoreData2 {
    	public static void main(String[] args) {
    		User user1 = new User(1001,"张三",20000,"2018.5.5");
    		User user2 = new User(1002,"李四",30000,"2005.4.4");
    		User user3 = new User(1003,"王五",3000,"2020.4.5");
    		
    		List<User> list = new ArrayList<>();
    		list.add(user1);
    		list.add(user2);
    		list.add(user3);
    		for (User u:list) {
    			System.out.println(u);
    		}
    		
    		Map<Integer,User> map = new HashMap<>();
    		map.put(1001,user1);
    		map.put(1002,user2);
    		map.put(1003,user3);
    		Set<Integer> keyset = map.keySet();
    		for(Integer key:keyset) {
    			System.out.println(key+"===="+map.get(key));
    		}
    		
    	}
    }
    
    class User{
    	private int id;
    	private String name;
    	private double salary;
    	private String hiredate;
    	
    	//一个完整的javabean。要有set和get方法,以及一个无参构造器!
    	public User() {
    		super();
    	}
    	
    	public User(int id, String name, double salary, String hiredate) {
    		super();
    		this.id = id;
    		this.name = name;
    		this.salary = salary;
    		this.hiredate = hiredate;
    	}
    	
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public double getSalary() {
    		return salary;
    	}
    	public void setSalary(double salary) {
    		this.salary = salary;
    	}
    	public String getHiredate() {
    		return hiredate;
    	}
    	public void setHiredate(String hiredate) {
    		this.hiredate = hiredate;
    	}
    	
    	public String toString() {
    		return "id:"+id+",name"+name+",salary:"+salary+",hiredate"+hiredate;
    	}
    	
    }

作业

一、1.BA(List接口和Set接口是Collection接口的子接口)C 2.DA(ArrayList类中有add()和add(index,vaule)两个重载,所以不会出现报错,但是因为list中只有一个元素,故索引为2超出范围了,故选A,运行时异常) 3.D 4.C 5.C

DAY20

三、参考

package cn.sxt.mycollection;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class Test1 {
	public static void main(String[] args) {
		
		BookList();
		BookMap();
		
	}
	
	//使用Map存放图书信息
	public static void BookMap() {
		Book book1 =new Book(1003, "语文", 49, "清华大学");
		Book book2 =new Book(1002, "数学", 59, "清华大学");
		Book book3 =new Book(1004, "英语", 90, "上海交通大学");
		Book book4 =new Book(1001, "物理", 30, "同济大学");
		Book book5 =new Book(1005, "化学", 59, "北京大学");
		
		Map<Integer,Book> bookmap = new HashMap<>();
		bookmap.put(book1.getId(), book1);
		bookmap.put(book2.getId(), book2);
		bookmap.put(book3.getId(), book3);
		bookmap.put(book4.getId(), book4);
		bookmap.put(book5.getId(), book5);
		
		System.out.println("使用map存放图书信息");
		Set<Integer> set = bookmap.keySet();
		for(Iterator<Integer> iterator = set.iterator();iterator.hasNext();) {
			Integer key = iterator.next();
            System.out.println(key + "--" + bookmap.get(key));
		
		}
	} 
	
	//使用List存放图书信息
	public static void BookList() {
		Book book1 =new Book(1003, "语文", 49, "清华大学");
		Book book2 =new Book(1002, "数学", 59, "清华大学");
		Book book3 =new Book(1004, "英语", 90, "上海交通大学");
		Book book4 =new Book(1001, "物理", 30, "同济大学");
		Book book5 =new Book(1005, "化学", 59, "北京大学");
		
		List<Book> booklist = new ArrayList<>();
		booklist.add(book1);
		booklist.add(book2);
		booklist.add(book3);
		booklist.add(book4);
		booklist.add(book5);
		
		System.out.println("使用list存放图书信息");
		for(int i=0;i<booklist.size();i++) {
			System.out.println(booklist.get(i));
		}
		
	}
	
}

class Book{
	
	private int id;
	private String name;
	private int price;
	private String out;
	
	public Book() {
		super();
	}
	public Book(int id, String name, int price, String out) {
		super();
		this.id = id;
		this.name = name;
		this.price = price;
		this.out = out;
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public String getOut() {
		return out;
	}
	public void setOut(String out) {
		this.out = out;
	}
	@Override
	public String toString() {
		return "[id=" + id + ", name=" + name + ", price=" + price + ", out=" + out + "]";
	
	}	
}
package cn.sxt.mycollection;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class Test2 {
	
	public static void main(String[] args) {
		bookHashSet();
		bookTreeSet();
	}
	
	public static void bookHashSet() {
		Book2 book1 =new Book2(1003, "语文", 49, "清华大学");
		Book2 book2 =new Book2(1002, "数学", 59, "清华大学");
		Book2 book3 =new Book2(1004, "英语", 90, "上海交通大学");
		Book2 book4 =new Book2(1001, "语文", 49, "清华大学"); //id不一样,可以添加
		Book2 book5 =new Book2(1003, "语文", 49, "清华大学"); //id一样,不可以添加
		
		Set bookhashset = new HashSet();
		//于 HashSet 的 add() 方法添加集合元素时实际上转变为调用 HashMap 的 put() 方法来添加 key-value 对。HashMap 的 put() 方法首先调用.hashCode() 判断返回值相等,如果返回值相等则再通过 equals 比较也返回 true,最终认为key对象是相等的已经在HashMap中存在了。

		bookhashset.add(book1);
		bookhashset.add(book2);
		bookhashset.add(book3);
		bookhashset.add(book4);
		bookhashset.add(book5);
		
		System.out.println("使用HashSet存放图书信息");
		for(Iterator<Book2> iter = bookhashset.iterator();iter.hasNext();) {
			Book2 book = iter.next();
			System.out.println(book);
		}
	}
	
	public static void bookTreeSet() {
		Book2 book1 =new Book2(1003, "语文", 49, "清华大学");
		Book2 book2 =new Book2(1002, "数学", 59, "清华大学");
		Book2 book3 =new Book2(1004, "英语", 90, "上海交通大学");
		Book2 book4 =new Book2(1001, "语文", 49, "清华大学"); //id不一样,可以添加
		Book2 book5 =new Book2(1003, "语文", 49, "清华大学"); //id一样,不可以添加
		
		Set booktreeset = new TreeSet();
		//TreeMap中调用put方法添加键值时,调用对象的它的 compareTo(或 compare)方法对所有键进行比较,此方法饭回0,则认为两个键就是相等的。
		
		booktreeset.add(book1);
		booktreeset.add(book2);
		booktreeset.add(book3);
		booktreeset.add(book4);
		booktreeset.add(book5);
		
		System.out.println("使用TreeSet存放图书信息");
		for(Iterator<Book2> iter = booktreeset.iterator();iter.hasNext();) {
			Book2 book = iter.next();
			System.out.println(book);
		}
		
	}
	
}

class Book2 implements Comparable<Book2> {
	
	private int id;
	private String name;
	private int price;
	private String out;
	
	//实现compareTo()方法
	public int compareTo(Book2 o) {
		if(this.price<o.price) {
			return -1;
		}else if(this.price>o.price) {
			return 1;
		}else {
			if(this.id<o.id) {
				return -1;
			}else if(this.id<o.id){
				return 1;
			}else {
				return 0;
			}
		}
	}
	
	//重写equals方法
	public boolean equals(Object obj) {
		//判断对象是不是Book2对象
		if(obj instanceof Book2) {
			Book2 temp = (Book2)obj;
			if(temp.getId()!=this.getId()) {
				return false;
			}else {
				return true;
			}
		}else {
			return false;
		}
	}
	
	//重写hashCode方法
	public int hashCode() {
		//hashCode方法返回的是int类型,并且保证返回值要与Goods02对象的属性有关
		return this.getId();
	}	
	
	public Book2() {
		super();
	}
	public Book2(int id, String name, int price, String out) {
		super();
		this.id = id;
		this.name = name;
		this.price = price;
		this.out = out;
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public String getOut() {
		return out;
	}
	public void setOut(String out) {
		this.out = out;
	}
	@Override
	public String toString() {
		return "[id=" + id + ", name=" + name + ", price=" + price + ", out=" + out + "]";
	
	}
}
package cn.sxt.mycollection;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class Test3 {
	
	public static void main(String[] args) {
		listToMap();
		mapToList();
	}
	
	public static void listToMap() {
		
		Student stu1 = new Student(101,"张三",16,"男");
		Student stu2 = new Student(102,"李四",15,"男");
		Student stu3 = new Student(105,"李萌",16,"女");
		Student stu4 = new Student(104,"赵慧",17,"女");
		Student stu5 = new Student(103,"孙超",18,"男");
		
		List<Student> list = new ArrayList<>();
		list.add(stu1);
		list.add(stu2);
		list.add(stu3);
		list.add(stu4);
		list.add(stu5);
		System.out.println("List遍历的结果为:");
		for(int i=0;i<list.size();i++) {
			System.out.println(list.get(i));
		}
		
		Map<Integer,Student> map = new HashMap<>();
		int result; //用来存放list元素的id
		for(int i=0;i<list.size();i++) {
			result = list.get(i).getId();
			map.put(result, list.get(i));
		}
		
		Set<Integer> ss = map.keySet();
		System.out.println("List转换为Map的结果为:");
		for(Iterator<Integer> iter = ss.iterator();iter.hasNext();) {
			Integer key = iter.next();
			System.out.println(key+"--"+map.get(key));
		}
	}

	public static void mapToList() {
		StudentEntry stu1 = new StudentEntry(101,"张三",16,"男");
		StudentEntry stu2 = new StudentEntry(102,"李四",15,"男");
		StudentEntry stu3 = new StudentEntry(105,"李萌",16,"女");
		StudentEntry stu4 = new StudentEntry(104,"赵慧",17,"女");
		StudentEntry stu5 = new StudentEntry(103,"孙超",18,"男");
		
		Map<Integer,StudentEntry> map2 = new HashMap<>();
		map2.put(stu1.getId(), stu1);
		map2.put(stu2.getId(), stu2);
		map2.put(stu3.getId(), stu3);
		map2.put(stu4.getId(), stu4);
		map2.put(stu5.getId(), stu5);
		
		List<StudentEntry> list2 = new ArrayList<>();
		Set<Entry<Integer, StudentEntry>> key = map2.entrySet();
		for(Entry<Integer, StudentEntry> iter:key) {
			list2.add(iter.getValue());
		}
		
		System.out.println("Map转List的结果为:");
		for(int i=0;i<list2.size();i++) {
			System.out.println(list2.get(i));
		}
	}
}

class StudentEntry extends Student{
	//父类构造方法不能继承,所以要重写
	public StudentEntry() {
		super();
	}

	public StudentEntry(int id, String name, int age, String sex) {
		super(id,name,age,sex);
	}
}

class Student{
	
	private int id;
	private String name;
	private int age;
	private String sex;
	
	public String toString() {
		return "[id:"+id+",name:"+name+",age:"+age+",sex:"+sex+"]";
	}
	
	public Student() {
		super();
	}

	public Student(int id, String name, int age, String sex) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.sex = sex;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}
	
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值