day13

第一章 数据结构

1.1 常见数据结构

栈是一种具有 「先入后出」 特点的抽象数据结构,可使用数组或链表实现。

Stack<Integer> stack = new Stack<>();

如下图所示,通过常用操作「入栈 push()」,「出栈 pop()」,展示了栈的先入后出特性。

stack.push(1); // 元素 1 入栈
stack.push(2); // 元素 2 入栈
stack.pop();   // 出栈 -> 元素 2
stack.pop();   // 出栈 -> 元素 1


**注意:**通常情况下,不推荐使用 Java 的 Vector 以及其子类 Stack ,而一般将 LinkedList 作为栈来使用。详细说明请见:Stack,ArrayDeque,LinkedList 的区别

LinkedList<Integer> stack = new LinkedList<>();
stack.addLast(1);   // 元素 1 入栈
stack.addLast(2);   // 元素 2 入栈
stack.removeLast(); // 出栈 -> 元素 2
stack.removeLast(); // 出栈 -> 元素 1

队列

队列是一种具有 「先入先出」 特点的抽象数据结构,可使用链表实现。

Queue<Integer> queue = new LinkedList<>();

如下图所示,通过常用操作「入队 offer()」,「出队 poll()」,展示了队列的先入先出特性。

queue.offer(1); // 元素 1 入队
queue.offer(2); // 元素 2 入队
queue.poll();   // 出队 -> 元素 1
queue.poll();   // 出队 -> 元素 2

数组

数组是将相同类型的元素存储于连续内存空间的数据结构,其长度不可变。
数组特点:查询快,增删慢
如下图所示,构建此数组需要在初始化时给定长度,并对数组每个索引元素赋值,代码如下

// 初始化一个长度为 5 的数组 array
int[] array = new int[5];
// 元素赋值
array[0] = 2;
array[1] = 3;
array[2] = 1;
array[3] = 0;
array[4] = 2;

或者可以使用直接赋值的初始化方式,代码如下:

int[] array = {2, 3, 1, 0, 2};


「可变数组」是经常使用的数据结构,其基于数组和扩容机制实现,相比普通数组更加灵活。常用操作有:访问元素、添加元素、删除元素。

// 初始化可变数组
List<Integer> array = new ArrayList<>();// 向尾部添加元素
array.add(2);
array.add(3);
array.add(1);
array.add(0);
array.add(2);

链表

链表以节点为单位,每个元素都是一个独立对象,在内存空间的存储是非连续的。链表的节点对象具有两个成员变量:「值 val」,「后继节点引用 next」 。
链表特点:查询慢,增删快

class ListNode {int val;       // 节点值ListNode next; // 后继节点引用ListNode(int x) { val = x; }
}

如下图所示,建立此链表需要实例化每个节点,并构建各节点的引用指向。

// 实例化节点
ListNode n1 = new ListNode(4); // 节点 head
ListNode n2 = new ListNode(5);
ListNode n3 = new ListNode(1);// 构建引用指向
n1.next = n2;
n2.next = n3;

树是一种非线性数据结构,根据子节点数量可分为 「二叉树」 和 「多叉树」,最顶层的节点称为「根节点 root」。以二叉树为例,每个节点包含三个成员变量:「值 val」、「左子节点 left」、「右子节点 right」 。

class TreeNode {int val;        // 节点值TreeNode left;  // 左子节点TreeNode right; // 右子节点TreeNode(int x) { val = x; }
}

如下图所示,建立此二叉树需要实例化每个节点,并构建各节点的引用指向。

// 初始化节点
TreeNode n1 = new TreeNode(3); // 根节点 root
TreeNode n2 = new TreeNode(4);
TreeNode n3 = new TreeNode(5);
TreeNode n4 = new TreeNode(1);
TreeNode n5 = new TreeNode(2);// 构建引用指向
n1.left = n2;
n1.right = n3;
n2.left = n4;
n2.right = n5;


