关于容器的一些知识点以及部分代码

泛型

1.泛型简介:

1.1泛型的基本概念:

在这里插入图片描述

1.2泛型的好处:

代码可读性更好(不用强制转换);程序更加安全

1.3类型擦除:

编码时采用泛型写的类型参数,编译器会在编译时去掉,这称之为“类型擦除”

2.泛型的使用:

2.1定义泛型:

泛型字符可以是任何标识符,一般采用E,T,K,V,N,?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I55JDw1h-1645693071362)(C:\Users\15154\AppData\Roaming\Typora\typora-user-images\image-20220216100121878.png)]

2.2泛型类:

泛型类就是把泛型定义在类上,用户使用该类的时候,才把类型明确下来。泛型类的具体使用方法是在类的名称后添加一个或多个类型参数声明,如、<T,K,V>

2.2.1语法结构
public class ***<泛型表示符号>{

}
2.2.2示例
public class Generic <T>{
	private T flag;
	public void setFlag(T flag) {
		this.flag = flag;
	}
	public T getFlag() {
		return this.flag;
	}
}

public class Test {
	public static void main(String[] args) {
		Generic<String> generic = new Generic<>();
		generic.setFlag("admin");
		String flag = generic.getFlag();
		System.out.println(flag);
	}
}

2.3泛型接口:

泛型接口和泛型类的声明方式一致。泛型接口的具体类型需要在实现类中进行声明。

2.3.1语法结构:
public interface ***<泛型表示符号>{

}
2.3.2示例
//泛型接口
public interface Igeneric<T> {
	T getName(T name);
}

//接口实现类
public class IgenericImpl implements Igeneric<String>{
	@Override
	public String getName(String name) {
		// TODO Auto-generated method stub
		return name;
	}
}

//测试类
public class Test2 {
	public static void main(String[] args) {
		IgenericImpl igeneric = new IgenericImpl();
		String name = igeneric.getName("JioH");
		System.out.println(name);
		
		Igeneric<String> igeneric2 = new IgenericImpl();
		String name2 = igeneric2.getName("JioH");
		System.out.println(name2);
	}
}

2.4泛型方法:

2.4.1非静态方法
2.4.1.1语法结构
public <泛型表示符号> void  getName(泛型表示符号 name){
    
}

public <泛型表示符号> 泛型表示符号  getName(泛型表示符号 name){
    
}
2.4.1.2示例:
public class MethodGeneric {
    //无返回值
	public<T> void setName(T name) {
		System.out.println(name);
	}
    //有返回值
    public<T> T getName(T name) {
		return name;
	}
}

public class Test3 {
	public static void main(String[] args) {
		MethodGeneric mg = new MethodGeneric();
		mg.setName("JioH");
		mg.setName(951933);
		
		MethodGeneric mg1 = new MethodGeneric();
		String name = mg1.getName("JioH");
		System.out.println(name);
		Integer name1 = mg1.getName(951933);
		System.out.println(name1);
	}
}
2.4.2静态方法:

静态方法无法访问类上的泛型

只能在方法上定义泛型

2.4.2.1语法结构:
public static<泛型表示符号> void  getName(泛型表示符号 name){
    
}

public static<泛型表示符号> 泛型表示符号  getName(泛型表示符号 name){
    
}
2.4.2.2示例:
public class MethodGeneric {
    //无返回值
	public static <T> void getFlag(T flag) {
		System.out.println(flag);
	}
    //有返回值
	public static <T> T setFlag(T flag) {
		return flag;
	}
}

public class Test4{
    public static void main(String[] args) {
		//静态方法不需要实例化,用过类名直接调用
		MethodGeneric.setFlag("JioH");
		MethodGeneric.setFlag(123123);
		
		String flag = MethodGeneric.getFlag("jioh");
		Integer flag1 = MethodGeneric.getFlag(123123);
		System.out.println(flag);
		System.out.println(flag1);
	}
}
2.4.3泛型方法与可变参数

在泛型方法中,泛型也可以定义可变参数类型

2.4.3.1语法结构
public <泛型表示符号> void showMsg(泛型表示符号... args){

}
2.4.3.2示例
public <T> void method(T...args) {
		//遍历数组
		for(T t:args) {
			System.out.println(t);
		}
	}
public class Test5{
    public static void main(String[] args) {
		//实例化
		MethodGeneric mg = new MethodGeneric();
		String[] arr = new String[] {"a","b","c"};
		mg.method(arr);
		Integer[] arr2 = new Integer[] {1,2,3};
		mg.method(arr2);
	}
}

