JavaSe——集合_Part2

A.泛型

package com.core.collection.demo;

import java.util.ArrayList;
import java.util.Iterator;

/*
 * ArrayList存储字符串并遍历
 * 
 * 我们按照正常的写法来写这个程序, 结果确出错了。
 * 为什么呢?
 * 		因为我们开始存储的时候,存储了String和Integer两种类型的数据。
 * 		而在遍历的时候,我们把它们都当作String类型处理的,做了转换,所以就报错了。
 * 但是呢,它在编译期间却没有告诉我们。
 * 所以,我就觉得这个设计的不好。
 * 回想一下,我们的数组
 * 		String[] strArray = new String[3];
 * 		strArray[0] = "hello";
 * 		strArray[1] = "world";
 * 		strArray[2] = 10;
 * 集合也模仿着数组的这种做法,在创建对象的时候明确元素的数据类型。这样就不会在有问题了。
 * 而这种技术被称为:泛型。
 * 
 * 泛型:是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。参数化类型,把类型当作参数一样的传递。
 * 格式:
 * 		<数据类型>
 * 		此处的数据类型只能是引用类型。
 * 好处:
 * 		A:把运行时期的问题提前到了编译期间
 * 		B:避免了强制类型转换
 * 		C:优化了程序设计,解决了黄色警告线
 */

public class Test {

	public static void main(String[] args) {
		ArrayList list = new ArrayList();
		list.add("hello");
		list.add("world");
		list.add("java");
		// list.add(10); 加了泛型之后,编译不通过

		// 遍历list输出数据
		// A.toArray转成数组-这个方法还是要强转的,因为他用的是父类Collection的toArray方法
		Object[] array = list.toArray();
		for (int i = 0; i < array.length; i++) {
			String next = (String) array[i];
			System.out.println(next);
		}

		// B.使用特有方法size和get-注意这个方法不需要强转
		for (int i = 0; i < list.size(); i++) {
			String s = list.get(i);
			System.out.println(s);
		}

		// C.使用得迭代器-注意这个方法不需要强转
		Iterator iterator = list.iterator();
		while (iterator.hasNext()) {
			String s = iterator.next();
			System.out.println(s);
		}
		// D.使用for循环改进,提高效率
		System.out.println("========");
		for (Iterator it2 = list.iterator(); it2.hasNext();) {
			String s = it2.next();
			System.out.println(s);
		}
	}

}


1:泛型是一种特殊的类型,它把指定类型的工作推迟到客户端代码声明并实例化类或方法的时候进行。

   也被称为参数化类型,可以把类型当作参数一样传递过来,在传递过来之前我不明确,但是在使用的时候我就用明确了。

2:泛型的好处

A:提高了程序的安全性

B:将运行期遇到的问题转移到了编译期

C:省去了类型强转的麻烦



B.泛型类

l  泛型类

•    把泛型定义在类上

•    格式:public class 类名<泛型类型1,…>

•    注意:泛型类型必须是引用类型


泛型类:
package com.core.collection.demo1;

public class ObjectTool  {

	private T t;
	public void setObj(T t){
		this.t = t;
	}
	
	public T getObj(){
		return t;
	}
}

测试类:
package com.core.collection.demo1;


public class Test {

	//演示泛型类:泛型定义在类上
	public static void main(String[] args) {
		ObjectTool tool = new ObjectTool();
		tool.setObj("hello");
		String s = tool.getObj();
		System.out.println(s);
//		tool.setObj(new Student("张三",20)); 编译报错
		
		ObjectTool tool2 = new ObjectTool();
//		tool2.setObj("world"); 编译报错
		tool2.setObj(new Student("张三",20));
		Student ss = tool2.getObj();
		System.out.println(ss.getName()+"--"+ss.getAge());
	
	}

}


C.泛型方法

l  泛型方法

•    把泛型定义在方法上

•    格式:public<泛型类型> 返回类型方法名(泛型类型.)

