java学习脚印:集合(Collection)之算法
来源:互联网 发布:陈一发知乎 编辑:程序博客网 时间:2024/06/05 20:42
java学习脚印:集合(Collection)之算法
上接,《java学习脚印:集合(Collection)之实现类》。
集合框架提供了一些诸如排序,查找,打散顺序(Shuffling),逆置,旋转,取最大值,取最小值等基本算法,还可以使用集合框架中的接口实现自己的算法。
这里重点提示一下排序算法和查找算法,其他的算法可参考相关API。
1.排序算法
1.1 java中对象排序的方式
java中的sort排序采用稳定的归并排序算法。
要对一个集合进行排序有两种方法:
1) 实现Comparable接口,进行自然排序。
Comparable该接口声明有方法:
int compareTo(T o),利用该方法对元素进行排序,这称为自然排序(natural ordering) 。对于没有实现Comparable接口的类调用Collections.sort()或者Arrays.sort()方法均会抛出ClassCastException异常。
下表给出了实现了Comparable接口的一些类及其自然排序。
(来自:http://docs.oracle.com/javase/tutorial/collections/interfaces/order.html)。
Class
NaturalOrdering
Byte
Signednumerical(有符号数值比较)
Character
Unsignednumerical(无符号数值比较)
Long
Signednumerical
Integer
Signednumerical
Short
Signednumerical
Double
Signednumerical
Float
Signednumerical
BigInteger
Signednumerical
BigDecimal
Signednumerical
Boolean
Boolean.FALSE< Boolean.TRUE
File
System-dependentlexicographic on path name
(依赖于平台的路径字典序)
String
Lexicographic(字典序)
Date
Chronological(年代)
CollationKey
Locale-specificlexicographic
2)构造Comparators比较器,自定义排序规则。
Comparators接口声明有一个比较方法:
public interface Comparator<T> {
int compare(T o1, T o2);
}
通过像集合类或者sort方法传递一个Comparator即可实现自己所需要的排序。
具体可参见代码案例部分。
1.2 代码实例
这里举出一个首先利用自然排序即按Date排序,然后按照Comparator排序的案例。
注意两种排序方式的使用,以及观察稳定排序的特点。
代码清单1-1 :CollectionsDemo8.java
package com.learningjava;import java.text.SimpleDateFormat;import java.util.*;/** * This program illustrate usage of sort method in Collections * @author wangdq * 2013-11-4 */public class CollectionsDemo8 {public static void main(String[] args) {Employee[] staffs = new Employee[]{new Employee("Steve",5500,1986,7,13),new Employee("Jack",7000,1986,7,5),new Employee("Karl",5000,1985,11,2),new Employee("Jason",7000,1980,8,12),};//before sortSystem.out.println("Original:"+Arrays.toString(staffs));//create a backup arraylist and shuffled itArrayList<Employee> bkList1 = new ArrayList<Employee>(Arrays.asList(staffs));Collections.shuffle(bkList1);System.out.println("Shuffled:"+bkList1);//sorted it by natural ordering(compare date)ArrayList<Employee> bkList2 = new ArrayList<Employee>(Arrays.asList(staffs));Collections.sort(bkList2);System.out.println("date order:"+bkList2);//sorted it by name via providing a ComparatorArrayList<Employee> bkList3 = new ArrayList<Employee>(Arrays.asList(staffs));Collections.sort(bkList3,new Comparator<Employee>(){@Overridepublic int compare(Employee e1, Employee e2) {// TODO Auto-generated method stubreturn e1.getName().compareTo(e2.getName());}});System.out.println("name order:"+bkList3);//sort based on bkList3//thus we get sorted by name and then by salary//check if it is a stable sortCollections.sort(bkList3,new Comparator<Employee>(){@Overridepublic int compare(Employee e1, Employee e2) {return Double.valueOf(e1.getSalary()).compareTo(Double.valueOf(e2.getSalary()));}});System.out.println("salary order:"+bkList3);}}/** * a class to descript employee * origin by the book 《Core Java,Volume I:Fundamentals》 * @version 1.1 2013-08-07 */class Employee implements Comparable<Employee>{/** * * @param name name to set * @param salary salary to set * @param year month day to create a GregorianCalendar */public Employee(String name, double salary, int year,int month,int day) {this.name = name;this.salary = salary;GregorianCalendar calendar = new GregorianCalendar(year,month-1,day);this.hireDay = calendar.getTime();setId();}public void raiseSalary(double percent) {double raise = salary*percent/100;salary += raise;}public String getName() {return name;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}public Date getHireday() {return (Date)hireDay.clone();}public void setHireday(Date hireDay) {this.hireDay = hireDay;}public int getId() {return id;}private void setId() {this.id = nextId;nextId++;}@Override//sort by hireDaypublic int compareTo(Employee o) {// TODO Auto-generated method stubreturn this.hireDay.compareTo(o.getHireday());}@Overridepublic String toString() {SimpleDateFormat dateformat =new SimpleDateFormat("yyyy-MM-dd");String date = dateformat.format(hireDay);return "["+name+","+getSalary()+","+date+"]";}private String name; private double salary;private Date hireDay;private int id;private static int nextId = 1;}
运行输出
Original: [[Steve,5500.0,1986-07-13], [Jack,7000.0,1986-07-05], [Karl,5000.0,1985-11-02], [Jason,7000.0,1980-08-12]]
Shuffled: [[Jason,7000.0,1980-08-12], [Steve,5500.0,1986-07-13], [Karl,5000.0,1985-11-02], [Jack,7000.0,1986-07-05]]
date order: [[Jason,7000.0,1980-08-12], [Karl,5000.0,1985-11-02], [Jack,7000.0,1986-07-05], [Steve,5500.0,1986-07-13]]
name order: [[Jack,7000.0,1986-07-05], [Jason,7000.0,1980-08-12], [Karl,5000.0,1985-11-02], [Steve,5500.0,1986-07-13]]
salary order: [[Karl,5000.0,1985-11-02], [Steve,5500.0,1986-07-13], [Jack,7000.0,1986-07-05], [Jason,7000.0,1980-08-12]]
这里先按姓名进行了排序,然后按工资进行了排序,工资排序中jack和jason工资相等,因为是稳定排序,所以最后的结果是工资想等者按先前的姓名排序结果排列。
2.查找算法
java查找排序采用二分查找,要求必须是有序的顺序存贮的列表,否则影响查找结果和查找效率。
查找成功时,返回该元素在列表中的索引;当查找失败时,返回的索引并非无用,它恰好给出了插入该元素的一个参考,查找失败时,元素插入位置为:-pos-1,如下:
int pos = Collections.binarySearch(list, key);
if (pos < 0)
l.add(-pos-1, key);
下面给出一个实例代码,以加深理解。
代码清单1-2 :CollectionsDemo9.java
package com.learningjava;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;/** * This program illustrate usage of search method in Collections * @author wangdq * 2013-11-4 */public class CollectionsDemo9 {public static void main(String[] args) {Integer[] ints = new Integer[]{5,13,19,21,37,56,64,75,80,88,92};ArrayList<Integer> bkList1 = new ArrayList<>(Arrays.asList(ints));//before reverseSystem.out.println("original list:"+Arrays.toString(ints));//reverse listCollections.reverse(bkList1);System.out.println("reversed list:"+bkList1);//sort the listArrayList<Integer> bkList2 = new ArrayList<>(Arrays.asList(ints));Collections.sort(bkList2);System.out.println("sorted list:"+bkList2);//binary search with included keyint index = Collections.binarySearch(bkList2, Integer.valueOf(21));System.out.println("search 21:"+index);//binary search with non-included keyint Index2 = Collections.binarySearch(bkList2, Integer.valueOf(85));System.out.println("search 85:"+Index2);if (Index2 < 0)bkList2.add(-Index2-1, Integer.valueOf(85));//insertposition -Index2-1System.out.println("after insert:"+bkList2);}}
运行输出
original list: [5, 13, 19, 21, 37, 56, 64, 75, 80, 88, 92]
reversed list: [92, 88, 80, 75, 64, 56, 37, 21, 19, 13, 5]
sorted list: [5, 13, 19, 21, 37, 56, 64, 75, 80, 88, 92]
search 21: 3
search 85: -10
after insert: [5, 13, 19, 21, 37, 56, 64, 75, 80, 85, 88, 92]
- java学习脚印:集合(Collection)之算法
- java学习脚印:集合(Collection)之接口
- java学习脚印:集合(Collection)之实现类
- java--------学习之《集合类 (Collection)》
- Java集合学习之Collection(2)
- java集合学习之Collection(3)
- Java学习笔记之集合Collection&Map
- Java集合之Collection
- Java集合之Collection
- java集合之Collection
- Java之集合Collection
- Java集合框架学习笔记之集合与Collection API
- Java学习笔记之集合(一):Collection集合的方法
- JAVA学习笔记---集合(Collection)
- java-collection-集合的学习
- 四大名捕----JAVA集合之Collection
- Java SE 之 Collection集合
- Java 入门 之 集合 Collection
- Java中获取键盘输入值的三种方法
- Arm Linux交叉编译和连接过程分析(1)
- 为动态创建的LinkButton加Onclick事件
- C指针原理(7)-C内嵌汇编
- 简单的RPC java实现
- java学习脚印:集合(Collection)之算法
- OpenCV问题集结版
- ADO和ADO.NET的区别
- Arm Linux交叉编译和连接过程分析(2)
- vs08新建win32空白项目 属性设置
- 详解排序算法C语言代码实现之选择排序法
- JAVA线程状态
- 将List集合插入到数据库中,C#中的事物实现
- pthread_mutex_t的使用