Arrays类
是java.util工具包中的一个类,主要用于对数组进行操作。public static int binarySearch(数据类型[] a, 数据类型 key)
import java.util.Arrays;
public class Demo {
public static void main(String[] args) throws Exception {
int data[] = new int[]{
1, 9, 5, 7, 2, 3, 4, 6, 10, 8};
// 未进行排序,二分查找可能失败,结果为负数
System.out.println(Arrays.binarySearch(data, 9)); // -9
java.util.Arrays.sort(data);
// 数组排序后,二分查找成功
System.out.println(Arrays.binarySearch(data, 9));
}
}
equals()
,该方法与Object类中的equals()没有任何关系:public static boolean equals(数据类型[] a, 数据类型[] a2)
import java.util.Arrays;
public class Demo {
public static void main(String[] args) throws Exception {
int dataA[] = new int[]{
1, 2, 3};
int dataB[] = new int[]{
2, 1, 3};
int dataC[] = new int[]{
1, 2, 3};
System.out.println(Arrays.equals(dataA, dataB)); // false
System.out.println(Arrays.equals(dataA, dataC)); // true
}
}
如果要使得数据判断为相同,数组中的元素顺序必须一致,因为该方法是按照顺序一个个比较元素的。
4. 在Arrays类中提供
·填充数组的方法:public static void fill(数据类型[] a, 数据类型 val);
·将数组变为字符串输出:public static String toString(数据类型[] a);
import java.util.Arrays;
public class Demo {
public static void main(String[] args) throws Exception {
int data[] = new int[10];
Arrays.fill(data, 3); // 填充数组
System.out.println(Arrays.toString(data)); // 将数组变为字符串输出
}
}
public static void sort(Object[] a);
import java.util.Arrays;
class Book {
private String title;
private double price;
public Book(String title, double price) {
this.title = title;
this.price = price;
}
@Override
public String toString() {
return "书名:" + this.title + ",价格:" + this.price;
}
}
public class Demo {
public static void main(String[] args) throws Exception {
Book books[] = new Book[]{
new Book("Java开发", 66.6),
new Book("JSP", 36.6),
new Book("C++", 86.6),
new Book("C", 16.6)
};
Arrays.sort(books); // 对象数组排序
System.out.println(Arrays.toString(books));
}
}
上述代码没有任何语法错误,但是执行后发生了异常
Exception in thread “main” java.lang.ClassCastException: com.java.demo.Book cannot be cast to java.lang.Comparable
at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:320)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:188)
at java.util.Arrays.sort(Arrays.java:1246)
at com.java.demo.Demo.main(Demo.java:28)
造成这种异常的原因是两个没有关系的类对象发生了强制转换。
2. 每一个对象只保留有地址信息,地址中是有内容的,所以int型数组比较,只要判断大小;而对象数组,里面包含的只是编码(地址)比较是没意义的,像上述代码,按照价格排序才是有意义的,所以此处必须明确地设置出比较的规则。
比较的规则就是由Comparable接口定义的,此接口定义如下:
public interface Comparable
实际上String类是Comparable接口的子类,之前使用的compareTo()方法就是比较的操作功能,如果现在要进行对象比较,建议compareTo()返回三类数据:1(大于)
、0(等于)
、-1(小于)
。
范例:使用比较器
import java.util.Arrays;
class Book implements Comparable<Book> {
// 实现比较
private String title;
private double price;
public Book(String title, double price) {
this.title = title;
this.price = price;
}
@Override
public String toString() {
return "书名:" + this.title + ",价格:" + this.price + "\n";
}
@Override
public int compareTo(Book o) {
// Arrays.sort()会自动调用此方法
if (this.price > o.price) {
return 1;
} else if (this.price < o.price) {
return -1;
} else {
return 0;
}
}
}
public class Demo {
public static void main(String[] args) throws Exception {
Book books[] = new Book[]{
new Book("Java开发", 66.6),
new Book("JSP", 36.6),
new Book("C++", 86.6),
new Book("C", 16.6)
};
Arrays.sort(books); // 对象数组排序
System.out.println(Arrays.toString(books));
}
}
总结:
只要是一组对象要进行排序,对象所在的类一定要实现Comparable接口。
class Book implements Comparable<Book> {
// 实现比较
private String title;
private double price;
public Book(String title, double price) {
this.title = title;
this.price = price;
}
@Override
public String toString() {
return "书名:" + this.title + ",价格:" + this.price + "\n";
}
@Override
public int compareTo(Book o) {
// Arrays.sort()会自动调用此方法
if (this.price > o.price) {
return 1;
} else if (this.price < o.price) {
return -1;
} else {
return 0;
}
}
}
· 定义二叉树,所有数据结构都需要Node类的支持
import java.util.Arrays;
class Book implements Comparable<Book> {
// 实现比较
private String title;
private double price;
public Book(String title, double price) {
this.title = title;
this.price = price;
}
@Override
public String toString() {
return "书名:" + this.title + ",价格:" + this.price + "\n";
}
@Override
public int compareTo(Book o) {
// Arrays.sort()会自动调用此方法
if (this.price > o.price) {
return 1;
} else if (this.price < o.price) {
return -1;
} else {
return 0;
}
}
}
class BinaryTree {
private class Node {
private Comparable data; // 排序的依据就是Comparable
private Node left; // 左节点
private Node right; // 右节点
@SuppressWarnings("unused")
public Node(Comparable data) {
this.data = data;
}
public void addNode(Node newNode) {
if (this.data.compareTo(newNode.data) < 0) {
if (this.left == null) {
this.left = newNode;
} else {
this.left.addNode(newNode);
}
} else {
if (this.right == null) {
this.right = newNode;
} else {
this.right.addNode(newNode);
}
}
}
public void toArrayNode() {
if (this.left != null) {
this.left.toArrayNode(); // 左子树输出
}
BinaryTree.this.retData[BinaryTree.this.foot++] = this.data;
if (this.right != null) {
this.right.toArrayNode(); // 右子树输出
}
}
}
// ==========================内部类===============================
private Node root; // 根节点
private int count; // 元素个数
private Object[] retData;
private int foot;
public void add(Object obj) {
// 数据添加
Comparable com = (Comparable) obj; // 必须变为Comparable才能实现Node保存
Node newNode = new Node(com); // 创建新节点
if (this.root == null) {
// 根节点不存在
this.root = newNode; // 保存为根节点
} else {
this.root.addNode(newNode);
}
this.count++;
}
public Object[] toArray() {
if (this.root == null) {
return null;
}
this.foot = 0;
this.retData = new Object[this.count];
this.root.toArrayNode();
return this.retData;
}
}
public class Demo {
public static void main(String[] args) throws Exception {
BinaryTree bt = new BinaryTree();
bt.add(new Book("Java开发", 66.6));
bt.add(new Book("JSP", 36.6));
bt.add(new Book("C++", 86.6));
bt.add(new Book("C", 16.6));
Object obj[] = bt.toArray();
System.out.println(Arrays.toString(obj));
}
}
class Book {
private String title;
private double price;
public Book() {
}
public Book(String title, double price) {
this.title = title;
this.price = price;
}
@Override
public String toString() {
return "书名:" + this.title + ",价格:" + this.price + "\n";
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
假设上述在初期设计时,有对象数组,但是没有设置对象数组排序的方法。之后要实现对象数组的排序,这时在不能修改Book类定义的情况下是不能实现Comparable接口的。因此Java为解决该问题,提供了另外一个比较器:java.util.Comparator,原先在Comparator下定义了两个方法:
@FunctionalInterface
public interface Comparator<T> {
public int compare(T o1, T o2);
public boolean equals(Object obj);
}
上述代码中,实际真正要实现只有compare()方法,需要定义一个类实现Comparator接口,这个类将作为指定类的排序类。
范例:定义排序的工具类
class BookComparator implements Comparator<Book> {
@Override
public int compare(Book o1, Book o2) {
if (o1.getPrice() > o2.getPrice()) {
return 1;
} else if (o1.getPrice() < o2.getPrice()) {
return -1;
} else {
return 0;
}
}
}
Comparable接口的使用依靠Arrays类的sort()方法,而Comparator接口可以利用另一个被重载的sort()方法:public static
。
范例:进行排序
public class Demo {
public static void main(String[] args) throws Exception {
Book books[] = new Book[]{
new Book("Java开发", 66.6),
new Book("JSP", 36.6),
new Book("C++", 86.6),
new Book("C", 16.6)
};
Arrays.sort(books, new BookComparator());
System.out.println(Arrays.toString(books));
}
}
由该过程可得,使用Comparator比较麻烦,因为要定义一个专门的排序类,并且调用排序时也要明确地指明一个排序规则类。
题目:请解释Comparator和Comparable的区别?(请解释两种比较器的区别)
答案:
· 如果对象数组要进行排序那么必须设置排序规则,可以使用Comparator和Comparable接口实现;
· java.lang.Comparable是在一个类定义时实现的接口,这样该类数组就可以进行排序,在该接口下定义了一个public int compareTo()方法;
· java.util.Comparator是专门定义一个指定类的比较规则,用于进行挽救的比较操作,该接口下定义有两个方法public int compare()、public boolean equals()