1.1 数组操作类Arrays
Arrays 类一早就开始使用了,最早使用的是它的排序操作,但是现在打开Arrays类来观察下一下,有那些方法
(1)二分查找:public static int binarySearch(数据类型 a, 数据类型 key)
在进行此调用之前,数组必须按照sort(数据类型[])方法进行排序。如果没有排序,结果是未定义的。如果数组包含具有指定值的多个元素,则不能保证将找到哪个元素。
范例:二分查找
package day2;
import java.util.Arrays;
public class TestDemo {
public static void main(String[] args) throws Exception {
int date[] = {5,69,85,35,45,67,54,62,89,50,7,12,28};
Arrays.sort(date);
System.out.println(Arrays.binarySearch(date,67));//9
}
}
(2)数组比较:public static boolean equals(数据类型[] a,数据类型[] a2)
如果两个数组以相同的顺序包含相同的元素,则它们是相等的。另外,如果两个数组引用都是null,则它们被认为是相等的 。
范例:数组比较
package day2;
import java.util.Arrays;
public class TestDemo {
public static void main(String[] args) throws Exception {
int dateA[] = new int[]{1,2,3};
int dateB[] = new int[]{2,1,3};
int dateC[] = new int[]{1,2,3};
System.out.println(Arrays.equals(dateA,dateB));//false
System.out.println(Arrays.equals(dateA,dateC));//true
}
}
(3)数组填充:public static void fill(数据类型[] a,数据类型 val),将指定的 数据类型值分配给指定的数据类型 数组的每个元素。
(4)public static String toString(数据类型[] a)
返回指定数组的内容的字符串表示形式。 字符串表示由数组元素的列表组成,括在方括号( “[]” )中。 相邻的元素由字符", "分隔(逗号后跟一个空格)。 元素被转换为字符串由String.valueOf(int)。 返回"null"如果a是null。
范例:数组填充
package day2;
import java.util.Arrays;
public class TestDemo {
public static void main(String[] args) throws Exception {
int dateA[] = new int[]{1,2,3};
Arrays.fill(dateA,5);
System.out.println(Arrays.toString(dateA));
}
}
[5, 5, 5]
在Arrays类中几乎包含了所有可能使用到的数组的相关操作。
1.2 比较器 Comparable接口
在Arrays类中提供有一个方法:public static void sort(byte[] a),此方法可以直接针对于队形数组进行排序的操作;但是如果现在真的要进行对象数组的排序,并不是意味着直接调用此方法即可。如果要想进行对象数组的排序,需要解决数据的大小关系问题,但是对象无法区分大小关系,那么为了解决这样的一个问题,java会自动在排序的时候将所有的对象强制转换为Comparable接口对象,也就是数组的自动排序,那么对象所在的类一定要实现Comparable接口,这个接口定义如下:
public interface Comparable{ public int compareTo(T o); }
String 类中的compareTo()本身就是覆写了Comparable接口中的compareTo方法。而如果说下周需要进行排序,实际上只需要返回三个内容即可:0,-1,1
范例:对象数组排序
package day2; import java.util.Arrays; class Person implements Comparable{ private String name; private int age; public Person(String name,int age){ this.name = name; this.age = age; } @Override public String toString() { return "姓名 :" + this.name + ",年龄:" + this.age + "n"; } @Override public int compareTo(Person p) { if(this.age > p.age){//1升序,-1 降序 return 1; }else if(this.age < p.age){ return -1; }else { return 0; } } } public class TestDemo { public static void main(String[] args) throws Exception { Person person [] = new Person[]{ new Person("张角",26), new Person("王怡",18), new Person("黎明",22) }; Arrays.sort(person); System.out.println(Arrays.toString(person)); } } [姓名 :王怡,年龄:18 , 姓名 :黎明,年龄:22 , 姓名 :张角,年龄:26 ]
结论:只要是进行对象数组的排序,一定要使用Comparable接口完成。
1.3 实现二叉树算法(Binary Tree)
二叉树也好,链表也好,本质是一样的,目的就是为了保存多个数据,实现动态的对象数组。所有的数据结构都一定有一个前提:必须通过节点来进行数据的包裹,目的:确定先后顺序。那么现在也对Node进行修改,让其进行可以保存对象(Object,Comparable),但是现在每一个节点上要保留有两个子节点:左子树、右子树
保存原则:比根节点小的数据放在左子树,比根节点大于等于的数据保存在左子树。
最后按照中序遍历(左-根-右)的方式可以取得内容,所有数据的排序后的结果。
范例:实现二叉树
package day2; import java.util.Arrays; class Person implements Comparable{ private String name; private int age; public Person(String name,int age){ this.name = name; this.age = age; } @Override public String toString() { return "姓名 :" + this.name + ",年龄:" + this.age + "n"; } @Override public int compareTo(Person p) { return this.age - p.age; } } class MyBinaryTree{//二叉树的实现类 private class Node{//数据结构中必须有Node类,负责保存数据及节点的关系匹配 @SuppressWarnings("rawtypes") private Comparable data; private Node left;//左子树,保存比根节点小的内容 private Node right;//右子树,保存比根节点大或等于的内容 @SuppressWarnings({"rawtypes","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(); } MyBinaryTree.this.retData[MyBinaryTree.this.foot++] = this.data; if(this.right != null){//有右节点 this.right.toArrayNode(); } } } private Node root;//必须保留着根节点 private int count = 0 ;//保存节点个数 private Object[] retData; private int foot = 0; public void add(Object obj){//数据的追加 Comparable data = (Comparable)obj; Node newNode = new Node(data);//将数据包装在Node节点中 if(this.root == null){//保存根节点 this.root = newNode; }else { this.root.addNode(newNode); } this.count++; } public Object[] toArray(){ if(this.count > 0){ this.foot = 0; this.retData = new Object[this.count]; this.root.toArrayNode(); return this.retData; }else { return null; } } } public class TestDemo { public static void main(String[] args) throws Exception { MyBinaryTree mbt = new MyBinaryTree(); mbt.add( new Person("张角",26)); mbt.add( new Person("王怡",18)); mbt.add( new Person("黎明",22)); mbt.add( new Person("李思",15)); System.out.println(Arrays.toString(mbt.toArray())); } } [ 姓名 :李思,年龄:15 , 姓名 :王怡,年龄:18 , 姓名 :黎明,年龄:22 , 姓名 :张角,年龄:26 ]
1.4 Comparator 比较器
通过Comparable的观察可以发现,如果一个类的对象想要进行对象数组排序,那么这个类在定义的时候就必须明确的实现Comparable接口,如果出现一个类原本定义完成了,原本是没有排序要求的,可是后期需要追加排序,并且这个类已经不能够修改了。那么在这种情况下,就可以利用java.util.Comparator接口,此接口定义如下:
@FunctionalInterface public interface Comparator{ public int compare(T o1, T o2); public boolean equals(Object obj); }
如果要想继续使用Arrays实现排序操作,那么就必须观察新的排序方法:
排序:public static void sort(T[] a,int fromIndex,int toIndex, Comparator super T> c)
范例:定义一个单独的Person类(不允许Person类发生改变)
class Person{
private String name;
private int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "姓名 :" + this.name + ",年龄:" + this.age + "n";
}
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;
}
}
范例:实现单独的比较器
package day2; import java.util.Arrays; import java.util.Comparator; class PersonComparator implements Comparator{ @Override public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } } public class TestDemo { public static void main(String[] args) throws Exception { Person person [] = new Person[]{ new Person("张角",26), new Person("王怡",18), new Person("黎明",22) }; Arrays.sort(person,new PersonComparator());//编写排序 System.out.println(Arrays.toString(person)); } } [姓名 :王怡,年龄:18 , 姓名 :黎明,年龄:22 , 姓名 :张角,年龄:26 ]
面试题:请解释两种比较器的区别
(1)在进行对象数组排序的过程中需要使用到比较器,比较器有两个:Comparable、Comparator
(2)java.lang.Comparable:是在类定义的的时候默认实现好的接口,里面提供有一个compateTo()方法用于大小比较;
(3)java.util.Comparator需要单独定义一个排序的比较规则类,里面有两个方法:compare()、equals()。