2.5通配符与上下限定:

只能在<>中使用

2.5.1无界通配符
2.5.1.1语法结构:
public void showFlag(Generic<?> generic){

}
2.5.1.2示例:
public class Generic <T>{
	private T flag;
	public void setFlag(T flag) {
		this.flag = flag;
	}
	public T getFlag() {
		return this.flag;
	}
}

public class ShowMsg {
    public void showFlag(Generic<?> generic){
        System.out.println(generic.getFlag());
    }
}

public class Test6 {
    public static void main(String[] args) {
        ShowMsg showMsg = new ShowMsg();
        Generic<Integer> generic = new Generic<>();
        generic.setFlag(20);
        showMsg.showFlag(generic);
        
        Generic<Number> generic1 = new Generic<>();
        generic1.setFlag(50);
        showMsg.showFlag(generic1);
        
        Generic<String> generic2 = new Generic<>();
        generic2.setFlag("JioH");
        showMsg.showFlag(generic2);
    }
}
2.5.2通配符的上限限定

上限限定表示通配符的类型是T类以及T类的子类或者T接口以及T接口的子接口;该方式同样适用于与泛型的上限限定

2.5.2.1语法结构
public void showFlag(Generic<? extends Number> generic){

}
2.5.2.2示例:
public class ShowMsg {
    public void showFlag(Generic<? extends Number> generic){
        System.out.println(generic.getFlag());
    }
}
2.5.3通配符的下限限定

下限限定表示通配符的类型是T类以及T类的父类或者T接口以及T接口的父接口;该方式不适用于泛型类

2.5.3.1语法结构
public void showFlag(Generic<? super Number> generic){

}
2.5.3.2示例:
public class ShowMsg {
    public void showFlag(Generic<? super Integer> generic){
        System.out.println(generic.getFlag());
    }
}

3泛型总结

1.基本类型不能用于泛型 Test t

2.不能通过类型参数创建对象 T elm = new T();

容器

1.容器的结构

1.1结构图

1.1.1单例集合

将数据一个一个的存储

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uAZNK8xk-1645693071367)(C:\Users\15154\AppData\Roaming\Typora\typora-user-images\image-20220216152657396.png)]

1.1.2双例集合

基于key和value的结构存储数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YOwr0Bzc-1645693071368)(C:\Users\15154\AppData\Roaming\Typora\typora-user-images\image-20220216152813178.png)]

2.单例集合的使用

2.1 Collection接口介绍

Collection是单例集合的根接口,它的两个子接口是List、Set接口

2.2 Collection接口中的抽象方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QgKMPICH-1645693071368)(C:\Users\15154\AppData\Roaming\Typora\typora-user-images\image-20220216154526228.png)]

2.3 List接口

2.3.1 List接口特点

有序、可重复

2.3.2 List的常用方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3zjQDiqb-1645693071369)(C:\Users\15154\AppData\Roaming\Typora\typora-user-images\image-20220216155409003.png)]

2.4 ArrayList容器类

ArrayList是List接口的实现类。是List存储特征的具体实现。

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

2.4.1添加元素
public class ArrayListTest {
	public static void main(String[] args) {
		//实例化 ArrayList容器
		List<String> list = new ArrayList<>();
		//添加元素
		boolean flag = list.add("123");
		System.out.println(flag);
		list.add(1, "JioH");
	}
}
2.4.2获取元素

get

for(int i = 0;i<list.size();i++){
	System.out.println(list.get(i));
}
2.4.3替换元素

set

String val = list.set(0, "JioH");
System.out.println(val);
for(int i=0;i<list.size();i++) {
    System.out.println(list.get(i));
}

//转换为object[]
//不能在转化的方法调用时进行强制类型转换
Object[] arr = list.toArray();
for(int i=0;i<arr.length;i++){
    String str = (String)arr[i];
    System.out.println(str);
}

//将单例集合转换为指定类型的数组
//类型需要参考泛型中的类型
String[] arr2 = list.toArray(new String[list.size()]);
for(int i=0;i<arr2.length;i++){
    System.out.println(arr2[i]);
}
2.4.4容器的并集操作

集合不可为空,若为空会返回FALSE

		List<String> a = new ArrayList<>();
		a.add("a");
		a.add("b");
		a.add("c");
		List<String> b = new ArrayList<>();
		b.add("d");
		b.add("e");
		//a并b
		boolean flag5 = a.addAll(b);
		System.out.println(flag5);
		for(String str:a) {
			System.out.println(str);
		}
