这几天看了一些用java编写的程序代码,发现了很多以前不知道的api功能。原以为自己还算得上是一个java语言的中级学习者,现在看来自己只是一个java初级学习者,对java的认识一直只是停留在java的表层,解决一些应用问题只是毫无新意地将一些已知的常用接口、数据结构等翻来覆去地使用,没有更深地去了解这门语言。事实上java提供了很多功能非常强大的接口,能够很方便地为我们解决一些实际的问题,下面就具体介绍几个我最近了解的java API功能。
一. 排序
在编写java程序的时候,我们经常都会遇到排序的问题,没有深入学习过java的人一般会选择两种做法,第一种是在网上找一段代码改改后就用在自己的程序中,第二种是自己花时间写一个。当然对第一种方法如果你看懂了网上找的代码还有点点收获,对第二种方法则可以证明你是一个认真的人,对一些排序算法有比较深刻的研究,但是倘若你写的不是很精妙的排序算法,而只是写一个普通的选择、冒泡、插入亦或是更高级一点的堆排、快排、归并之类的算法,在你对这些算法已经比较熟悉的情况下,这样自己写是没有多大意义的,相反会浪费不少时间。
事实上java语言已经为它的使用者考虑到了排序的需求,提供了集合排序的函数调用,如下所示:
java.util.Arrays.sort(int[])
java.util.Arrays.sort(int[], int, int)
java.util.Arrays.sort(T[], int, int, java.util.Comparator)
java.util.Arrays.sort(T[], java.util.Comparator)
java.util.Collections.sort(java.util.List)
java.util.Collections.sort(java.util.List, java.util.Comparator)
上面所列的是可能会经常用到的函数接口,还有其它一些重载的函数,感兴趣的可以可以查一查api说明文档。下面是一个例子:
//集合排序
public class ArraySort {
//对整数集合进行排序
public void sortIntArray() {
int[] array = new int[] { 8, 5, 9, 0, 6, 3, 4, 7, 2, 1 };
System.out.println("整数排序前");
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
Arrays.sort(array);
System.out.println("整数排序后");
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
}
//对字符串集合进行排序
public void sortStringArray() {
String[] array = new String[] { "a", "c", "e", "d", "b" };
System.out.println("字符串排序前");
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
System.out.println("字符串排序后");
Arrays.sort(array);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
}
//对对象集合进行排序
public void sortObjectArray() {
Dog o1 = new Dog("dog1", 1);
Dog o2 = new Dog("dog2", 4);
Dog o3 = new Dog("dog3", 5);
Dog o4 = new Dog("dog4", 2);
Dog o5 = new Dog("dog5", 3);
Dog[] dogs = new Dog[] { o1, o2, o3, o4, o5 };
System.out.println("对象排序前");
for (int i = 0; i < dogs.length; i++) {
Dog dog = dogs[i];
System.out.print(dog.getName() + ":" + dog.getWeight()+ " ");
}
System.out.println();
Arrays.sort(dogs, new ByWeightComparator());
System.out.println("对象排序后");
for (int i = 0; i < dogs.length; i++) {
Dog dog = dogs[i];
System.out.print(dog.getName() + ":" + dog.getWeight()+ " ");
}
System.out.println();
}
public static void main(String[] args) {
ArraySort t = new ArraySort();
t.sortIntArray();
t.sortStringArray();
t.sortObjectArray();
}
}
//测试对象Dog
class Dog {
private String name;
private int weight;
public Dog(String name, int weight) {
this.setName(name);
this.weight = weight;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
//比较器,以Dog的重量作为比较的基准
class ByWeightComparator implements Comparator {
public int compare(Dog o1, Dog o2) {
int diff = o1.getWeight() - o2.getWeight();
if (diff > 0)
return 1;
if (diff < 0)
return -1;
else
return 0;
}
}
程序运行结果:
整数排序前
8 5 9 0 6 3 4 7 2 1
整数排序后
0 1 2 3 4 5 6 7 8 9
字符串排序前
a c e d b
字符串排序后
a b c d e
对象排序前
dog1:1 dog2:4 dog3:5 dog4:2 dog5:3
对象排序后
dog1:1 dog4:2 dog5:3 dog2:4 dog3:5
注意,对对象集合进行排序时,需要提供一个比较器,比较器需要实现Comparator接口并实现接口的compare方法。另外值得注意的是compare函数返回值的意义,它是拿参数中的第一个对象与第二个对象进行比较,若大于则返回1,小于则返回-1,等于则返回0。不要在函数实现体中将两个对象对数弄倒了!
二. 读写对象
有时候你会遇到这样的情况:从数据集合中读取数据,解析数据,然后封装成对象,再把对象放到一个集合中,对集合对象进行操作,程序结束。第二次需要运行程序时,又按如上的操作流程做一遍。第三次,每四次…每一次都执行相同的操作。又或者会遇到这样的情况:程序运行过程中会产生一些对象的集合,我们只对这个对象集合感兴趣,而对它是如何生成的不感兴趣。程序结束后第二次你又需要这个对象集合时,又要重新生成这个对象集合。
当你遇到这样的情况时,你有没有想过这样可能会造成系统资源的浪费,会影响功能实现的效率,那你有没有考虑过一个更好的做法来解决这个问题。事实上,这个问题可以通过java提供的实现对象读写的两个类来解决,它们是ObjectInputStream和ObjectOutputStream。通过这两个类可以非常方便的实现将对象以序列化的格式写入到文件或者是从文件读取序列化的数据来直接生成对象,这两个类操作的对象必须是可以序列化的。因此,可以利用这两个类来保存中间结果到文件中,当需要时再从文件中直接读取出中间结果,这样可以在一定程度上提高程序功能的实现效率。下面是一个例子:
public class ObjectIOStreamTest implements Serializable {
public static void main(String[] args) throws Exception {
ObjectIOStreamTest test = new ObjectIOStreamTest();
Set num = new HashSet();
num.add(test.new Student(1, "a"));
num.add(test.new Student(2, "b"));
num.add(test.new Student(3, "c"));
FileOutputStream fos = new FileOutputStream("test");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(num);
FileInputStream fis = new FileInputStream("test");
ObjectInputStream ois = new ObjectInputStream(fis);
Set num2 = new HashSet();
num2 = (Set) ois.readObject();
Iterator it = num2.iterator();
while (it.hasNext()) {
Student stu = it.next();
System.out.println(stu.getId() + " " + stu.getName());
}
}
public class Student implements Serializable {
private int id;
private String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
测试结果:
2 b
3 c
1 a
感兴趣的读者可以看看生成的test文件,它是以二进制的格式来保存对象的,其中也保存了集合的类型和对象的类型。另外要说明的是,ObjectInputStream和ObjectOutputStream两个类也可以读写复杂的数据对象,但是前提是所涉及的集合及对象都是可序列化的。
三. 集合运算
在实现数据挖掘一些算法或者是利用空间向量模型来发现相似文档的时候,会遇到求两个集合的交集的情况。以前一般是采用比较笨拙的办法,依次遍历其中一个集合的元素,然后判断它是否包含在另一个集合中。这样做非常机械繁琐,代码编得让人心烦,其实java的api中提供了对集合进行交、并、差运算的功能,灰常强大!看下面的例子:
public class SetOpt {
public List intersect(List ls, List ls2) {
List list = new ArrayList(Arrays.asList(new Object[ls.size()]));
Collections.copy(list, ls);
list.retainAll(ls2);
return list;
}
public List union(List ls, List ls2) {
List list = new ArrayList(Arrays.asList(new Object[ls.size()]));
Collections.copy(list, ls);
list.addAll(ls2);
return list;
}
public List diff(List ls, List ls2) {
List list = new ArrayList(Arrays.asList(new Object[ls.size()]));
Collections.copy(list, ls);
list.removeAll(ls2);
return list;
}
public static void main(String[] args) {
SetOpt opt = new SetOpt();
List l1 = new ArrayList();
l1.add(1);
l1.add(2);
l1.add(3);
l1.add(4);
List l2 = new ArrayList();
l2.add(3);
l2.add(4);
l2.add(5);
l2.add(6);
List intersectList = opt.intersect(l1, l2);
System.out.println("交集:");
for (int i = 0; i < intersectList.size(); i++) {
System.out.print(intersectList.get(i) + " ");
}
System.out.println();
List unionList = opt.union(l1, l2);
System.out.println("并集:");
for (int i = 0; i < unionList.size(); i++) {
System.out.print(unionList.get(i) + " ");
}
System.out.println();
List diffList = opt.diff(l1, l2);
System.out.println("差集:");
for (int i = 0; i < diffList.size(); i++) {
System.out.print(diffList.get(i) + " ");
}
System.out.println();
}
}
测试结果:
交集:
3 4
并集:
1 2 3 4 3 4 5 6
差集:
1 2
注意:在进行两个集合(操作集合和被操作集合)交、并、差操作时,一定要先将操作集合拷贝一份,以拷贝的集合作为操作集合来进行运算。否则,将改变原来操作集合的内容。
四. 排序的集合
在java中,提供了一个(可能还有其它的)可以进行排序的集合对象TreeSet,它实现了SortedSet集合接口,对于普通类型的集合元素,它们默认是按照字母顺序排列的,对于复杂类型的集合元素,需要为集合对象指定比较器。看下面的例子:
public class TreeSetTest {
private static Comparator comparator = new Comparator() {
public int compare(Node o1, Node o2) {
int diff = o1.getValue() - o2.getValue();
if (diff > 0) {
return 1;
} else if(diff < 0){
return -1;
} else {
return 0;
}
}
};
public static void main(String[] args) {
TreeSetTest tst = new TreeSetTest();
SortedSet pq = new TreeSet(comparator);
pq.add(tst.new Node(3));
pq.add(tst.new Node(5));
pq.add(tst.new Node(2));
pq.add(tst.new Node(1));
Iterator it = pq.iterator();
while(it.hasNext()){
Node node = it.next();
System.out.println(node.getValue());
}
}
public class Node {
private int value;
public Node(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
}
测试结果:
1
2
3
5
五. 二分查找
二分查找是一个高效的查找算法,在java的集合对象中也提供了二分查找的算法,如下面的java api接口:
java.util.Arrays.binarySearch(java.lang.Object,java.lang.Object,java.util.Comparator)
java.util.Arrays.binarySearch(java.lang.Object[], java.lang.Object)
上面列出的是两个泛型接口,还有其它不同参数类型的重载函数没有在此列出,请参考java api文档。
分享到:
相关推荐
下面我们将深入探讨如何在Java中实现集合的分组与排序。 1. **集合分组**: 集合分组通常涉及到`GroupingBy`操作,这在Java 8引入的流(Stream)API中得到了很好的支持。`Collectors.groupingBy`方法允许我们将...
Java 1.8 API中文手册是Java开发者的重要参考资料,它详细介绍了Java 1.8版本中的各种类库、接口、方法和异常等核心组件。这个手册以中文的形式提供了丰富的编程指南,帮助开发者理解和使用Java 1.8的特性。下面我们...
此外,`JavaAPI(CHINA).chm`文件是一个Windows帮助文档格式,其中包含的索引和搜索功能使得查找特定API变得轻而易举。开发者可以通过这个文件快速定位到所需的信息,提高开发效率。 总之,《JAVA中文版API使用手册...
Java API,全称为Java应用程序接口,是Java编程语言的核心组成部分,包含了各种类库、接口和异常,为开发者提供了丰富的功能,极大地提高了开发效率。本文将深入探讨Java API中的一些常见且重要的类和方法,结合实际...
Java API(Application Programming Interface)是Java编程语言的核心组成部分,它为开发者提供了丰富的类库和接口,使得开发人员能够构建各种复杂的应用程序。这份"JAVA API官方文档中文版"是Java开发者的重要参考...
它们提供了存储和操作对象的方式,支持数据结构的操作,如添加、删除、查找和排序。 3. **多线程**:`java.lang.Thread`和`java.util.concurrent`包提供了多线程编程的支持。线程是程序中的执行流,可以同时执行多...
例如,`ArrayList`类是`java.util`包中的一个动态数组实现,提供了添加、删除、查找和排序元素的功能。通过阅读文档,开发者可以了解如何正确使用这些类。 3. **接口(Interfaces)**:接口定义了一组方法的签名,...
例如,`java.util.Comparator`接口定义了比较两个对象的通用方法,广泛用于排序和比较操作。 总的来说,Java API接口是Java编程的基础,通过理解和熟练使用这些接口,开发者可以高效地编写出稳定且功能丰富的程序。...
- **快速查找**:压缩包中的"Java_api查找"可能是一个搜索工具或目录,帮助开发者快速定位所需API。通常,开发者可以通过类名、方法名或关键词进行查找,理解API的用途和用法。 - **API详解**:每个类和接口的文档...
Java API帮助文档是Java开发人员的重要参考资料,它包含了Java标准库中的各种类和接口的详细说明,特别是"util"标签指出,这部分主要关注的是Java的`java.util`包。这个包是Java的核心部分,提供了大量的工具类和...
总的来说,《Java JDK API 1.8谷歌翻译中文版在线参考手册》是Java开发者的重要学习和参考资料,它覆盖了Java 1.8的所有核心API,可以帮助开发者快速查找和理解各种类、接口和方法,提高开发效率。无论你是初学者...
8. **国际化与本地化**:`java.text`和`java.util.Locale`支持全球化应用,可以处理不同地区的日期格式、数字格式和文本排序。 9. **泛型**:Java 5引入的泛型增强了类型安全,允许在定义类、接口和方法时指定参数...
- `Collections`: 集合操作的工具类,提供了排序、填充、查找等方法。 3. **并发编程** - `Thread`: 多线程编程的基础,提供了`start()`启动线程和`sleep()`暂停线程等方法。 - `ExecutorService`, `...
这些类提供了丰富的操作方法,如添加、删除、查找元素,以及对集合的遍历和排序。 3. **泛型**:Java 7中的泛型允许在类、接口和方法声明中使用类型参数,增强了类型安全,减少了强制类型转换。泛型通配符如用于...
- **Collections工具类**:提供了对集合的各种操作,如排序、查找、填充等。 6. **反射机制**: - **Class类**:代表运行时的类信息,通过它我们可以获取类的方法、字段等。 - **Constructor、Method和Field**:...
在Java API中,有众多的类供开发者使用,这些类涵盖了数据处理、文件操作、网络通信、集合框架等多个方面。本笔记将详细讲解一些常用的Java类,并探讨它们的使用方法和应用场景。 首先,我们来看看Java基础类库中的...
Java API,全称为Java应用程序接口,是Java编程语言的核心组成部分,包含了各种类库、接口和异常,为开发者提供了丰富的功能,使得开发Java程序变得更加高效和便捷。本资料“java常用API-适合初学者”旨在帮助初学者...
这些接口和类提供了丰富的操作方法,支持数据的增删改查,以及各种排序和查找算法。 2. **I/O流**:Java I/O流系统允许程序进行数据输入和输出。它分为字符流和字节流,涵盖了文件操作、网络通信、对象序列化等多种...
Java 1.8 API 帮助文档是Java开发者的重要参考资料,它包含了Java Development Kit (JDK) 1.8版本中的所有公共类、接口、枚举和注解的详细说明。这个中文版文档使得中国开发者能更方便地理解和使用Java 1.8的特性,...
### Java API函数大全 在Java开发中,熟练掌握并运用API是提高开发效率、编写高质量代码的关键之一。本文将从给定的文档片段出发,详细解读其中提及的一些关键API概念及函数,帮助开发者们深入了解这些功能的具体...