Java 从入门到进阶之路(二十五)
在之前的文章我们介绍了一下 Java 中的 集合框架中的Collection 的子接口 List的 增删改查和与数组间相互转换的方法,本章我们来看一下 Java 集合框架中的Collection 的子接口 List 的另外一些方法。
我们在使用集合的时候难免会对其中的元素进行排序,因为 Set 集合本身是无序的,所以本章将着重讲解 List 集合,如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random; /**
* 排序集合元素
* 排序集合使用的是集合的工具类 Collections 的静态方法 sort
* 排序仅能对 List 集合进行,因为 Set 部分实现类是无序的
* */
public class Main {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
Random random = new Random();
for(int i=0;i<10;i++){
list.add(random.nextInt(100));
}
System.out.println(list); // [49, 24, 29, 59, 56, 1, 1, 5, 49, 60] Collections.sort(list);
System.out.println(list); // [1, 1, 5, 24, 29, 49, 49, 56, 59, 60]
}
}
在上面的代码中,我们随机生成了一些正数并添加到 List 集合中,我们通过 sort 方法,系统变自动按照自然数的排列方法为我们做好了排序,很是方便,那如果 List 中使我们自己定义的内容,比如说一个类,那该如何排序呢,如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; /**
* 排序集合元素
* 排序集合使用的是集合的工具类 Collections 的静态方法 sort
* 排序仅能对 List 集合进行,因为 Set 部分实现类是无序的
*/
public class Main {
public static void main(String[] args) {
List<Point> list = new ArrayList<Point>();
list.add(new Point(1, 2));
list.add(new Point(2, 3));
list.add(new Point(4, 2));
list.add(new Point(2, 5));
list.add(new Point(9, 3));
list.add(new Point(7, 1));
System.out.println(list); // [(1, 2), (2, 3), (4, 2), (2, 5), (9, 3), (7, 1)]
// Collections.sort(list); // 编译错误,不知道 Point 排序规则
/**
* sort 方法要求集合必须实现 Comparable 接口
* 该接口用于规定实现类事可以比较的
* 其中一个 compareTo 方法时用来定义比较大小的规则
* */
Collections.sort(list);
System.out.println(list); // [(1, 2), (2, 3), (4, 2), (2, 5), (7, 1), (9, 3)] }
} class Point implements Comparable<Point> { // 定义为泛型 T 类型
private int x;
private int y; public Point(int x, int y) {
this.x = x;
this.y = y;
} public int getX() {
return x;
} public void setX(int x) {
this.x = x;
} public int getY() {
return y;
} public void setY(int y) {
this.y = y;
} @Override
public String toString() {
return "(" + x + ", " + y + ")";
} /**
* 当实现了 Comparable 接口后,需要重写下面的方法
* 该方法的作用是定义当前对象与给定参数对象比较大小的规则
* 返回值为一个 int 值,该值表示大小关系
* 它不关注具体的取值是多少,而关注的是取值范围
* 当返回值 >0 时:当前对象不参数对象大
* 当返回值 <0 时:当前对象比参数对象小
* 当返回值 =0 时:两个对象相等
*/
@Override
public int compareTo(Point o) {
/**
* 比较规则,点到原点的距离长的打
* */
int len = this.x * this.x + this.y * this.y;
int olen = o.x * o.x + o.y * o.y;
return len - olen;
}
}
在上面的代码中,我们跟之前一样定义了一个 Point 类,然后实例化后存入 list 集合中,如果我们相对 Point 进行排序,如果直接调用 sort 方法会报错,这是由于编译器不知道我们定义的 Point 类的排序规则,所以我们需要通过接口 Comparable 接口来自定义排序规则,如下图:

我们可以通过坐标系中点到原点的距离来判断 Point 的大小,即 x*x+y*y 的大小,然后通过重写 compareTo 方法来实现 sort 。
实际上虽然能实现,但是并不理想,为了实现一个 sort 方法,要求我们的集合元素必须实现 Comparable 接口并且定义比较规则,这种我们想使用某个功能,而它要求我们修改程序的现象称为“侵入性”。修改的代码越多,侵入性越强,越不利于程序的扩展。
我们再来看一下下面的排序:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; public class Main {
public static void main(String[] args) {
List<String> list1 = new ArrayList<String>();
list1.add("Java");
list1.add("c++");
list1.add("Python");
list1.add("PHP");
Collections.sort(list1);
System.out.println(list1); // [Java, PHP, Python, c++] List<String> list2 = new ArrayList<String>();
list2.add("孙悟空");
list2.add("猪八戒");
list2.add("唐僧");
list2.add("六小龄童");
Collections.sort(list2);
System.out.println(list2); // [六小龄童, 唐僧, 孙悟空, 猪八戒] }
}
在上面的排序中,当我们对字母或汉字进行排序时,其实是比的第一个字的 Unicode 码,那如果我们不使用 Comparable 的接口该如何自定义我们想要的实现规则呢?比如根据字符串的长度来进行排序,其实 sort 有一个额外的重载方法来实现我们想要的结果,如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; public class Main {
public static void main(String[] args) {
/**
* 重载的 sort 方法要求传入一个额外的比较器
* 该方法不再要求集合元素必须实现 Comparable 接口
* 并且不再使用集合元素资深的比较规则排序了
* 而是根据给定的这个额外的比较器的比较规则对集合元素进行排序
* 实际开发中也推荐使用这种方式进行集合元素排序
* 若集合元素是自定义的
* 创建比较器时推荐使用匿名内部类的形式
*/
List<String> list1 = new ArrayList<String>();
list1.add("Java");
list1.add("c++");
list1.add("Python");
list1.add("PHP");
MyComparator myComparator1 = new MyComparator();
Collections.sort(list1, myComparator1); // 重载 sort
System.out.println(list1); // [c++, PHP, Java, Python] List<String> list2 = new ArrayList<String>();
list2.add("孙悟空");
list2.add("猪八戒");
list2.add("唐僧");
list2.add("六小龄童");
// 匿名内部类形式创建
Comparator<String> myComparator2 = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
};
Collections.sort(list2, myComparator2); // 重载 sort
System.out.println(list2); // [唐僧, 孙悟空, 猪八戒, 六小龄童] }
} /**
* 定义一个额外的比较器
* 该方法用来定义 o1 和 o2 的比较
* 若返回值 >0:o1>o2
* 若返回值 <0:o1<o2
* 若返回值 =0:两个对象相等
*/
class MyComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
/**
* 字符串中字符多的大
* */
return o1.length() - o2.length();
}
}
Java 从入门到进阶之路(二十五)的更多相关文章
- Java 从入门到进阶之路(十五)
在之前的文章我们介绍了一下 Java 中的接口,本章我们来看一下 Java 中类的多态. 在日常生活中,很多意思并不是我们想要的意思,如下: 1.领导:“你这是什么意思?” 小明:“没什么意思,意思意 ...
- Java 从入门到进阶之路(十二)
在之前的文章我们介绍了一下 Java 类的重写及与重载的区别,本章我们来看一下 Java 类的 private,static,final. 我们在之前引入 Java 类概念的时候是通过商场收银台来引入 ...
- Java 从入门到进阶之路(十八)
在之前的文章我们介绍了一下 Java 中的正则表达式,本章我们来看一下 Java 中的 Object. 在日常生活中,任何事物我们都可以看做是一个对象,在编程中是同样的道理,在 Java 编程中其实更 ...
- Java 从入门到进阶之路(十)
之前的文章我们介绍了一下 Java 中的引用型数组类型,接下来我们再来看一下 Java 中的继承. 继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继 ...
- Java 从入门到进阶之路(十四)
在之前的文章我们介绍了一下 Java 中的抽象类和抽象方法,本章我们来看一下 Java 中的接口. 在日常生活中,我们会接触到很多类似接口的问题,比如 USB 接口,我们在电脑上插鼠标,键盘,U盘的时 ...
- Java 从入门到进阶之路(十六)
在之前的文章我们介绍了一下 Java 中类的多态,本章我们来看一下 Java 中类的内部类. 在 Java 中,内部类分为成员内部类和匿名内部类. 我们先来看一下成员内部类: 1.类中套类,外面的叫外 ...
- Java 从入门到进阶之路(十九)
在之前的文章我们介绍了一下 Java 中的Object,本章我们来看一下 Java 中的包装类. 在 Java 中有八个基本类型:byte,short,int,long,float,double,ch ...
- Python 爬虫从入门到进阶之路(十五)
之前的文章我们介绍了一下 Python 的 json 模块,本章我们就介绍一下之前根据 Xpath 模块做的爬取<糗事百科>的糗事进行丰富和完善. 在 Xpath 模块的爬取糗百的案例中我 ...
- Java 从入门到进阶之路(二十)
在之前的文章我们介绍了一下 Java 中的包装类,本章我们来看一下 Java 中的日期操作. 在我们日常编程中,日期使我们非常常用的一个操作,比如读写日期,输出日志等,那接下来我们就看一下 Java ...
- Java 从入门到进阶之路(二十三)
在之前的文章我们介绍了一下 Java 中的 集合框架中的Collection 的迭代器 Iterator,本章我们来看一下 Java 集合框架中的Collection 的泛型. 在讲泛型之前我们先来 ...
随机推荐
- 什么是 JVM ?
什么是 JVM ? 解析:不仅仅是基本概念,还有 JVM 的作用. 答:JVM,即 Java Virtual Machine,Java 虚拟机.它通过模拟一个计算机来达到一个计算机所具有的的计算功能. ...
- java实现平面点最小距离
已知平面上若干个点的坐标. 需要求出在所有的组合中,4个点间平均距离的最小值(四舍五入,保留2位小数). 比如有4个点:a,b,c,d, 则平均距离是指:ab, ac, ad, bc, bd, cd ...
- java实现第六届蓝桥杯生成回文数
生成回文数 所谓回文数就是左右对称的数字,比如: 585,5885,123321- 当然,单个的数字也可以算作是对称的. 小明发现了一种生成回文数的方法: 比如,取数字19,把它与自己的翻转数相加: ...
- Linux网卡驱动移植--Dm9000网卡驱动分析
1. Linux网络体系结构由以下5部分组成 ① 系统调用接口: 位于Linux网络子系统的顶部,为应用程序提供访问内核网络子系统的方法,主要指socket系统调用. ② 协议无关接口: 实现一组基于 ...
- KVM NAT(网络地址转换模式)
NAT(网络地址转换模式) 使用NAT模式,就是让虚拟系统借助NAT(网络地址转换)功能,通过宿主机器所在的网络来访问公网.也就是说,使用NAT模式可以实现在虚拟系统里访问互联网.很显然,如果你只有一 ...
- 在WinForms里嵌入MediaPlayer的一些版本问题, tlbimp导入, 以及不导入而纯用C#+字符串来动态调用.
网上很多写使用WindowsMediaPlayer WMP控件的文章. 大多数都是从工具栏或COM导入. 最近正在做的CEF整合Asp.Net Core Blazor server side的过程中, ...
- STM32的8*8点阵屏开发(小项目)
基础认识 实现效果 项目实现STM32点阵屏的操作,自动更改显示内容和串口控制显示内容 STM32上电后: 1) 程序将进行行和列的刷新 2) 自动递增显示0-9变化 3) 进行矩形由内向 ...
- PAT1040 Longest Symmetric String (25分) 中心扩展法+动态规划
题目 Given a string, you are supposed to output the length of the longest symmetric sub-string. For ex ...
- ubuntu12.04 qtcreate支持中文输入
1.sudo apt-get install ibus-qt4 2.重启电脑 reboot
- UI 自动化遇到的坑
1,ElementNotInteractableException: Message: element not interactable 该解决方法是用xpath定位,然后使用js操作元素,点击之类 ...