2.4.5容器的交集操作
boolean flag6 = a.retainAll(b);
2.4.6容器的差集操作
//去掉a集合中,b有的元素
boolean flag6 = a.removeAll(b);
2.4.7源码分析
2.4.7.1 ArrayList底层存储方式

ArrayList底层是用数组实现的存储

2.5 Vector容器类

Vector底层是用数组实现的,线程安全低效

2.5.1 Vector的使用

Vector的使用与ArrayList是相同的,都实现了List接口,对List接口中的抽象方法做了具体实现

public class VectorTest {
	public static void main(String[] args) {
		//实例化Vector
		List<String> v = new Vector<>();
		v.add("a");
		v.add("b");
		v.add("a");
		for(int i=0;i<v.size();i++) {
			System.out.println(v.get(i));
		}
		//迭代	
		for(String str:v) {
			System.out.println(str);
		}
	}
}
2.5.2 Stack容器

Stack栈容器,是Vector的一个子类,它实现了一个标准的后进先出的栈。

2.5.2.1操作栈的方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ywgBCfie-1645693071369)(C:\Users\15154\AppData\Roaming\Typora\typora-user-images\image-20220218112001022.png)]

2.5.2.2 Stack的使用
public class StackTest {
	public static void main(String[] args) {
		//实例化栈容器
		Stack<String> s = new Stack<>();
		//将元素添加到栈容器中
		s.push("a");
		s.push("b");
		s.push("c");
		
		System.out.println(s.empty()); //false
		
		//查看栈顶元素
		System.out.println(s.peek());
		//返回元素在栈容器中的位置
		System.out.println(s.search("c"));
		//返回1 从栈顶开始计数
		//从容器中取出元素
		String s1 = s.pop();
		System.out.println(s1);
		String s2 = s.pop();
		System.out.println(s2);
		String s3 = s.pop();
		System.out.println(s3);
		
		System.out.println(s.empty()); //true
	}
}
2.5.2.3 Stack的使用案例
//匹配符号的对称性
public class StackTest {
	public static void main(String[] args) {
        StackTest stacktest = new StackTest();
		stacktest.symmetry();
	}
	public void symmetry() {
		String str = "...{...[...(...)...]...}..(...)..[..]...";
		//实例化
		Stack<String> stack = new Stack<>();
		boolean flag = true;
		
		for(int i = 0;i<str.length();i++) {
			char c = str.charAt(i);
			if(c == '{') {
				stack.push("}");
			}
			if(c == '[') {
				stack.push("]");
			}
			if(c == '(') {
				stack.push(")");
			}
			//判断符号是否匹配
			if(c == '}' || c == ']' || c == ')') {
				if(stack.empty()) {
					flag = false;
					break;
				}
				String x = stack.pop();
				//单个字符串转字符
				if(x.charAt(0) != c) {
					flag = false;
					break;
				}
			}
		}
		if(!stack.empty()) {
			flag = false;
		}
		System.out.println(flag);
	}

2.6 LinkedList 容器类

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

LinkedList实现了List接口,所以LinkedList是具备List的存储特征的(有序,元素可重复)。

2.6.1 LinkedList的使用
public class LinkedListTest {
	public static void main(String[] args) {
		//实例化
		List<String> list =  new LinkedList<>();
		//添加元素
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("a");
		//获取元素
		for(int i = 0;i<list.size();i++) {
			System.out.println(list.get(i));
		}
		
	}
}
2.6.2 LinkedList的使用(非List标准)
public class LinkedListTest {
	public static void main(String[] args) {
		//实例化
		LinkedList<String> linkedlist = new LinkedList<>();
		//在第一个位置添加一个元素
		linkedlist.addFirst("xixi");
		linkedlist.addFirst("haha");
		linkedlist.addFirst("xixihaha");
		for(String str:linkedlist) {
			System.out.println(str);
		}
		//在最后一个位置添加元素
		linkedlist.addLast("无变");
		linkedlist.addLast("嘎乐");
		linkedlist.addLast("嘻嘻哈哈");
		//获取第一个元素
		System.out.println(linkedlist.getFirst());
		//获取最后一个元素
		System.out.println(linkedlist.getLast());
		//移除第一个元素
		linkedlist.removeFirst();
		//移除最后一个元素
		linkedlist.removeLast();
		//从此列表所表示的堆栈中弹出一个元素,等效于removeFirst
		linkedlist.pop();
		//将元素推入此列表所表示的堆栈中,等效于addFirst
		linkedlist.push("哈哈哈哈");
		boolean flag = linkedlist.isEmpty();
		System.out.println(flag);
	}
}
2.6.3 LinkedList源码分析
2.6.3.1 节点类
    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;
        }
    }