注意泛型方法和泛型类的区别。演示输出整型、字符串、布尔型数据的例子:
先用泛型类演示:

package com.core.collection.demo2;

public class ObjectTool {

	public void print(T t) {
		System.out.println(t);
	}
}

测试类:
package com.core.collection.demo2;

public class Test {

	public static void main(String[] args) {
		// 输出整型
		ObjectTool tool = new ObjectTool();
		// tool.print("abc"); 编译报错
		tool.print(10);

		// 输出字符串
		ObjectTool tool2 = new ObjectTool();
		// tool2.print(10);//编译报错
		tool2.print("abc");
		
//		输出布尔值
		ObjectTool tool3 = new ObjectTool();
		tool3.print(true);

	}

}


再用泛型方法:

package com.core.collection.demo2;

public class ObjectTool2 {

	public  void print(T t) {
		System.out.println(t);
	}
}

测试类:
package com.core.collection.demo2;

public class Test {

	public static void main(String[] args) {
		// 输出整型
		ObjectTool tool = new ObjectTool();
		// tool.print("abc"); 编译报错
		tool.print(10);

		// 输出字符串
		ObjectTool tool2 = new ObjectTool();
		// tool2.print(10);//编译报错
		tool2.print("abc");
		
//		输出布尔值
		ObjectTool tool3 = new ObjectTool();
		tool3.print(true);
		
		System.out.println("----使用泛型方法-----");
		ObjectTool2 tool4 = new ObjectTool2();
		tool4.print("hello");
		tool4.print(2015);
		tool4.print(true);
		

	}

}



D.泛型接口

l  泛型接口

•    把泛型定义在接口上

•    格式:public  interface 接口名<泛型类型1…>


接口定义:
package com.core.collection.demo3;

public interface Inter {
	public abstract void print(T t);

}


第一种实现:
package com.core.collection.demo3;

//实现类在实现接口的时候,有两种情况,
//第一种,已经知道该类型是什么了。但这种情况不常见
public class InterImpl implements Inter {

	@Override
	public void print(String t) {
		System.out.println(t);
	}

}

第二种接口实现(不知道该类型是什么)
package com.core.collection.demo3;

//第二种情况,还不知道该类型是什么
public class InterImpl2 implements Inter {

	@Override
	public void print(T t) {
		System.out.println(t);
	}

}
测试类:
package com.core.collection.demo3;

public class Test {

	public static void main(String[] args) {
		// 第一种类型测试
		InterImpl impl = new InterImpl();
		impl.print("hello");
		// impl.print(123); 编译报错
		// 这种情况不常见
		
		//第二种情况测试
		InterImpl2 impl2 = new InterImpl2();
		impl2.print("world");
		
		InterImpl2 impl3 = new InterImpl2();
		impl3.print(123);
	}

}


D.泛型通配符

l  泛型通配符

•    任意类型,如果没有明确,那么就是Object以及任意的Java类了

l  ? extends E

•    向下限定,E及其子类

l  ? super E

•    向上限定,E及其父类


package com.core.collection.demo4;

import java.util.ArrayList;

public class Test {

	public static void main(String[] args) {
		// 如果给出,则必须一致
		ArrayList list1 = new ArrayList();
		// ArrayList list2 = new ArrayList(); 编译报错
		// ArrayList list3 = new ArrayList();编译报错
		// ArrayList list4 = new ArrayList();编译报错
		// ArrayList list4 = new ArrayList();编译报错

		// ? 表示任意类型都可
		ArrayList list5 = new ArrayList();
		ArrayList list6 = new ArrayList();
		ArrayList list7 = new ArrayList();
		ArrayList list8 = new ArrayList();
		ArrayList list9 = new ArrayList();
		// ? extends E
		ArrayList list10 = new ArrayList();
		// ArrayList list10 = new ArrayList();//报错
		ArrayList list11 = new ArrayList();

		// ? super E
//		ArrayList list12 = new ArrayList();//报错
		ArrayList list13 = new ArrayList();
		ArrayList list14 = new ArrayList();
	}

}

