需要为多个对象排序时必须设置排序规则,而排序规则就可以通过比较器进行设置,在Java中,提供了两种比较器,分别是Comparable(定义类时实现)接口和Comparator(主要用于在已有未实现比较类的基础上实现比较功能也就是定义类时没有实现Comparable接口)接口,接下来展开介绍:
对多个对象进行比较排序的类,就需要实现该接口;该接口定义如下
public interface Comparable<T> {
public int compareTo(T o);
}
从源码我们可以看出,如果相对一个对象进行排序,只需要实现这个接口即可,并且重写接口的 public int compareTo(T o)方法;并且,此方法的返回值,只能是如下情况之一:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Demo {
public static void main(String[] args) {
List<Book> list = new ArrayList<>();
list.add(new Book("java开发", 100));
list.add(new Book("C++开发", 90));
list.add(new Book("Android开发", 60));
list.add(new Book("C#开发", 80));
Object[] obj = list.toArray();
// 进行排序输出
Arrays.sort(obj);
System.out.println(Arrays.toString(obj));
}
}
class Book implements Comparable<Book>{
private String name;
private int price;
public Book(String name, int price) {
this.name = name;
this.price = price;
}
// 根据书本的价钱进行排序
@Override
public int compareTo(Book o) {
if(this.price == o.price)
return 0;
else
return this.price > o.price ? 1 : -1;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
输出结果如下:
当然,如果要实现逆序排序,只需要在compareTo方法上调换返回值1和-1即可。
接下来,考虑一种情况,如果我们在写Book类的时候,没有实现比较器接口,那么在后续中,我们就无法使用Arrays.sort()方法进行排序,那该怎么办呢?
这时候就需要用到我们的Comparator接口;
Comparator接口里面有一个int compare(T o1, T o2);方法,我们只需要实现该方法即可;该方法的返回值也是同上原理。
public interface Comparator<T> {
int compare(T o1, T o2);
}
废话不多说,直接上代码:
import java.util.Arrays;
import java.util.Comparator;
public class Demo {
public static void main(String[] args) {
Book [] books = new Book[]{
new Book("java开发", 100),
new Book("C#开发", 80),
new Book("C++开发", 90),
new Book("Android开发", 60)
};
// 进行排序输出
Arrays.sort(books,new BookComparator());
System.out.println(Arrays.toString(books));
}
}
class Book {
private String name;
private int price;
public Book(String name, int price) {
this.name = name;
this.price = price;
}
public int getPrice() {
return price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
// 书籍比较器定义
class BookComparator implements Comparator<Book>{
// 根据价钱比较
@Override
public int compare(Book o1, Book o2) {
if(o1.getPrice() == o2.getPrice())
return 0;
else
return o1.getPrice() > o2.getPrice() ? 1 : -1;
}
}
注意:Arrays.sort()的一个重载方法;? super T表示T以及T的父类
public static <T> void sort(T[] a, Comparator<? super T> c)
现在,比较器的基本使用应该时比较清楚了!!!
Java中,为了遍历类集中的元素,降低访问代码和集合本身的耦合性,提高代码的复用性,提出了迭代器Iterator的概念。泛型机制+迭代器,成功解决了算法与容器的分离问题,使得Java语言的开发变得更加灵活可用。
那么迭代器到底是什么呢?
迭代器是一种抽象的设计概念,它提供了一种允许访问某个容器所含的各个元素的方法,而无需暴露该容器内部结构,也是一种设计模式,在Java中它的任务就是遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构,使用迭代器就可以遍历这个对象的内部,通常呗成为“轻量级”对象,因为创建它的代价很小。
在将迭代器开始之前,我们先说下Iterator和Iterable
Iterator为Java中的迭代器对象,是能够对List这样的集合进行迭代遍历的底层依赖。Iterable接口实现后的功能是‘返回’一个迭代器,我们常用的实现了该接口的子接口有:Collection、List、Set等。该接口的iterator()方法返回一个标准的Iterator实现。实现Iterable接口允许对象成为Foreach语句的目标。就可以通过foreach语句来遍历你的底层序列。
废话不多说,直接上源码比较
public interface Iterator<E> {
// 判断是否有下一个元素
boolean hasNext();
// 取得下一个元素,没有则抛出异常
E next();
// 删除当前元素,删除时当前必须要有获取的元素,否则删除异常,即next()后调用删除
default void remove() {
throw new UnsupportedOperationException("remove");
}
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
//----------------------------------------------------------------------------------------------------------------------------
public interface Iterable<T> {
// 取得迭代器
Iterator<T> iterator();
// forEach循环
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
使用迭代器遍历集合案例举例
List<Integer> list = new ArrayList<>();
list.add(5);
list.add(23);
list.add(42);
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.print(it.next() + ",");
}
for (Integer i : list) {
System.out.print(i + ",");
}
Java 1.8引入的lambda表达式,使得Java代码设计更加简洁,更具可读性。lambda表达式时建立在函数式接口上的,先简单介绍下函数式接口。
主要如下三点:
其中由于泛型的自动推断功能,参数类型type可以不用给出,编译器可以自动推断,代码中 [ ] 表示可选项
( [type1] param1, [type2] param2, [type3] param3, ...[typeN] paramN ) -> {
语句 1;
语句 2;
语句 3;
//.....
return value;
}
// 若只有一个参数时,可直接如下使用
param1 -> {
语句;
//....
return value;
}
// 若只包含一条语句,则可以如下
param1 -> statement
// 如计算x的平方
x -> x*x
比如计算x+y+z的函数lambda可表示为:
(x, y, z) -> { return x+y+z; }