12.Java中Comparable接口,Readable接口和Iterable接口
1.Comparable接口
说明:可比较(可排序的)
例子:按照MyClass的y属性进行生序排序
class MyClass implements Comparable<MyClass>{ private int x; private int y; public MyClass(int x,int y){ this.x=x; this.y=y; } @Override public int compareTo(MyClass o) { //按照y进行升序排序 return y<o.y?-1:(y==o.y?0:1); } @Override public String toString(){ return x+"@"+y; } } main函数 List<MyClass> list=new ArrayList<>(Arrays.asList(new MyClass(1,2),new MyClass(3,1),new MyClass(2,3))); Collections.sort(list); System.out.println(list); 结果: [3@1, 1@2, 2@3]
2.Comparator接口
说明:迭代器,是sort函数的参数
例子:按照MyClass的x属性进行排序
class MyClass{ public int x; public int y; public MyClass(int x,int y){ this.x=x; this.y=y; } @Override public String toString(){ return x+"@"+y; } } class MyComparator implements Comparator<MyClass>{ @Override public int compare(MyClass o1,MyClass o2){
return o1.x<o2.x?-1:(o1.x==o2.x?(o1.y<o2.y?-1:(o1.y==o2.y?0:1)):1);
} }
main函数
List<MyClass> list=new ArrayList<>(Arrays.asList(new MyClass(1,2),new MyClass(3,1),new MyClass(3,3),new MyClass(3,2),new MyClass(2,3)));
Collections.sort(list,new MyComparator());
System.out.println(list);
结果: [1@2, 2@3, 3@1, 3@2, 3@3]
3.Iterable接口
说明:可迭代,实现Iterable<T>接口之后,可以用Foreach遍历
例子:有点多余,List直接就可以用foreach遍历
class MyClass implements Iterable<Integer>{ public List<Integer> list=new ArrayList<>(Arrays.asList(new Integer(1),new Integer(2),new Integer(3))); @Override public Iterator<Integer> iterator() { return list.iterator(); } @Override public String toString(){ return super.toString(); } }
例子:结合Iterator接口
class MyClass implements Iterable<Integer>{ int[] array=new int[]{1,2,3,4,5,6,7}; int index=0; @Override public Iterator<Integer> iterator() { return new Iterator<Integer>() { @Override public boolean hasNext() { return index<array.length; } @Override public Integer next() { return array[index++]; } @Override public void remove() { throw new UnsupportedOperationException(); } }; } @Override public String toString(){ return super.toString(); } }
4.Readable接口
说明:实现Readable接口后可以作为Scanner对象的输入流
例子:
public class TaskTimeoutDemo { public static void main(String[] args) { Scanner scanner=new Scanner(new MyClass(2)); while(scanner.hasNext()){ System.out.println(scanner.nextLine()); } } } class MyClass implements Readable{ private int count; public MyClass(int count){ this.count=count; } @Override public int read(CharBuffer cb) throws IOException { if(count--==0) return -1; cb.append("Aa"); cb.append("Bb"); cb.append("Cc"); cb.append("Dd"); cb.append("Ee"); cb.append("Ff"); cb.append("Gg"); cb.append("Hh"); cb.append("Ii\n"); return 1; } }
这里需要注意一点什么时候会调用read函数?
1.scanner.hasNext()后发现缓冲区中没有数据,就回去读区输入流中的数据,输入流的数据存储在CharBuffer中,上边的例子中一次read会向缓冲区中添加一行字符串,整个程序会调用两次read函数。