class Animal {
}

class Dog extends Animal {
}

class Cat extends Animal {
}
 
   

E.增强for循环-JDK5 新特性

静态导入、泛型、增强for循环、自动拆装箱、可变参数、枚举

l  增强for概述

•    简化数组和Collection集合的遍历

l  格式:

•    for(元素数据类型变量 : 数组或者Collection集合) {

         使用变量即可,该变量就是元素

    }

l  好处:简化遍历

l  注意事项:增强for的目标要判断是否为null

l  把前面的集合代码的遍历用增强for改进


F.静态导入-JDK5 新特性


l  静态导入概述

•    格式:importstatic 包名….类名.方法名;

•    可以直接导入到方法的级别

l  注意事项

•    方法必须是静态的

•    如果有多个同名的静态方法,容易不知道使用谁?这个时候要使用,必须加前缀。由此可见,意义不大,所以一般不用,但是要能看懂。


G.可变参数-JDK5 新特性

l  可变参数概述

•    定义方法的时候不知道该定义多少个参数

l  格式

•    修饰符 返回值类型 方法名(数据类型…  变量名){}

•    注意:

•    这里的变量其实是一个数组

•    如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个

举例:求和

package com.core.collection.demo5;

public class Test {

	public static void main(String[] args) {
		int res = sum(1, 2, 3, 4);
		int res2 = sum(1, 2, 3, 4, 5);
		int res3 = sum(1, 2, 3, 4, 5,6);
		System.out.println(res+","+res2+","+res3);//10,15,21
	}

	private static int sum(int... a) {
		int sum = 0;
		for (int i : a) {
			sum += i;
		}
		return sum;
	}
}

K.Arrays工具类的asList()方法的使用

l  Arrays工具类中的一个方法

•    public static List asList(T... a)


package com.core.collection.demo6;

import java.util.Arrays;
import java.util.List;

public class Test {

	public static void main(String[] args) {
		// Arrays 的asList方法
		String[] arrays = new String[]{"hello","world","java"};
		List list = Arrays.asList(arrays);
		//遍历
		for (String s : list) {
			System.out.println(s);
		}
		
//		list.add("android");报错 UnsupportedOperationException
//		list.remove(1);报错 UnsupportedOperationException
		list.set(1, "android");
		System.out.println(list);//[hello, android, java]
	}

}

L.产生10个1-20之间的随机数要求随机数不能重复案例


package com.core.collection.demo7;

import java.util.ArrayList;
import java.util.Random;

public class Test {
	// 产生10个1-20之间的随机数要求随机数不能重复案例
	public static void main(String[] args) {
		Random r = new Random();
		ArrayList list = new ArrayList();
		while(list.size()!=10){
			int num = r.nextInt(20)+1;
			if(!list.contains(num)){
				list.add(num);
			}
		}
		System.out.println(list);
	}

}


M.ArrayList集合的toString()方法源码解析

代码:

         Collectionc = new ArrayList();

         c.add("hello");

         c.add("world");

         c.add("java");

        

         System.out.println(c);

        

为什么c输出的不是地址值呢?

         A:Collectionc = new ArrayList();

                   这是多态,所以输出c的toString()方法,其实是输出ArrayList的toString()

         B:看ArrayList的toString()

                   而我们在ArrayList里面却没有发现toString()。

                   以后遇到这种情况,也不要担心,你认为有,它却没有,就应该去它父亲里面看看。

         C:toString()的方法源码

        

                   publicString toString() {

                 Iterator it = iterator(); //集合本身调用迭代器方法,得到集合迭代器

                 if (! it.hasNext())

                     return "[]";

        

                 StringBuilder sb = new StringBuilder();

                 sb.append('[');

                 for (;;) {

                     E e = it.next();//e=hello,world,java

                     sb.append(e == this ? "(thisCollection)" : e);

                     if (! it.hasNext())

                              //[hello,world, java]

                         returnsb.append(']').toString();

                     sb.append(',').append(' ');

                 }

             }