//上一个节点的地址   元素对象的地址  下一个节点的地址
2.6.3.2 成员变量
	transient int size = 0;

    /**
     * Pointer to first node.
     * Invariant: (first == null && last == null) ||
     *            (first.prev == null && first.item != null)
     */
    transient Node<E> first;

    /**
     * Pointer to last node.
     * Invariant: (first == null && last == null) ||
     *            (last.next == null && last.item != null)
     */
    transient Node<E> last;
2.6.3.3 添加元素
    /**
     * Appends the specified element to the end of this list.
     *
     * <p>This method is equivalent to {@link #addLast}.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    /**
     * Links e as last element.
     */
	void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }
2.6.3.4 头尾添加元素
2.6.3.4.1 addFirst
    /**
     * Inserts the specified element at the beginning of this list.
     *
     * @param e the element to add
     */
    public void addFirst(E e) {
        linkFirst(e);
    }
    /**
     * Links e as first element.
     */
    private void linkFirst(E e) {
        final Node<E> f = first;
        final Node<E> newNode = new Node<>(null, e, f);
        first = newNode;
        if (f == null)
            last = newNode;
        else
            f.prev = newNode;
        size++;
        modCount++;
    }
2.6.3.4.2 addLast
    /**
     * Appends the specified element to the end of this list.
     *
     * <p>This method is equivalent to {@link #add}.
     *
     * @param e the element to add
     */
    public void addLast(E e) {
        linkLast(e);
    }
    /**
     * Links e as last element.
     */
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }
2.6.3.5 在指定位置添加元素
    public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
    }
    private void checkPositionIndex(int index) {
        if (!isPositionIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    void linkBefore(E e, Node<E> succ) {
        // assert succ != null;
        final Node<E> pred = succ.prev;
        final Node<E> newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }
    /**
     * Returns the (non-null) Node at the specified element index.
     */
    Node<E> node(int index) {
        // assert isElementIndex(index);

        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }
2.6.3.6 获取元素
    /**
     * Returns the element at the specified position in this list.
     *
     * @param index index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
    private void checkElementIndex(int index) {
        if (!isElementIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    /**
     * Tells if the argument is the index of an existing element.
     */
    private boolean isElementIndex(int index) {
        return index >= 0 && index < size;
    }
    /**
     * Returns the (non-null) Node at the specified element index.
     */
    Node<E> node(int index) {
        // assert isElementIndex(index);

        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

2.7 Set接口

Set继承自Collection,方法与Collection保持一致。

2.7.1 特点

无序、不可重复。

常用实现类:HashSet、TreeSet等;一般使用HashSet

2.7.2 HashSet

HashSet是一个没有重复元素的集合,不保证元素的顺序。而且HashSet允许有null元素。HashSet是采用哈希算法实现,底层实际是用HashMap实现的(HashSet本质是一个简化版的HashMap),因此,查询效率和增删效率都比较高。

2.7.2.1 Hash算法原理

Hash算法也称之为散列算法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AqMAgQNp-1645693071370)(C:\Users\15154\AppData\Roaming\Typora\typora-user-images\image-20220221160250177.png)]

2.7.3 HashSet的使用
public class HashSetTest {
	public static void main(String[] args) {
		//实例化HashSet
		Set<String> set = new HashSet<>();
		//添加元素
		set.add("a");
		set.add("b");
		set.add("c");
		//获取元素,在Set容器中没有索引,所以没有get(int index)方法
		for(String str:set) {
			System.out.println(str);
		}
		//删除元素
		set.remove("a");
		//返回元素个数
		int size = set.size();	
		System.out.println(size);
	}
}
2.7.4 HashSet存储特征分析

不保证元素顺序,没有重复元素,线程不安全。允许有null元素。

无序:

在HashSet中底层是用HashMap存储元素的,HashMap底层使用的是数组与链表实现元素的存储。元素在数组中存放时,并不是有序存放的,也不是随机存放的,而是对元素的哈希值(通过散列算法得出)进行元素决定元素在数组中的位置。

不重复:

当两个元素的哈希值进行运算后得到相同的在数组中的位置时,会调用元素的equals()方法判断两个元素是否相同。如果元素相同则不会添加该元素,如果不相同则会使用单向链表保存该元素。

2.7.5 通过HashSet存储自定义对象
2.7.5.1 创建Users对象
public class Users {
	private String username;
	private int userage;
	
	public Users(String username,int userage) {
		this.username = username;
		this.userage = userage;
	}
	public Users() {
		
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + userage;
		result = prime * result + ((username == null) ? 0 : username.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;
		Users other = (Users) obj;
		if (userage != other.userage)
			return false;
		if (username == null) {
			if (other.username != null)
				return false;
		} else if (!username.equals(other.username))
			return false;
		return true;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public int getUserage() {
		return userage;
	}
	public void setUserage(int userage) {
		this.userage = userage;
	}
	@Override
	public String toString() {
		return "Users [username=" + username + ", userage=" + userage + "]";
	}
}
2.7.5.2 在HashSet中存储Users对象
public class HashSetTest {
	public static void main(String[] args) {
		//实例化HashSet
		Set<Users> set = new HashSet<>();
		Users u1 = new Users("JioH",18);
		Users u2 = new Users("JioH",18);
		set.add(u1);
		set.add(u2);
		for(Users users:set) {
			System.out.println(users);
		}
	}
}
2.7.6 TreeSet容器类

TreeSet是一个可以对元素进行排序的容器。底层实际是使用TreeMap实现的,内部维持了一个简化版的TreeMap,通过key来存储Set的元素。TreeSet内部需要对存储的元素进行排序,因此,我们需要给定排序规则

排序规则实现方式:

通过元素自身实现比较规则。

通过比较器指定比较规则。

2.7.6.1 TreeSet的使用
public class TreeSetTest {
	public static void main(String[] args) {
		//实例化
		Set<String> set = new TreeSet<>();
		//添加元素
		set.add("a");
		set.add("d");
		set.add("b");
		set.add("a");
		for(String str:set) {
			System.out.println(str);
		}
	}
}
2.7.7 通过元素自身实现比较规则
2.7.7.1 创建Users类
public class Users implements Comparable<Users>{
	private String username;
	private int userage;
	
	public Users(String username,int userage) {
		this.username = username;
		this.userage = userage;
	}
	public Users() {
		
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + userage;
		result = prime * result + ((username == null) ? 0 : username.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;
		Users other = (Users) obj;
		if (userage != other.userage)
			return false;
		if (username == null) {
			if (other.username != null)
				return false;
		} else if (!username.equals(other.username))
			return false;
		return true;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public int getUserage() {
		return userage;
	}
	public void setUserage(int userage) {
		this.userage = userage;
	}
	@Override
	public String toString() {
		return "Users [username=" + username + ", userage=" + userage + "]";
	}
	//定义比较规则
	@Override
	public int compareTo(Users o) {
		if(this.userage < o.getUserage()) {
			return 1;
		}
		if(this.userage == o.getUserage()) {
			return this.username.compareTo(o.getUsername()); //比较名字
		}
		// TODO Auto-generated method stub
		return -1;
	}
}
2.7.7.2 在TreeSet中存放Users对象
public class TreeSetTest {
	public static void main(String[] args) {
		//实例化
		Set<Users> set = new TreeSet<>();
		Users u = new Users("JioH",18);
		Users u1 = new Users("xixihaha",20);
		Users u2 = new Users("axixihaha",20);
		set.add(u);
		set.add(u1);
		set.add(u2);
		for(Users Users:set) {
			System.out.println(Users);
		}
	}
}
2.7.8 通过比较器实现比较规则

通过比较器定义比较规则时,我们需要单独创建一个比较器,比较器需要实现Comparator接口中的compare方法来定义比较规则。在实例化TreeSet时将比较器对象交给TreeSet来完成元素的排序处理。此时元素自身就不需要实现比较规则了。

2.7.8.1 创建比较器
public class StudentComparator implements Comparator<Student>{
	//定义比较规则	
	@Override
	public int compare(Student o1, Student o2) {
		// TODO Auto-generated method stub
		if(o1.getAge() > o2.getAge()) {
			return 1;
		}
		if(o1.getAge() == o2.getAge()) {
			return o1.getName().compareTo(o2.getName());
		}
		return -1;
	}
}
2.7.8.2 创建Student对象
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;
	}
	@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;
	}
	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 + "]";
	}
	
}
2.7.8.3 在TreeSet中存储Users对象
public class TreeSetTest {
	public static void main(String[] args) {
		//实例化
		Set<Student> set = new TreeSet<>(new StudentComparator());
		Student s = new Student("JIOH",18);
		Student s1 = new Student("jioh",16);
		Student s2 = new Student("JioH",22);
		set.add(s);
		set.add(s1);
		set.add(s2);
		for(Student str:set) {
			System.out.println(str);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值