容易忽视但是功能灰常强大的Java API

2023-12-15 14:32

本文主要是介绍容易忽视但是功能灰常强大的Java API,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这几天看了一些用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文档。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/luowen3405/archive/2011/04/18/6331763.aspx

这篇关于容易忽视但是功能灰常强大的Java API的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/496778

相关文章

Java五子棋之坐标校正

上篇针对了Java项目中的解构思维,在这篇内容中我们不妨从整体项目中拆解拿出一个非常重要的五子棋逻辑实现:坐标校正,我们如何使漫无目的鼠标点击变得有序化和可控化呢? 目录 一、从鼠标监听到获取坐标 1.MouseListener和MouseAdapter 2.mousePressed方法 二、坐标校正的具体实现方法 1.关于fillOval方法 2.坐标获取 3.坐标转换 4.坐

Spring Cloud:构建分布式系统的利器

引言 在当今的云计算和微服务架构时代,构建高效、可靠的分布式系统成为软件开发的重要任务。Spring Cloud 提供了一套完整的解决方案,帮助开发者快速构建分布式系统中的一些常见模式(例如配置管理、服务发现、断路器等)。本文将探讨 Spring Cloud 的定义、核心组件、应用场景以及未来的发展趋势。 什么是 Spring Cloud Spring Cloud 是一个基于 Spring

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

java8的新特性之一(Java Lambda表达式)

1:Java8的新特性 Lambda 表达式: 允许以更简洁的方式表示匿名函数(或称为闭包)。可以将Lambda表达式作为参数传递给方法或赋值给函数式接口类型的变量。 Stream API: 提供了一种处理集合数据的流式处理方式,支持函数式编程风格。 允许以声明性方式处理数据集合(如List、Set等)。提供了一系列操作,如map、filter、reduce等,以支持复杂的查询和转

Java面试八股之怎么通过Java程序判断JVM是32位还是64位

怎么通过Java程序判断JVM是32位还是64位 可以通过Java程序内部检查系统属性来判断当前运行的JVM是32位还是64位。以下是一个简单的方法: public class JvmBitCheck {public static void main(String[] args) {String arch = System.getProperty("os.arch");String dataM

详细分析Springmvc中的@ModelAttribute基本知识(附Demo)

目录 前言1. 注解用法1.1 方法参数1.2 方法1.3 类 2. 注解场景2.1 表单参数2.2 AJAX请求2.3 文件上传 3. 实战4. 总结 前言 将请求参数绑定到模型对象上,或者在请求处理之前添加模型属性 可以在方法参数、方法或者类上使用 一般适用这几种场景: 表单处理:通过 @ModelAttribute 将表单数据绑定到模型对象上预处理逻辑:在请求处理之前

eclipse运行springboot项目,找不到主类

解决办法尝试了很多种,下载sts压缩包行不通。最后解决办法如图: help--->Eclipse Marketplace--->Popular--->找到Spring Tools 3---->Installed。

JAVA读取MongoDB中的二进制图片并显示在页面上

1:Jsp页面: <td><img src="${ctx}/mongoImg/show"></td> 2:xml配置: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001

Java面试题:通过实例说明内连接、左外连接和右外连接的区别

在 SQL 中,连接(JOIN)用于在多个表之间组合行。最常用的连接类型是内连接(INNER JOIN)、左外连接(LEFT OUTER JOIN)和右外连接(RIGHT OUTER JOIN)。它们的主要区别在于它们如何处理表之间的匹配和不匹配行。下面是每种连接的详细说明和示例。 表示例 假设有两个表:Customers 和 Orders。 Customers CustomerIDCus

22.手绘Spring DI运行时序图

1.依赖注入发生的时间 当Spring loC容器完成了 Bean定义资源的定位、载入和解析注册以后,loC容器中已经管理类Bean 定义的相关数据,但是此时loC容器还没有对所管理的Bean进行依赖注入,依赖注入在以下两种情况 发生: 、用户第一次调用getBean()方法时,loC容器触发依赖注入。 、当用户在配置文件中将<bean>元素配置了 lazy-init二false属性,即让