L.用户登录注册案例用户操作类的具体实现


注意这个例子,自己写,存在了很多的错误。

用户类:com.core.pojo

package com.core.pojo;

/**
 * @author Administration
 * 
 */
public class User {
	private String name;
	private String password;

	public User() {
		super();
	}

	public User(String name, String password) {
		super();
		this.name = name;
		this.password = password;
	}

	public String getName() {
		return name;
	}

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

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + password + "]";
	}

}



用户操作类接口:com.core.dao

package com.core.dao;

import com.core.pojo.User;

public interface  UserDao {
	public abstract boolean login(String name, String password);

	public abstract void regist(User user);
}

用户操作类接口实现类:com.core.dao.impl


package com.core.dao.impl;

import java.util.ArrayList;

import com.core.dao.UserDao;
import com.core.pojo.User;

public class UserDaoImpl implements UserDao {

	private static ArrayList list = new ArrayList();

	@Override
	public boolean login(String name, String password) {
		boolean flag = false;
		for(User user:list){
			if(user.getName().equals(name)&& user.getPassword().equals(password)){
				flag = true;
				break;
			}
		}
		return flag;
	}

	@Override
	public void regist(User user) {
		list.add(user);
	}

}


游戏类:
package com.core.game;

import java.util.Random;
import java.util.Scanner;

public class GuessNumber {

	public static void start() {
		Random r = new Random();
		int num = r.nextInt(100);
		int count = 0;
		System.out.println("num:"+num);
		while(true){
			System.out.println("你猜的是:");
			Scanner sc = new Scanner(System.in);
			int guessNum = sc.nextInt();
			if(guessNum == num){
				System.out.println("恭喜你,猜对了,共猜了"+count+"次.");
				break;
			}else{
				count++;
				if(num>guessNum){
					System.out.println("小了");
				}else{
					System.out.println("大了");
				}
			}
		}
		
	}

}

测试类:
package com.core.test;

import java.util.Scanner;

import com.core.dao.impl.UserDaoImpl;
import com.core.game.GuessNumber;
import com.core.pojo.User;

public class UserTest {

	public static void main(String[] args) {
		while (true) {
			System.out.println("------欢迎光临-------");
			System.out.println("1.注册");
			System.out.println("2.登陆");
			System.out.println("3.退出");

			Scanner sc = new Scanner(System.in);
			int num = sc.nextInt();

			Scanner scName = new Scanner(System.in);
			Scanner scPwd = new Scanner(System.in);
			Scanner scGame = new Scanner(System.in);
			switch (num) {
			case 1:
				// 注册
				System.out.println("请输入用户名:");
				String name = scName.nextLine();
				System.out.println("请输入密码:");
				String psw = scPwd.nextLine();
				User user = new User(name, psw);
				UserDaoImpl impl = new UserDaoImpl();
				impl.regist(user);
				System.out.println("注册成功");
				break;
			case 2:
				// 登陆
				System.out.println("请输入用户名:");
				String name2 = scName.nextLine();
				System.out.println("请输入密码:");
				String psw2 = scPwd.nextLine();
				UserDaoImpl impl2 = new UserDaoImpl();
				boolean flag = impl2.login(name2, psw2);
				if (flag) {
					System.out.println("登陆成功");
					System.out.println("是否开始玩游戏?y/n");
					while (true) {
						String nextLine = scGame.nextLine();
						if (nextLine.equalsIgnoreCase("y")) {
							GuessNumber.start();
							System.out.println("你还玩吗?y/n");
						}else{
							break;
						}
					}
					System.out.println("谢谢使用,欢迎下次再来");
//					System.exit(0);
					 break; //这里写break,结束的是switch
				} else {
					System.out.println("用户名或密码不正确");
				}
				break;
			case 3:
				// 退出
				System.out.println("退出了。");
				System.exit(0);
				break;

			default:
				System.out.println("输出有误");
				break;
			}
		}
	}
}