排序树/查找树
在二叉树的基础上,元素是有大小顺序的
左子树小,右子树大

平衡树
平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

红黑树

红黑树是一种特定类型的二叉树,它是在计算机科学中用来组织数据比如数字的块的一种结构。

红黑树是一种平衡二叉查找树的变体,它的左右子树高差有可能大于 1,所以红黑树不是严格意义上的平衡二叉树(AVL),但 对之进行平衡的代价较低, 其平均统计性能要强于 AVL 。

由于每一棵红黑树都是一颗二叉排序树,因此,在对红黑树进行查找时,可以采用运用于普通二叉排序树上的查找算法,在查找过程中不需要颜色信息。

红黑树是每个结点都带有颜色属性的二叉查找树,颜色或红色或黑色。 在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求:
性质1. 结点是红色或黑色。
性质2. 根结点是黑色。
性质3. 所有叶子都是黑色。(叶子是NIL结点)
性质4. 每个红色结点的两个子结点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色结点)
性质5. 从任一节结点其每个叶子的所有路径都包含相同数目的黑色结点。

这些约束强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果是这个树大致上是平衡的。因为操作比如插入、删除和查找某个值的最坏情况时间都要求与树的高度成比例,这个在高度上的理论上限允许红黑树在最坏情况下都是高效的,而不同于普通的二叉查找树。

是性质4导致路径上不能有两个连续的红色结点确保了这个结果。最短的可能路径都是黑色结点,最长的可能路径有交替的红色和黑色结点。因为根据性质5所有最长的路径都有相同数目的黑色结点,这就表明了没有路径能多于任何其他路径的两倍长。

因为红黑树是一种特化的二叉查找树,所以红黑树上的只读操作与普通二叉查找树相同。

第二章 List集合

java.util.List接口继承自collection接口,是单列集合的一个重要分支,习惯性地会将实现了List接口的对象称为List集合。在List集合中允许出现重复的元素,所有的元素是以一种线性方式进行存储的,在程序中可以通过索引来访问集合中的指定元素。另外,List集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;/*java. utiL.List接口extends collection接口list接口的特点:1.有序的集合存储元素和取出元素的顺序是一致的(存储123取出123)2.有索引包含了一些带索引的方法3.允许存储重复的元素List接口中带索引的方法(特有)- public void add(int index,E element):将指定的元素,添加到该集合中的指定位置上。- public E get(int index):返回集合中指定位置的元素。- public E remove(int index):移除列表中指定位置的元素,返回的是被移除的元素。- public E set(int index,E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。注意:操作索引的时候,一定要防止索引越界异常IndexOutOfBoundsException:索引越界异常ArrayIndexOutOfBoundsException:数组索引越界异常StringIndexOutOfBoundsException:字符串索引越界异常*/
public class Demo01List {public static void main(String[] args) {//创建一个List集合对象,多态List<String> list = new ArrayList<>();//使用add方法往集合中添加元素list.add("a");list.add("b");list.add("c");list.add("d");list.add("a");//打印集合System.out.println(list);//[a, b, c, d, a]//public void add(int index,E element):将指定的元素,添加到该集合中的指定位置上。//在c和d之间添加一个itheimalist.add(3, "itheima");System.out.println(list);//[a, b, c, itheima, d, a]//public E remove(int index):移除列表中指定位置的元素,返回的是被移除的元素。String remove = list.remove(2);System.out.println("被移除的元素:" + remove);//被移除的元素:cSystem.out.println(list);//[a, b, itheima, d, a]//public E set(int index,E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。//把最后一个a替换为AString setE = list.set(4, "A");System.out.println("被替换的元素:" + setE);//被替换的元素:aSystem.out.println(list);//[a, b, itheima, d, A]//List集合遍历有3种方法//使用普通的for循环for (int i = 0; i < list.size(); i++) {//public E get(int index):返回集合中指定位置的元素。String s = list.get(i);System.out.println(s);}System.out.println("======================");//使用迭代器Iterator<String> it = list.iterator();while (it.hasNext()){String s = it.next();System.out.println(s);}System.out.println("======================");//使用增强forfor (String s : list){System.out.println(s);}}
}

第三章 List的子类

3.1 ArrayList集合

java.util.ArrayList集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList是最常用的集合。
许多程序员开发时非常随意地使用ArrayList完成任何需求,并不严谨,这种用法是不提倡的。

3.2 LinkedList集合

java.util.LinkedList集合数据存储的结构是链表结构。链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
链表可分为单向链表和双向链表。
一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。

一个双向链表有三个整数值: 数值、向后的节点链接、向前的节点链接。

Java LinkedList(链表) 类似于 ArrayList,是一种常用的数据容器。
与 ArrayList 相比,LinkedList 的增加和删除的操作效率更高,而查找和修改的操作效率较低。
以下情况使用 ArrayList :