M.Set集合



l  Set接口概述

•    一个不包含重复元素的 collection。

l  Set案例

•    存储字符串并遍历

•    存储自定义对象并遍历



不保证顺序;允许使用null接口。


package com.core.collection.demo;

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

public class Test {

	public static void main(String[] args) {
		Set set = new HashSet();
		set.add("hello");
		set.add("world");
		set.add("java");
		//和存进去的顺序不一样
		for (String str : set) {
			System.out.println(str);
			// hello
			// java
			// world
		}
		
		System.out.println("-------");
		set.add("android");
		set.add("java");
		//只存了一个java
		System.out.println(set);//[hello, android, java, world]
	}

}


N.HashSet保证元素唯一性的源码解析

interface Collection {

         ...

}

 

interface Set extends Collection {

         ...

}

 

class HashSet implements Set {

         private static final Object PRESENT = new Object();

         private transient HashMap map;

        

         public HashSet() {

                   map= new HashMap<>();

         }

        

         publicboolean add(E e) { //e=hello,world

       return map.put(e, PRESENT)==null;

    }

}

 

class HashMap implements Map {

         publicV put(K key, V value) { //key=e=hello,world

        

                   //看哈希表是否为空,如果空,就开辟空间

       if (table == EMPTY_TABLE) {

           inflateTable(threshold);

       }

       

       //判断对象是否为null

       if (key == null)

           return putForNullKey(value);

       

       int hash = hash(key); //和对象的hashCode()方法相关

       

       //在哈希表中查找hash值

       int i = indexFor(hash, table.length);

       for (Entry e = table[i]; e != null; e = e.next) {

                //这次的e其实是第一次的world

           Object k;

           if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {

                V oldValue = e.value;

                e.value = value;

                e.recordAccess(this);

                return oldValue;

                //走这里其实是没有添加元素

           }

       }

 

       modCount++;

       addEntry(hash, key, value, i); //把元素添加

       return null;

    }

    

   transient int hashSeed = 0;

   

   final int hash(Object k) { //k=key=e=hello,

       int h = hashSeed;

       if (0 != h && k instanceof String) {

           return sun.misc.Hashing.stringHash32((String) k);

       }

 

       h ^= k.hashCode(); //这里调用的是对象的hashCode()方法

 

       // This function ensures that hashCodes that differ only by

       // constant multiples at each bit position have a bounded

       // number of collisions (approximately 8 at default load factor).

       h ^= (h >>> 20) ^ (h >>> 12);

       return h ^ (h >>> 7) ^ (h >>> 4);

    }

}

 

 

hs.add("hello");

hs.add("world");

hs.add("java");

hs.add("world");


O.HashSet练习

package com.core.collection.demo1;

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

public class Test {

	public static void main(String[] args) {
		HashSet hs = new HashSet();
		Student s1 = new Student("张三", 18);
		Student s2 = new Student("李四", 20);
		Student s3 = new Student("王五", 17);
		Student s4 = new Student("赵六", 22);
		Student s5 = new Student("张三", 18);
		Student s6 = new Student("赵六", 24);
		
		hs.add(s1);
		hs.add(s2);
		hs.add(s3);
		hs.add(s4);
		hs.add(s5);
		hs.add(s6);
		for (Student s : hs) {
			System.out.println(s.toString());
		}
		// Student [name=赵六, age=22]
		// Student [name=张三, age=18]
		// Student [name=李四, age=20]
		// Student [name=王五, age=17]
		// Student [name=张三, age=18]
		// Student [name=赵六, age=24]
		System.out.println("-----------");
		//存了两遍张三
		
		//重写hashCode和equals方法 
		// Student [name=赵六, age=24]
		// Student [name=李四, age=20]
		// Student [name=张三, age=18]
		// Student [name=赵六, age=22]
		// Student [name=王五, age=17]

	}
}


P.LinkedHashSet


l  LinkedHashSet类概述

•    元素有序唯一

•    由链表保证元素有序

•    由哈希表保证元素唯一




package com.core.collection.demo2;

import java.util.LinkedHashSet;

public class Test {
	// 由哈希表确保唯一性
	// 由链表保证元素有序,存储和取出有序
	public static void main(String[] args) {
		LinkedHashSet set = new LinkedHashSet();
		set.add("hello");
		set.add("world");
		set.add("java");
		set.add("hello");
		for (String string : set) {
			System.out.println(string);
		}
		// hello
		// world
		// java

	}
}


package com.core.collection.demo3;

import java.util.TreeSet;

public class Test {
	// TreeSet保存Integer
	//排序分两种:
	//A.自然排序
	//B.比较器排序
	public static void main(String[] args) {
		TreeSet set = new TreeSet();
		set.add(10);
		set.add(75);
		set.add(24);
		set.add(93);
		set.add(45);
		set.add(62);
		for (Integer integer : set) {
			System.out.println(integer);
		}
		// 10
		// 24
		// 45
		// 62
		// 75
		// 93

	}
}



TreeSet保证元素排序的源码解析

interface Collection {...}

 

interface Set extends Collection {...}

 

interface NavigableMap {

 

}

 

class TreeMap implements NavigableMap {

          public V put(K key, V value) {

       Entry t = root;

       if (t == null) {

           compare(key, key); // type (and possibly null) check

 

           root = new Entry<>(key, value, null);

           size = 1;

           modCount++;

           return null;

       }

       int cmp;

       Entry parent;

       // split comparator and comparable paths

       Comparator cpr = comparator;

       if (cpr != null) {

           do {

                parent = t;

                cmp = cpr.compare(key, t.key);

                if (cmp < 0)

                    t = t.left;

                else if (cmp > 0)

                    t = t.right;

                else

                    return t.setValue(value);

           } while (t != null);

       }

       else {

           if (key == null)

                throw newNullPointerException();

           Comparable k = (Comparable) key;

           do {

                parent = t;

                cmp = k.compareTo(t.key);

                if (cmp < 0)

                    t = t.left;

                else if (cmp > 0)

                    t = t.right;

               else

                    return t.setValue(value);

           } while (t != null);

       }

       Entry e = new Entry<>(key, value, parent);

       if (cmp < 0)

           parent.left = e;

       else

           parent.right = e;

        fixAfterInsertion(e);

       size++;

       modCount++;

       return null;

    }

}

 

class TreeSet implements Set {

         privatetransient NavigableMap m;

        

         publicTreeSet() {

                    this(new TreeMap());

         }

 

         publicboolean add(E e) {

       return m.put(e, PRESENT)==null;

    }

}

 

真正的比较是依赖于元素的compareTo()方法,而这个方法是定义在 Comparable里面的。

所以,你要想重写该方法,就必须是先 Comparable接口。这个接口表示的就是自然排序。



Q.TreeSet存储自定义对象

方法1:写一个MyComparator继承Comparator,重写Compare方法。在创建TreeSet的时候,以它为参数传到构造方法里:
Student类:
package com.core.collection.demo4;

public class Student {
	private String name;
	private int age;

	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

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

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

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

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

}


MyComparator:
package com.core.collection.demo4;

import java.util.Comparator;

public class MyComparator implements Comparator {

	@Override
	public int compare(Student o1, Student o2) {
		// 先按照年龄大小排序
		int num = o1.getAge() - o2.getAge();
		int num2 = num == 0 ? o1.getName().compareTo(o2.getName()) : num;
		return num2;
	}

}