  • 频繁访问列表中的某一个元素。
  • 只需要在列表末尾进行添加和删除元素操作。
    以下情况使用 LinkedList :
  • 你需要通过循环迭代来访问列表中的某些元素。
  • 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。

特有方法实现如下:

import java.util.LinkedList;/*java.utiL.LinkedList集合implements list接口LinkedList集合的特点:1.底层是一个链表结构:查询慢,增删快2.里边包含了大量操作首尾元素的方法注意:使用LinkedList集合特有的方法,不能使用多态- public void addFirst(E e):将指定元素插入此列表的开头。- public void addLast(E e):将指定元素添加到此列表的结尾。此方法等效于与add(E).- public void push(E e):将元素推入此列表所表示的堆栈。此方法等效于addFirst(E).- public E getFirst():返回此列表的第一个元素。- public E getLast():返回此列表的最后一个元素。- public E removeFirst():移除并返回此列表的第一个元素。- public E removeLast():移除并返回此列表的最后一个元素。- public E pop():从此列表所表示的推钱处弹出一个元素。此方法相当于removeFirst- public boolean isEmpty():如果列表不包含元素,则返回true。*/
public class Demo02LinkedList {public static void main(String[] args) {show01();show02();show03();}/*public E removeFirst():移除并返回此列表的第一个元素。public E removeLast():移除并返回此列表的最后一个元素。public E pop():从此列表所表示的推钱处弹出一个元素。*/private static void show03() {//创建LinkedList集合对象LinkedList<String> linked = new LinkedList<>();//使用add方法往集合中添加元素linked.add("a");linked.add("b");linked.add("c");System.out.println(linked);//String first = linked.removeFirst();String first = linked.pop();System.out.println("被移除的第一个元素:" + first);//被移除的第一个元素:aString last = linked.removeLast();System.out.println("被移除的最后一个元素:" + last);//被移除的最后一个元素:cSystem.out.println(linked);//[b]}private static void show02() {//创建LinkedList集合对象LinkedList<String> linked = new LinkedList<>();//使用add方法往集合中添加元素linked.add("a");linked.add("b");linked.add("c");//linked.clear();//清空集合中的元素,在获取集合中的元素会抛出NoSuchElementException//public boolean isEmpty();//如果列表不包含元素,则返回true。if (linked.isEmpty()){String first = linked.getFirst();System.out.println(first);//aString last = linked.getLast();System.out.println(last);//c}}/*public void addFirst(E e):将指定元素插入此列表的开头。public void addLast(E e):将指定元素添加到此列表的结尾。public void push(E e):将元素推入此列表所表示的堆栈。*/private static void show01() {//创建LinkedList集合对象LinkedList<String> linked = new LinkedList<>();//使用add方法往集合中添加元素linked.add("a");linked.add("b");linked.add("c");System.out.println(linked);//[a, b, c]//public void addFirst(E e):将指定元素插入此列表的开头。//linked.addFirst("www");//System.out.println(linked);//[www, a, b, c]//public void push(E e):将元素推入此列表所表示的堆栈。此方法等效于addFirst(E).linked.push("www");System.out.println(linked);//[www, a, b, c]//public void addLast(E e):将指定元素添加到此列表的结尾。此方法等效于与add(E).linked.addLast("www");System.out.println(linked);//[www, a, b, c, www]}
}

第四章 Set接口

4.1 Set集合介绍

java.util.Set 接口和java.util.List接口一样,同样继承自Collegtion接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比 Collection接口更加严格了。与List 接口不同的是,Set 接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。
Set集合有多个子类,这里我们介绍其中的java.util.HashSetjava.util.LinkedHashSet这两个集合。

tips:Set集合取出元素的方式可以采用:迭代器、增强for。

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;/*java.util.Set接口 extends Collectionset接口的特点:1.不允许存储重复的元素2.没有索引没有带索引的方法,也不能使用普通的for循环遍历java.util.HashSet集合 implements set接口HashSet特点:1.不允许存储重复的元素2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历3.是一个无序的集合,存储元素和取出元素的顺序有可能不一致4.底层是一个哈希表结构(查询的速度非常的快)*/
public class Demo01Set {public static void main(String[] args) {Set<Integer> set = new HashSet<>();//使用add方法往集合中添加元素set.add(1);set.add(3);set.add(2);set.add(1);//使用迭代器遍历set集合Iterator<Integer> it = set.iterator();while (it.hasNext()){Integer n = it.next();System.out.println(n);//1 2 3}System.out.println("==================");//使用增强for遍历set集合for(Integer n : set){System.out.println(n);//1 2 3}System.out.println("==================");System.out.println(set);//[1, 2, 3]}
}

4.2 HashSet集合存储数据的结构(哈希表)

hashCode()方法

/*哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到地址,不是数据实际存储的物理地址)在Object类有一个方法,可以获取对象的哈希值int hashCode返回该对象的哈希码值。hashCode()方法的源码:public native int hashCode();native:代表该方法调用的是本地操作系统的方法*/
public class Demo01HashCode {public static void main(String[] args){Person p1 = new Person();int h1 = p1.hashCode();System.out.println(h1);//1355531311Person p2 = new Person();int h2 = p2.hashCode();System.out.println(h2);//1967205423/*toString()方法的源码:public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}*/System.out.println(p1);//com.itheima.demo03.hashCode.Person@50cbc42fSystem.out.println(p2);//com.itheima.demo03.hashCode.Person@75412c2f/*String类的哈希值String类重写Object类的hashCode方法*/String s1 = new String("abc");String s2 = new String("abc");System.out.println(s1.hashCode());//96354System.out.println(s2.hashCode());//96354System.out.println("重地".hashCode());//1179395System.out.println("通话".hashCode());//1179395这两个是巧合}
}

HashSet集合存储数据的结构(哈希表)

4.3 Set集合存储元素不重复的原理

4.4 HashSet存储自定义类型元素

给HashSet中存放自定义类型元素时,需要重写对象中的hashCode和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一

import java.util.Objects;public class Person {private String name;private int age;public Person() {}public Person(String name, int age) {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;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age &&Objects.equals(name, person.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}
import java.util.HashSet;/*HashSet存储自定义类型元素set集合报错元素唯一:存储的元素(String,Integer, . . .student , Person.. .) ,必须重写hashcode方法和equals方法要求:同名同年龄的人,视为同一个人,只能存储一次*/
public class Demo03HashSetSavePerson {public static void main(String[] args) {//创建HashSet集合存储PersonHashSet<Person> set = new HashSet<>();Person p1 = new Person("小美女", 18);Person p2 = new Person("小美女", 18);Person p3 = new Person("小美女", 19);System.out.println(p1.hashCode());//重写hashCode()方法前 1355531311 | 重写hashCode()方法后 734175839System.out.println(p2.hashCode());//重写hashCode()方法前 1967205423 | 重写hashCode()方法后System.out.println(p1==p2);//falseSystem.out.println(p2.equals(p2));//重写equals()方法前 false | 重写equals()方法后 trueset.add(p1);set.add(p2);set.add(p3);System.out.println(set);}
}

4.5 LinkedHashSet集合

import java.util.HashSet;
import java.util.LinkedHashSet;/*java.util.LinkedHashSet集合 extends HashSet集合LinkedHashSet集合特点:底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序),保证元素有序*/
public class Demo04LinkedHashSet {public static void main(String[] args) {HashSet<String> set = new HashSet<>();set.add("www");set.add("abc");set.add("abc");set.add("itcast");System.out.println(set);//[abc, www, itcast] 无序的,不允许重复LinkedHashSet<String> linked = new LinkedHashSet<>();linked.add("www");linked.add("abc");linked.add("abc");linked.add("itcast");System.out.println(linked);//[www, abc, itcast] 有序的,不允许重复}
}

4.6 可变参数

JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化成如下格式:

修饰符 返回值类型 方法名(参数类型... 形参名){ }

其实这个书写完全等价与

修饰符 返回值类型 方法名(参数类型[] 形参名){ }

只是后面这种定义,在调用时必须传递数组,而前者可以直接传递数据即可。
JDK1.5以后。出现了简化操作。…用在参数上,称之为可变参数。
同样是代表数组,但是在调用这个带有可变参数的方法时,不用创建数组(这就是简单之处),直接将数组中的元素作为实际参数进行传递,其实编译成的class文件,将这些元素先封装到一个数组中,在进行传递。这些动作都在编译.class文件时,自动完成了。

/*可变参数:是JDK1.5之后出现的新特性使用前提:当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数.使用格式:定义方法时使用修饰符 返回值类型 方法名(数据类型...变量名){}可变参数的原理:可变参数底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数传递的参数个数,可以是0个(不传递),1,2...多个*/
public class Demo01VarArgs {public static void main(String[] args) {//int i = add();//int i = add(10);//int i = add(10, 20);int i = add(10, 20, 30, 40, 50, 60, 70, 80, 90, 100);System.out.println(i);}/*可变参数的注意事项1.一个方法的参数列表,只能有一个可变参数2.如果方法的参数有多个,那么可变参数必须写在参数列表的末尾*///可变参数的特殊(终极)写法public static void method(Object ...obj){}/*定义计算(0-n)整数和的方法已知:计算整数的和,数据类型已经确定int但是参数的个数不确定,不知道要计算几个整数的和,就可以使用可变参数add();就会创建一个长度为0的数组,new int[0]add(10);就会创建一个长度为1的数组,存储传递过来的参数 new int[]{10}add(10, 20);就会创建一个长度为2的数组,存储传递过来的参数 new int[]{10, 20}add(10, 20, 30, 40, 50, 60, 70, 80, 90, 100);就会创建一个长度为10的数组,存储传递过来的参数 new int[]{10, 20, 30, 40, 50, 60, 70, 80, 90, 100};*/public static int add(int...arr){//System.out.println(arr);//[I@1c53fd30 底层是一个数组//System.out.println(arr.length);//0, 1, 2 ,10int sum = 0;for (int i : arr) {sum += i;}return sum;}//定义一个方法,计算三个个int类型整数的和/*public static int add(int a, int b, int c){return a + b + c;}*///定义一个方法,计算两个int类型整数的和/*public static int add(int a, int b){return a + b;}*/
}

第五章 Collections

java.util.Collections是集合工具类,用来对集合进行操作。部分方法如下︰
public static <T> boolean addAl)(Collection<T> c, T... elements):往集合中添加一些元素。
public static void shuffle(List<?> list):打乱顺序:打乱集合顺序。
public static <T> void sort(List<T> list):将集合中元素按照默认规则排序。
public static <T> void sort(List<T> list , comparator<? super T>) :将集合中元素按照指定规则排序。

import java.util.ArrayList;
import java.util.Collections;/*- java.util.collections是集合工具类,用来对集合进行操作。部分方法如下:- public static <T> boolean addAll(collection<T>c, T... elements):往集合中添加一些元素。- public static void shuffle(List<?> list)打乱顺序:打乱集合顺序。*/
public class Demo01Collections {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();//public static <T> boolean addAll(collection<T>c, T... elements):往集合中添加一些元素。Collections.addAll(list, "a", "b", "c", "d", "e");System.out.println(list);//[a, b, c, d, e]//public static void shuffle(List<?> list)打乱顺序:打乱集合顺序。Collections.shuffle(list);System.out.println(list);//[b, c, a, d, e]}
}
public class Person implements Comparable<Person>{private String name;private int age;public Person() {}public Person(String name, int age) {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;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}//重写排序的规则@Overridepublic int compareTo(Person o) {// return 0; //认为元素都是相同的//自定义比较的规则,比较两个人的年龄(this,参数Person)//return this.getAge() - o.getAge();//年龄升序排序return o.getAge() - this.getAge();//年龄降序排序}
}
import java.util.ArrayList;
import java.util.Collections;/*- java.util.collections是集合工具类,用来对集合进行操作。部分方法如下:- public static <T> void sort(list<T> list) :将集合中元素按照默认规则排序。注意:sort(List<T> list)使用前提被排序的集合里边存储的元素,必须实现Comparable,重写接口中的方法compareTo()Comparable接口的排序规则:自己(this) - 参数:就是升序参数 - 自己(this):就是降序*/
public class Demo02Sort {public static void main(String[] args) {ArrayList<Integer> list01 = new ArrayList<>();list01.add(1);list01.add(3);list01.add(2);System.out.println(list01);//[1, 3, 2]//public static <T> void sort(list<T> list) :将集合中元素按照默认规则排序。Collections.sort(list01);//默认是升序的System.out.println(list01);//[1, 2, 3]/*public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequenceString重写了Comparable接口compareTo方法,比较器*/ArrayList<String> list02 = new ArrayList<>();list02.add("a");list02.add("c");list02.add("b");System.out.println(list02);//[a, c, b]Collections.sort(list02);//默认是升序的System.out.println(list02);//[a, b, c]ArrayList<Person> list03 = new ArrayList<>();list03.add(new Person("张三", 18));list03.add(new Person("李四", 20));list03.add(new Person("王五", 19));System.out.println(list03);Collections.sort(list03);System.out.println(list03);}
}
public class Student {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}public Student() {}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;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;/*- java.utils.collections是集合工具类,用来对集合进行操作。部分方法如下:- public static <T> void sort(List<T> list,comparator<? super T〉):将集合中元素按照指定规则排序。Comparator和Comparable的区别Comparable:自己(this )和别人(参数)比较,自己需要实现Comparable接口,重写比较的规则compareTo方法Comparator:相当于找一个第三方的裁判,比较两个Comparator的排序规则:o1 - o2:升序o2 - o1:降序*/
public class Demo03Sort {public static void main(String[] args) {ArrayList<Integer> list01 = new ArrayList<>();list01.add(1);list01.add(3);list01.add(2);System.out.println(list01);//[1, 3, 2]Collections.sort(list01, new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {//return o1 - o2;//升序return o2 - o1;//降序}});System.out.println(list01);ArrayList<Student> list02 = new ArrayList<>();list02.add(new Student("张三", 18));list02.add(new Student("李四", 20));list02.add(new Student("王五", 19));list02.add(new Student("张三", 19));System.out.println(list02);Collections.sort(list02, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {//按升序int result = o1.getAge() - o2.getAge();//如果两个人年龄相同,再使用姓名的第一个字比较if (result == 0){result = o1.getName().charAt(0) - o2.getName().charAt(0);}return result;}});System.out.println(list02);}
}

Java小农养成记第十三天相关推荐

  1. Java小农养成记第二十三天

    day23 第一章 Stream流 说到Stream便容易想到I/O Stream,而实际上,谁规定"流"就一定是"I0流"呢?在Java8中,得益于Lambd ...

  2. Java小农养成记第八天

    Day08 第十二章 继承 12.1概述 面向对象的三大特征:封装性.继承性.多态性. 继承是多态的前提,如果没有继承,就没有多态. 继承主要解决的问题就是:共性抽取. 父类也可以叫基类,超类 子类也 ...

  3. Java小农养成记第一天

    Day01 第一章 开发前言 1.1 java语言概述 Java语言是美国Sun公司(Stanford University Network),在1995年推出的高级编程语言.在2009年Oracle ...

  4. Java小农养成记第五天

    Day05 第九章 面向对象 9.1 概念 面向过程:当需要实现一个功能的时候,每一个具体的步骤都要亲力亲为,详细处理每一个细节. 面向对象:当需要实现一个功能的时候,不关心具体的步骤,而是找一个已经 ...

  5. Java小农养成记第十天

    Day10 第十六章 final关键字 /*finaL关键字代表最终.不可改变的. 常见四种用法: 1. 可以用来修饰一个类 2. 可以用来修饰一个方法 3.还可以用来修饰一个局部变量 4. 还可以用 ...

  6. Java小农养成记第九天

    Day09 第十四章 接口 14.1 概述 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来 ...

  7. Java小农养成记第六天

    Day06 第十章 API 10.1 概述 API(Application Programming Interface),应用程序编程接口.JavaAPI是一本程序员的字典,是JDK中提供给我们使用的 ...

  8. Java小农养成记第四天

    Day04 第八章 数组 8.1 数组定义 /* * 数组:是一种容器,可以同时存放多个数据值 * * 数组的特点: * 1.数组是一种引用数据类型 * 2.数组当中的多个数据,类型必须统一 * 3. ...

  9. Java小农养成记第二天

    Day02 第五章 Java流程控制语句 5.1 概述 在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的.也就是说,程序的流程对运行结果有直接的影响.所以,我们必须清楚每条语句的执 ...

最新文章

  1. 消息称苹果正在组建新智能家居团队
  2. java jdkxp32_java运行环境(jre-8u65-windows-i586) 官方安装版 32位
  3. boost::log模块实现宽字符日志记录示例
  4. WPF:使用Json.NET在TreeView中树形显示JSON数据
  5. 浅谈Windows下SVN在Android Studio中的配置、基本使用及解除关联
  6. C++类分号(;)问题
  7. 用python做舆情分析系统_如何用Python做舆情时间序列可视化?
  8. arcpy.SpatialJoin_analysis 空间连接分析
  9. Atiti  attilax主要成果与解决方案与案例rsm版 v4
  10. VMware虚拟机中Linux系统如何修改IP地址
  11. 数据结构初阶——二叉树
  12. 微软hci推荐服务器,Azure Stack HCI 的系统需求
  13. 大神如何用油猴提升前端开发效率 ?
  14. 这里有美女!!!!抖音上很火的3D立体动态相册的实现(纯CSS)
  15. 自定义角色外观之捏脸
  16. MySQL数据库11——子查询语句
  17. 毕设分享SSM 网上购物商城系统(含源码+论文)
  18. [Android Pro] 将你的安卓手机屏幕共享到PC或Mac上
  19. postgresql时间差计算
  20. 全新UI简洁H5商城网站源码

热门文章

  1. 怎么把照片变成漫画?照片生成漫画的办法介绍
  2. 为什么使用React作为云平台的前端框架(PPT)
  3. 软考 | 2009年下半年 软件设计师 下午试卷
  4. go get 更改密码 权限错误 git ls-remote -q origin in terminal prompts disabled
  5. C语言编写一个简单的选择题答题系统
  6. 在线阅读文库系统开发支持手机在线观看下载文档(一)
  7. 在新板子上点亮第一盏灯
  8. 教你批量消除视频原声,一学就会
  9. react生命周期学习
  10. 高等学校学生违纪条例