测试类:
package com.core.collection.demo4;

import java.util.TreeSet;

public class Test {
	// TreeSet存储自定义对象
	// 排序:按年龄大小排序,由大到小,年龄一致,按姓名字母排序
	public static void main(String[] args) {
		Student s1 = new Student("张三", 12);
		Student s2 = new Student("李四", 32);
		Student s3 = new Student("王五", 22);
		Student s4 = new Student("赵六", 19);
		Student s5 = new Student("孙八", 12);
		
		TreeSet set = new TreeSet(new MyComparator());
		set.add(s1);//java.lang.ClassCastException
		//注意:在没有实现Comparator的时候,是报错的。
		set.add(s2);
		set.add(s3);
		set.add(s4);
		set.add(s5);
		for (Student student : set) {
			System.out.println(student);
		}
		// Student [name=孙八, age=12]
		// Student [name=张三, age=12]
		// Student [name=赵六, age=19]
		// Student [name=王五, age=22]
		// Student [name=李四, age=32]

	}
}

方法2:学生类继承Comparable接口,实现compare方法:


package com.core.collection.demo5;

public class Student implements Comparable {
	private String name;
	private int age;

	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

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

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

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

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

	@Override
	public int compareTo(Student o) {
		// 先按照年龄大小排序
		int num = this.getAge() - o.getAge();
		int num2 = num == 0 ? this.getName().compareTo(o.getName()) : num;
		return num2;
	}

}


测试类:
package com.core.collection.demo5;

import java.util.TreeSet;

public class Test {
	// TreeSet存储自定义对象
	// 排序:按年龄大小排序,由大到小,年龄一致,按姓名字母排序
	public static void main(String[] args) {
		Student s1 = new Student("张三", 12);
		Student s2 = new Student("李四", 32);
		Student s3 = new Student("王五", 22);
		Student s4 = new Student("赵六", 19);
		Student s5 = new Student("孙八", 12);
		
		TreeSet set = new TreeSet();
		set.add(s1);//java.lang.ClassCastException
		//注意:在没有实现Comparator的时候,是报错的。
		set.add(s2);
		set.add(s3);
		set.add(s4);
		set.add(s5);
		for (Student student : set) {
			System.out.println(student);
		}
		// Student [name=孙八, age=12]
		// Student [name=张三, age=12]
		// Student [name=赵六, age=19]
		// Student [name=王五, age=22]
		// Student [name=李四, age=32]

	}
}

方法3:匿名内部类


学生类:
package com.core.collection.demo6;

public class Student {
	private String name;
	private int age;

	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

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

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

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

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

}

测试类:

package com.core.collection.demo6;

import java.util.Comparator;
import java.util.TreeSet;

public class Test {
	// TreeSet存储自定义对象
	// 排序:按年龄大小排序,由大到小,年龄一致,按姓名字母排序
	public static void main(String[] args) {
		Student s1 = new Student("张三", 12);
		Student s2 = new Student("李四", 32);
		Student s3 = new Student("王五", 22);
		Student s4 = new Student("赵六", 19);
		Student s5 = new Student("孙八", 12);

		TreeSet set = new TreeSet(new Comparator() {

			@Override
			public int compare(Student o1, Student o2) {
				// 先按照年龄大小排序
				int num = o1.getAge() - o2.getAge();
				int num2 = num == 0 ? o1.getName().compareTo(o2.getName())
						: num;
				return num2;
			}
		});
		set.add(s1);// java.lang.ClassCastException
		// 注意:在没有实现Comparator的时候,是报错的。
		set.add(s2);
		set.add(s3);
		set.add(s4);
		set.add(s5);
		for (Student student : set) {
			System.out.println(student);
		}
		// Student [name=孙八, age=12]
		// Student [name=张三, age=12]
		// Student [name=赵六, age=19]
		// Student [name=王五, age=22]
		// Student [name=李四, age=32]

	}
}


R.产生10个1-20之间的随机数要求随机数不能重复案例简洁版


package com.core.collection.demo7;

import java.util.HashSet;
import java.util.Random;

public class Test {

	public static void main(String[] args) {
		// 产生10个1-20之间的随机数要求随机数不能重复案例简洁版
		Random r = new Random();
		HashSet set = new HashSet();
		while(set.size()<10){
			int num = r.nextInt(20)+1;
			set.add(num);
		}

		for (Integer integer : set) {
			System.out.println(integer);
		}
	}

}




1:登录注册案例(理解)

 

2:Set集合(理解)

         (1)Set集合的特点

                   无序,唯一

         (2)HashSet集合(掌握)

                   A:底层数据结构是哈希表(是一个元素为链表的数组)

                   B:哈希表底层依赖两个方法:hashCode()和equals()

                     执行顺序:

                            首先比较哈希值是否相同

                                     相同:继续执行equals()方法

                                               返回true:元素重复了,不添加

                                               返回false:直接把元素添加到集合

                                     不同:就直接把元素添加到集合

                   C:如何保证元素唯一性的呢?

                            由hashCode()和equals()保证的

                   D:开发的时候,代码非常的简单,自动生成即可。

                   E:HashSet存储字符串并遍历

                   F:HashSet存储自定义对象并遍历(对象的成员变量值相同即为同一个元素)

         (3)TreeSet集合

                   A:底层数据结构是红黑树(是一个自平衡的二叉树)

                   B:保证元素的排序方式

                            a:自然排序(元素具备比较性)

                                     让元素所属的类实现Comparable接口

                            b:比较器排序(集合具备比较性)

                                     让集合构造方法接收Comparator的实现类对象

                   C:把我们讲过的代码看一遍即可

         (4)案例:

                   A:获取无重复的随机数

                   B:键盘录入学生按照总分从高到底输出

                  

3:Collection集合总结(掌握)

         Collection

                   |--List       有序,可重复

                            |--ArrayList

                                     底层数据结构是数组,查询快,增删慢。

                                     线程不安全,效率高

                            |--Vector

                                     底层数据结构是数组,查询快,增删慢。

                                     线程安全,效率低

                            |--LinkedList

                                     底层数据结构是链表,查询慢,增删快。

                                     线程不安全,效率高

                   |--Set        无序,唯一

                            |--HashSet

                                     底层数据结构是哈希表。

                                     如何保证元素唯一性的呢?

                                               依赖两个方法:hashCode()和equals()

                                               开发中自动生成这两个方法即可

                                     |--LinkedHashSet

                                               底层数据结构是链表和哈希表

                                               由链表保证元素有序

                                               由哈希表保证元素唯一

                            |--TreeSet

                                     底层数据结构是红黑树。

                                     如何保证元素排序的呢?

                                               自然排序

                                               比较器排序

                                     如何保证元素唯一性的呢?

                                               根据比较的返回值是否是0来决定

                                              

4:针对Collection集合我们到底使用谁呢?(掌握)

         唯一吗?

                   是:Set

                            排序吗?

                                     是:TreeSet

                                     否:HashSet

                   如果你知道是Set,但是不知道是哪个Set,就用HashSet。

                           

                   否:List

                            要安全吗?

                                     是:Vector

                                     否:ArrayList或者LinkedList

                                               查询多:ArrayList

                                               增删多:LinkedList

                   如果你知道是List,但是不知道是哪个List,就用ArrayList。

        

         如果你知道是Collection集合,但是不知道使用谁,就用ArrayList。

        

         如果你知道用集合,就用ArrayList。

        

5:在集合中常见的数据结构(掌握)

         ArrayXxx:底层数据结构是数组,查询快,增删慢

         LinkedXxx:底层数据结构是链表,查询慢,增删快

         HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()

         TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序


























你可能感兴趣的:(JavaSe——集合_Part2)