StudyTonight-Java-中文教程-四-
StudyTonight Java 中文教程(四)
原文:StudyTonight
Java 二分搜索法
原文:https://www.studytonight.com/java-examples/java-binary-search
二分搜索法是一种高效的搜索算法,用于在排序的数组中寻找一个值。它比线性搜索性能好得多。正常的线性搜索不会以任何方式利用排序的数组特征,但是二分搜索法在每次迭代中使用排序的数组来消除一半的数组。在本教程中,我们将学习二分搜索法算法,并用 Java 实现它。
二分搜索法算法
如上所述,二分搜索法算法在每次迭代中消除了一半的数组。它通过将关键字(我们试图搜索的值)与数组的中间元素进行比较来实现这一点。
- 如果中间元素大于键,那么数组右半部分的所有元素也会大于键,因为数组是按升序排序的。
- 类似地,如果中间元素比关键点小,那么左半部分的所有元素也会更小。
- 这样,在每次比较中,我们都将搜索范围缩小到数组的一半。
我们将使用三个索引指针来表示最左边的索引(数组的开始)、最右边的索引(数组的结束)和中间的索引。二分搜索法算法总结如下。
- 将键与数组的中间元素进行比较。如果键与中间元素匹配,则返回中间元素的索引。
- 否则,如果中间元素大于键,则键只能出现在左半部分。所以我们在数组的左半部分重新开始搜索。我们将右索引重置为(中间索引- 1)。
- 否则我们在数组的右半部分重新开始搜索(因为中间的元素比键小)。我们将左索引重置为(中间索引+ 1)。
- 如果数组中没有这个键,那么我们返回-1。
二分搜索法-试运行
让我们借助一个例子来理解二分搜索法是如何工作的。假设我们有排序后的数组【5,7,15,20,110,120,139,500】,我们试图在其中搜索元素 15 。
最初,我们将考虑整个数组,数组的中间元素是 20。
15 小于 20,所以我们将移到左半部分。现在,搜索将在数组【5,7,15】上进行。这个数组的中间元素是 7。
15 大于 7,所以我们将移动到数组的右半部分【5,7,15】。新阵是【15】。这个数组的中间元素是 15。
15 等于中间元素(15),因此我们的搜索到此结束。
二分搜索法执行
上述算法既可以迭代实现,也可以递归实现。我们可以在这里使用递归,因为实际上,我们在数组的不同部分运行相同的三个步骤。我们将使用公式 low +((高-低)/ 2) 来计算中间索引,因为这将避免较大数组的溢出。
Java 中的迭代二分搜索法实现
import java.util.Arrays;
public class BinarySearch
{
public static int binarySearchIterative(int[] sortedArray, int key)
{
int leftIdx = 0;
int rightIdx = sortedArray.length - 1;
while(leftIdx <= rightIdx)
{
int midIdx = leftIdx + (rightIdx - leftIdx) / 2;
if(sortedArray[midIdx] == key)
return midIdx;
else if(sortedArray[midIdx] > key)
{
rightIdx = midIdx - 1;//left half of the array(from leftIdx to midIdx - 1)
}
else
leftIdx = midIdx + 1;//right half of the array(from midIdx + 1 to rightIdx)
}
return -1;//if key is absent
}
public static void main(String[] args)
{
int[] sortedArray = {5, 7, 15, 20, 110, 120, 139, 500};
int key1 = 139;
int key2 = 2;
System.out.println("The sorted list is: " + Arrays.toString(sortedArray));
System.out.println("The key " + key1 + " is present at index " + binarySearchIterative(sortedArray, key1));
System.out.println("The key " + key2 + " is present at index " + binarySearchIterative(sortedArray, key2));
}
}
排序列表为:【5,7,15,20,110,120,139,500】
键 139 出现在索引 6
键 2 出现在索引-1
Java 中递归二分搜索法实现
对于递归方法,我们将把左极值索引和右极值索引传递给方法本身。对于初始调用,左索引将为 0,右索引将比数组长度小 1。
import java.util.Arrays;
public class BinarySearch
{
public static int binarySearchRecursive(int[] sortedArray, int key, int leftIdx, int rightIdx)
{
if(leftIdx <= rightIdx)
{
int midIdx = leftIdx + (rightIdx - leftIdx) / 2;
if(sortedArray[midIdx] == key)
return midIdx;
else if(sortedArray[midIdx] > key)
{
return binarySearchRecursive(sortedArray, key, leftIdx, midIdx - 1); //left half of the array(from leftIdx to midIdx - 1)
}
else
return binarySearchRecursive(sortedArray, key, midIdx + 1, rightIdx);//right half of the array(from midIdx + 1 to rightIdx)
}
else
return -1;//if key is absent
}
public static void main(String[] args)
{
int[] sortedArray = {5, 7, 15, 20, 110, 120, 139, 500};
int leftIdx = 0;
int rightIdx = sortedArray.length - 1;
int key1 = 139;
int key2 = 2;
System.out.println("The sorted list is: " + Arrays.toString(sortedArray));
System.out.println("The key " + key1 + " is present at index " + binarySearchRecursive(sortedArray, key1, leftIdx, rightIdx));
System.out.println("The key " + key2 + " is present at index " + binarySearchRecursive(sortedArray, key2, leftIdx, rightIdx));
}
}
排序列表为:【5,7,15,20,110,120,139,500】
键 139 出现在索引 6
键 2 出现在索引-1
为二分搜索法使用内置方法
Java 中的数组. binarySearch()方法
Java 中的 Arrays 类为我们提供了一个 binarySearch()方法,将排序后的数组和要搜索的键值作为参数,返回存在键值的索引。如果密钥不在数组中,则返回-1。
import java.util.Arrays;
public class BinarySearch
{
public static void main(String[] args)
{
int[] sortedArray = {5, 7, 15, 20, 110, 120, 139, 500};
int key1 = 139;
int key2 = 2;
System.out.println("The sorted array is: " + Arrays.toString(sortedArray));
System.out.println("The key " + key1 + " is present at index " + Arrays.binarySearch(sortedArray, key1));
System.out.println("The key " + key2 + " is present at index " + Arrays.binarySearch(sortedArray, key2));
}
}
排序后的数组为:【5,7,15,20,110,120,139,500】
键 139 出现在索引 6
键 2 出现在索引-1
Java 中的 Collections.binarySearch()方法
Collections 类的 binarySearch()方法可用于像 ArrayLists 这样的集合来搜索元素。就像 Arrays.binarySearch()方法一样,它将排序后的集合和一个键作为参数,并返回该键所在的索引。如果钥匙不在列表中,则返回-1。
import java.util.ArrayList;
import java.util.Collections;
public class BinarySearch
{
public static void main(String[] args)
{
ArrayList<Integer> sortedList = new ArrayList<Integer>();
sortedList.add(5);
sortedList.add(7);
sortedList.add(15);
sortedList.add(20);
sortedList.add(110);
sortedList.add(120);
sortedList.add(139);
sortedList.add(500);
int key1 = 139;
int key2 = 2;
System.out.println("The sorted list is: " + sortedList);
System.out.println("The key " + key1 + " is present at index " + Collections.binarySearch(sortedList, key1));
System.out.println("The key " + key2 + " is present at index " + Collections.binarySearch(sortedList, key2));
}
}
排序列表为:【5,7,15,20,110,120,139,500】
键 139 出现在索引 6
键 2 出现在索引-1
常见问题
问:为什么叫二分搜索法?
二元意味着由两件事组成,在二分搜索法,我们只是在每次迭代中将搜索范围缩小到两半(左和右)。
问:为什么我们不能在未排序的数组上使用二分搜索法?
二分搜索法算法基于排序数组。对于未排序的数组,右半部分或左半部分的元素与中间元素之间没有关系。但是对于排序数组,我们知道如果中间元素大于一个数,那么右半部分的所有元素都将大于该元素。同样,如果中间元素小于一个数字,那么左半部分的所有元素也将小于该数字。
问:二叉查找树使用二分搜索法算法吗?
创建二叉查找树的方式是,左子树中的所有元素都小于根,右子树中的所有元素都大于根。这使得树被排序,我们可以使用二分搜索法算法来搜索树中的节点。
摘要
二分搜索法是在排序数组中搜索值的一种快速有效的方法。不同于线性搜索需要线性时间(O(n)),****二分搜索法需要对数时间(O(log(n))** 。 n 表示数组中存在的元素总数。递归实现更容易理解,但是递归可能会慢一点,因为递归栈。**
请记住二分搜索法只能在排序的数组**上使用,如果数组没有排序,那么我们应该或者使用像归并排序这样的排序算法来首先对数组进行排序,或者在这种情况下我们可以简单地使用线性搜索。使用额外的排序算法会增加时间复杂度,在这种情况下可以考虑线性搜索。
总体而言,线性搜索对于较小尺寸的数组表现更好,而二分搜索法优选用于较大尺寸的数组。
Java 中的Comparator
和Comparable
原文:https://www.studytonight.com/java-examples/comparator-and-comparable-in-java
相互比较项目是非常常见的,它有各种各样的应用。排序的整个思想是基于将一个对象与另一个对象进行比较,并决定哪个对象在排序的集合中最先出现。Comparator
和可Comparator
是两个接口,可以通过类实现来比较它们的对象。在本教程中,我们将了解更多关于这些接口的信息,并了解两者之间的一些关键区别。
Comparable
接口
Comparable
接口用于根据一些参数或标准比较一个类的不同对象。这些标准形成了该类的自然排序。
例如,考虑一个有三个字段的学生班级——姓名、GPA 和注册号。现在,假设我们想根据两个学生的平均成绩来比较他们。基于 GPA 的对象的这种自然排序可以通过使用Comparable
接口来定义。
要相互比较一个类的对象,类必须实现Comparable
接口。然后我们需要通过覆盖 compareTo()方法来定义比较策略。比较()方法返回一个整数值。根据以下条件,该值可以是正值、负值或零。
- 如果调用对象更大,则为正。
- 如果调用对象较小,则为负。
- 如果两者相等,则为 0。
让我们继续学生类的例子,并尝试根据他们的平均成绩来比较两个学生对象。我们可以简单地返回调用学生对象和作为参数的学生对象的 GPA 的差异。这将根据上述条件返回一个整数。下面显示了此场景的 compareTo()方法。
@Override
public int compareTo(Student other)
{
return (int)(this.getGpa() - other.getGpa());
}
示例:Java 中的Comparable
接口
现在,让我们用这个方法来比较两个学生。完整的类实现和主要方法如下所示。
class Student implements Comparable<Student>
{
private String name;
private int gpa;
private int regNo;
//Constructor
public Student(String name, int gpa, int regNo) {
this.name = name;
this.gpa = gpa;
this.regNo = regNo;
}
//Override the comapareTo() method
@Override
public int compareTo(Student other)
{
return (int)(this.getGpa() - other.getGpa());//compare using GPA
}
//getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGpa() {
return gpa;
}
public void setGpa(int gpa) {
this.gpa = gpa;
}
public int getRegNo() {
return regNo;
}
public void setRegNo(int regNo) {
this.regNo = regNo;
}
}
public class ComparatorComparable
{
public static void main(String[] args)
{
Student s1 = new Student("Justin", 9, 101);
Student s2 = new Student("Victor", 8, 102);
int comparisonResult = s1.compareTo(s2);
if(comparisonResult > 0)
System.out.println(s1.getName() + " has higher GPA");
else if(comparisonResult < 0)
System.out.println(s2.getName() + " has higher GPA");
else
System.out.println(s1.getName() + " and "+ s2.getName() + " have same GPA");
}
}
贾斯汀的 GPA 更高
我们经常需要将对象的集合(如ArrayList
或列表)按升序和降序排序。Collections 类有一个 sort()方法,该方法在内部使用类的这个被覆盖的 compareTo()方法来比较对象,然后对它们进行排序。让我们根据学生的平均成绩对学生名单进行排序。GPA 最低的学生在排序列表中排名第一。
import java.util.ArrayList;
import java.util.Collections;
public class ComparatorComparable
{
public static void main(String[] args)
{
Student s1 = new Student("Justin", 9, 101);
Student s2 = new Student("Victor", 7, 102);
Student s3 = new Student("Jessica", 8, 103);
Student s4 = new Student("Paul", 5, 104);
Student s5 = new Student("Rachel",8, 105);
ArrayList<Student> listOfStudents = new ArrayList<Student>();
listOfStudents.add(s1);
listOfStudents.add(s2);
listOfStudents.add(s3);
listOfStudents.add(s4);
listOfStudents.add(s5);
Collections.sort(listOfStudents);
for(Student s : listOfStudents)
System.out.println(s.getName() + " " + s.getGpa());
}
}
保罗 5
维克多 7
杰西卡 8
瑞秋 8
贾斯汀 9
Comparator
接口
Comparator
接口也用于根据一些参数比较一个类的对象。但是与 Comparable 接口不同,Comparator 接口可以用来创建多个类,以便根据不同成员变量的值来比较对象。
例如,如果我们希望根据学生的注册号码、他们的 GPA 以及他们的名字对一组学生进行排序,那么我们可以创建三个不同的类来实现Comparator
接口。
Comparable
接口,另一方面,只能创建一个 compareTo()方法,该方法将根据任意一个成员对数组进行排序。- 有时我们可能无法访问原始类,因此我们无法根据需要创建 compareTo()方法。在这些情况下,
Comparator
接口证明非常有用。 - 要使用 Comparator 接口,我们需要创建一个单独的类来实现这个接口。然后,我们必须在我们的类中覆盖这个接口的 compare()方法。
- compare()方法类似于
Comparable
接口的 compareTo()方法。它还返回一个遵循与 compareTo()方法相同条件的整数值。
示例:Java 中的Comparator
接口
让我们创建三个不同的类来实现Comparator
接口,并覆盖 compare()方法。
学生平均成绩等级:
class CompareUsingGPA implements Comparator<Student>
{
@Override
public int compare(Student s1, Student s2)
{
return s1.getGpa() - s2.getGpa();
}
}
学生姓名的类别:
class CompareUsingName implements Comparator<Student>
{
@Override
public int compare(Student s1, Student s2)
{
return s1.getName().compareTo(s2.getName());//the compareTo() method is already defined
//for strings so we can directly use it
}
}
学生注册班级:
class CompareUsingRegNo implements Comparator<Student>
{
@Override
public int compare(Student s1, Student s2)
{
return s1.getRegNo() - s2.getRegNo();
}
}
现在让我们使用这些Comparator
对学生列表进行排序。collections . sort()可以获取一个额外的类对象,该类对象具有一个被覆盖的 compare()方法。sort()方法将在内部使用这个 compare()方法对对象进行排序。
public class ComparatorComparable
{
public static void main(String[] args)
{
Student s1 = new Student("Justin", 9, 101);
Student s2 = new Student("Victor", 7, 102);
Student s3 = new Student("Jessica", 8, 103);
Student s4 = new Student("Paul", 5, 104);
Student s5 = new Student("Rachel",8, 105);
ArrayList<Student> listOfStudents = new ArrayList<Student>();
listOfStudents.add(s1);
listOfStudents.add(s2);
listOfStudents.add(s3);
listOfStudents.add(s4);
listOfStudents.add(s5);
System.out.println("Intial unsorted list:");
for(Student s:listOfStudents)
System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());
//Sorting Using GPA
CompareUsingGPA c1 = new CompareUsingGPA();
Collections.sort(listOfStudents, c1);
System.out.println("\nSorting using GPA");
for(Student s:listOfStudents)
System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());
//Sorting Using Names
CompareUsingName c2 = new CompareUsingName();
Collections.sort(listOfStudents, c2);
System.out.println("\nSorting using Name");
for(Student s:listOfStudents)
System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());
//Sorting Using Registration Number
CompareUsingRegNo c3 = new CompareUsingRegNo();
Collections.sort(listOfStudents, c3);
System.out.println("\nSorting using Registration Numbers");
for(Student s:listOfStudents)
System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());
}
}
初始未排序列表:
Justin 101 9
Victor 102 7
Jessica 103 8
Paul 104 5
Rachel 105 8
T7】使用 GPA 排序
Paul 104 5
Victor 102 7
Jessica 103 8
Rachel 105 8
Justin 101 9
T14】使用名称排序
Jessica 103 8 【T16
摘要
可比和Comparator
接口用于比较一个类的对象。Comparable
接口用于为类设置自然的排序模式。当我们需要多种比较对象的方式时,可以使用Comparator
接口。当我们无法访问原始类时,Comparator
也很有用。
Java 中的图
原文:https://www.studytonight.com/java-examples/graphs-in-java
图是一种数据结构,用于存储元素和元素之间的连接。图的元素称为顶点或节点,两个节点或顶点之间的连接由它们之间的边表示。
图有很多真实世界的用例。它们可以用来表示社交媒体网站上的人际网络,也可以用来表示各个城市之间的联系。
在本教程中,我们将学习图的基础知识,并在 Java 中实现一些常见的图操作。
图数据结构
如上所述,图是由边连接的节点网络。下图显示了一个图表,其中每个节点代表一个城市,两个节点之间的一条边表示它们之间有一条直接的路线。
图有各种类型,但在本教程中,我们将只关注一些最重要的图。
无向图
其中边是双向的的图,或者其中边不表示方向的图被称为无向图。上一节显示的城市图是无向图。在下图中,A 和 B 之间存在一条边,我们可以不受任何限制地从 A 自由移动到 B,或者从 B 自由移动到 A。
有向图
其中边表示方向的图称为有向图。例如,在下图中,A 和 B 之间的边缘有一个从 A 指向 B 的箭头。这意味着我们可以从 A 到 B,但不能从另一个方向(从 B 到 A)前进。B 和 C 之间的边有两个箭头,这意味着我们可以双向移动。
加权图
每条边都有权重或成本的图称为加权图。这个权重可以表示节点之间的任何相对度量。例如,在连通城市图的情况下,边的权重可以表示从一个节点到另一个节点的距离或时间。
表示图
一个图可以用两种方式来表示——使用邻接矩阵或者使用邻接列表。
邻接矩阵
图可以用二阶方阵(二维矩阵)的形式来表示。每行和每列表示节点,矩阵每个单元的值可以是 0 或 1。0 表示两个节点之间不存在边,1 表示存在边。对于加权图,我们可以使用边权重,而不是使用 1。如果图是无向图,矩阵将关于对角线对称。这些矩阵很容易创建,但是空间使用效率很低。
邻接表
邻接表仅仅是一组列表。数组的长度等于节点的数量。为数组中的每个节点维护一个列表,该列表包含与我们的节点直接连接的节点。邻接表使用起来更复杂,但提供了更好的空间效率。
在 Java 中实现图
我们将创建两个类来实现 Java 中的图。一个是简单的顶点或节点类,只有一个名称属性。另一个将被称为图类,它将有一个邻接表来存储图。所有的方法都将被添加到 Graph 类中。
节点类如下所示。它将只包含一个字符串名称属性和一个参数化的构造器。对于更复杂的节点,我们可以向这个类中添加多个字段和方法。
class Node
{
String nodeName;
Node(String name)
{
this.nodeName = name;
}
}
Graph 类将使用邻接表来存储节点和节点之间的连接。我们将使用 HashMap 将每个节点映射到一个节点列表。节点列表将通过使用ArrayList
来存储。在这个类中创建了一个构造器,它将节点列表作为参数,并初始化邻接表。最初,每个节点被映射到一个空的节点ArrayList
。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
class Graph
{
HashMap<Node, ArrayList<Node>> adjList;
Graph(List<Node> list)
{
this.adjList = new HashMap<Node, ArrayList<Node>>();
for(Node n:list)
adjList.put(n, new ArrayList<Node>());
}
}
添加顶点和边
我们可以将想要包含在图中的所有顶点传递给图构造器。接下来,我们需要在这些顶点之间添加边。添加边就像将节点值添加到节点列表中一样简单。
例如,如果我们想在 node1 和 node2 之间创建一条边,那么 node1 的相邻节点列表应该包含 node2 的值,node2 的相邻节点列表应该包含 node1。请记住,我们正在实现一个无向图,因此我们需要向两个节点的列表中添加新条目。
void addEdge(Node node1, Node node2)
{
adjList.get(node1).add(node2);
adjList.get(node2).add(node1);
}
移除边缘
去除边缘也很简单。我们只需要从正确的相邻列表中移除该节点。
例如,如果我们需要删除 node1 和 node2 之间的边,那么 node1 的值应该从 node2 的相邻节点列表中删除,node2 的值应该从 node1 的相邻列表中删除。
import java.util.ArrayList;
void removeEdge(Node node1, Node node2)
{
ArrayList<Node> node1List = adjList.get(node1);
ArrayList<Node> node2List = adjList.get(node2);
node1List.remove(node2);
node2List.remove(node1);
}
使用广度优先搜索遍历图
广度优先搜索将首先遍历起始节点的所有相邻节点,然后进入下一级。我们将使用队列来实现广度优先搜索算法。我们使用队列,因为任何新的节点都应该添加在最后,我们必须首先探索所有的邻居。
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
ArrayList<String> breadthFirstSearch(Node start)
{
ArrayList<Node> visited = new ArrayList<Node>();
Queue<Node> q = new LinkedList<Node>();
q.add(start);
visited.add(start);
while(q.isEmpty() == false)
{
Node currNode = q.poll();
for(Node n : adjList.get(currNode))
if(visited.contains(n) != true)
{
visited.add(n);
q.add(n);
}
}
ArrayList<String> bfs = new ArrayList<String>();
for(Node n : visited)
bfs.add(n.nodeName);
return bfs;
}
使用深度优先搜索遍历图
深度优先搜索在移动到另一个节点之前,尽可能深入地探索一个节点。因为每个新节点都应该首先被探索,所以我们使用一个栈数据结构。
import java.util.ArrayList;
import java.util.Stack;
ArrayList<String> depthFirstSearch(Node start)
{
ArrayList<Node> visited = new ArrayList<Node>();
Stack<Node> stk = new Stack<Node>();
stk.add(start);
while(stk.isEmpty() == false)
{
Node currNode = stk.pop();
if(visited.contains(currNode) != true)
{
visited.add(currNode);
for(Node n : adjList.get(currNode))
stk.push(n);
}
}
ArrayList<String> dfs = new ArrayList<String>();
for(Node n : visited)
dfs.add(n.nodeName);
return dfs;
}
示例:Java 中的图实现
Graph 类的完整代码如下所示。我们添加了一个新的 printAdjList()方法,它打印图的邻接表。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Stack;
class Graph
{
HashMap<Node, ArrayList<Node>> adjList;
Graph(List<Node> list)
{
this.adjList = new HashMap<Node, ArrayList<Node>>();
for(Node n:list)
adjList.put(n, new ArrayList<Node>());
}
void addEdge(Node node1, Node node2)
{
adjList.get(node1).add(node2);
adjList.get(node2).add(node1);
}
void removeEdge(Node node1, Node node2)
{
ArrayList<Node> node1List = adjList.get(node1);
ArrayList<Node> node2List = adjList.get(node2);
node1List.remove(node2);
node2List.remove(node1);
}
ArrayList<String> breadthFirstSearch(Node start)
{
ArrayList<Node> visited = new ArrayList<Node>();
Queue<Node> q = new LinkedList<Node>();
q.add(start);
visited.add(start);
while(q.isEmpty() == false)
{
Node currNode = q.poll();
for(Node n : adjList.get(currNode))
if(visited.contains(n) != true)
{
visited.add(n);
q.add(n);
}
}
ArrayList<String> bfs = new ArrayList<String>();
for(Node n : visited)
bfs.add(n.nodeName);
return bfs;
}
ArrayList<String> depthFirstSearch(Node start)
{
ArrayList<Node> visited = new ArrayList<Node>();
Stack<Node> stk = new Stack<Node>();
stk.add(start);
while(stk.isEmpty() == false)
{
Node currNode = stk.pop();
if(visited.contains(currNode) != true)
{
visited.add(currNode);
for(Node n : adjList.get(currNode))
stk.push(n);
}
}
ArrayList<String> dfs = new ArrayList<String>();
for(Node n : visited)
dfs.add(n.nodeName);
return dfs;
}
void printAdjList()
{
for (Map.Entry mapElement : adjList.entrySet()) {
Node n = (Node)mapElement.getKey();
System.out.print(n.nodeName + "->");
ArrayList<Node> list = adjList.get(n);
for(Node a : list)
System.out.print(a.nodeName + " ");
System.out.println();
}
}
}
让我们尝试一下我们在下图中学到的不同操作。
示例:创建图的邻接表
首先,让我们通过将节点列表传递给图构造器来创建这个图。然后我们可以使用 addEdge()方法来构建节点之间的边。让我们打印邻接表,看看图是否创建正确。
public static void main(String[] args)
{
//creating the nodes
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
Node d = new Node("D");
Node e = new Node("E");
ArrayList<Node> list = new ArrayList<Node>();
list.add(a);
list.add(b);
list.add(c);
list.add(d);
list.add(e);
//Constructing the graphs
Graph g = new Graph(list);
g.addEdge(a, e);
g.addEdge(a, d);
g.addEdge(d, e);
g.addEdge(b, e);
g.addEdge(b, c);
//print the adjacency list
System.out.println("Adjacency List: ");
g.printAdjList();
}
邻接表:
B->E C
D->A E
C->B
E->A D B
A->E D
示例:导线图
现在,让我们使用广度优先和深度优先遍历来遍历这个图。
public static void main(String[] args)
{
//creating the nodes
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
Node d = new Node("D");
Node e = new Node("E");
ArrayList<Node> list = new ArrayList<Node>();
list.add(a);
list.add(b);
list.add(c);
list.add(d);
list.add(e);
//Constructing the graphs
Graph g = new Graph(list);
g.addEdge(a, e);
g.addEdge(a, d);
g.addEdge(d, e);
g.addEdge(b, e);
g.addEdge(b, c);
//print BFS and DFS traversals
System.out.print("Breadth First Traversal starting from A: ");
System.out.println(g.breadthFirstSearch(a));
System.out.print("Depth First Traversal starting from E: ");
System.out.println(g.depthFirstSearch(e));
}
从 A 开始的广度优先遍历:[A,E,D,B,C]
从 E 开始的深度优先遍历:[E,B,C,D,A]
示例:删除图边
让我们删除图的几条边,然后查看邻接表。
public static void main(String[] args)
{
//creating the nodes
Node a = new Node("A");
Node b = new Node("B");
Node c = new Node("C");
Node d = new Node("D");
Node e = new Node("E");
ArrayList<Node> list = new ArrayList<Node>();
list.add(a);
list.add(b);
list.add(c);
list.add(d);
list.add(e);
//Constructing the graphs
Graph g = new Graph(list);
g.addEdge(a, e);
g.addEdge(a, d);
g.addEdge(d, e);
g.addEdge(b, e);
g.addEdge(b, c);
//Deleting edges
g.removeEdge(a, e);
g.removeEdge(b, c);
g.printAdjList();
}
B->E
D->A E
C->T3】E->D B
A->D
摘要
图是一种非常重要的数据结构,用于通过边存储节点和节点之间的关系。在本教程中,我们学习了图的基础知识以及图是如何存储和表示的。我们还学习了如何在 Java 中实现一个图,以及如何对它执行各种操作。
Java 中的偶对
顾名思义,偶对是存储偶对数据的一种方式。偶对数据由两个字段组成——一个用于键,另一个用于值。偶对是从一个方法返回多个值的好方法。在本教程中,我们将学习在 Java 中使用对的不同方法。
使用 javafx.util 包的偶对类
javafx.util
包有一个方便的 Pair 类,可以用来处理 Pair。我们可以使用以下语法初始化这个类的对象。
Pair<Key Type, Value Type> pairName = new Pair<>(key, value);
这个类提供了 getKey() 和 getValue() 方法从这对中获取数据。下面的代码显示了这些方法的工作原理。
import javafx.util.Pair;
public class PairsInJava
{
public static void main(String[] args)
{
Pair<String, Double> studentNameGPAPair1 = new Pair<>("Justin", 8.76);
Pair<String, Double> studentNameGPAPair2 = new Pair<>("Jessica", 8.76);
System.out.println("The Pair is: " + studentNameGPAPair1.toString());
System.out.println("The Key is: " + studentNameGPAPair1.getKey());
System.out.println("The Value is: " + studentNameGPAPair1.getValue());
}
}
这对是:贾斯汀=8.76
关键是:贾斯汀
数值是:8.76
使用抽象映射。简单入口类
Java 中的AbstractMap.SimpleEntry
类可以用来创建一对。与javafx.util
的 Pair 类不同,该类提供了 setValue() 方法,可用于更改 Pair 的值。但是,我们不能修改密钥。
import java.util.AbstractMap;
public class PairsInJava
{
public static void main(String[] args)
{
AbstractMap.SimpleEntry<String, Double> pair = new AbstractMap.SimpleEntry<>("Justin", 8.78);
System.out.println("Key = " + pair.getKey() + " Value = " + pair.getValue());
pair.setValue(8.8);
System.out.println("Key = " + pair.getKey() + " Updated Value = " + pair.getValue());
}
}
键=贾斯汀值= 8.78
键=贾斯汀更新值= 8.8
使用抽象映射。simpleimumplaceenttry
SimpleImmutatedEntry
班和SimpleEntry
班非常相似。唯一不同的是这个类的对象是不变的。我们不能在这个课堂上使用setValue()
方法。如果我们使用这种方法,我们会得到一个**UnsupportedOperationException**
。
在下面的代码中,前两行执行,但是当我们试图修改该值时,我们得到一个错误。
import java.util.AbstractMap;
public class PairsInJava
{
public static void main(String[] args)
{
AbstractMap.SimpleImmutableEntry<String, Double> pair = new AbstractMap.SimpleImmutableEntry<>("Justin", 8.78);
System.out.println("Key = " + pair.getKey() + " Value = " + pair.getValue());
pair.setValue(8.8);//error
}
}
Key = Justin Value = 8.78
线程“main”Java . lang . unsupportedoperationexception
处的异常
使用阿帕奇公共图书馆
阿帕奇公共图书馆为我们提供了一个 MutablePair
类和一个 ImmutablePair
类。这两个类都有标准的 getter 方法来获取键和值对。
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.MutablePair;
public class PairsInJava
{
public static void main(String[] args)
{
MutablePair<String, Double> studentNameGPAPair1 = new MutablePair<>("Justin", 8.76);
ImmutablePair<String, Double> studentNameGPAPair2 = new ImmutablePair<>("Jessica", 8.13);
System.out.println("The MutablePair Key is: " + studentNameGPAPair1.getKey());
System.out.println("The MutablePair Value is: " + studentNameGPAPair1.getValue());
System.out.println("The ImmutablePair Key is: " + studentNameGPAPair2.getKey());
System.out.println("The ImmutablePair Value is: " + studentNameGPAPair2.getValue());
}
}
可变空气键为:贾斯汀
可变空气值为:8.76
不变空气键为:杰西卡
不变空气值为:8.13
ImmutablePair
类没有 setter 方法,因为它创建了一个不可变的对,创建后不能修改。但是我们有**setLeft()**
和**setRight()**
方法给MutablePair
类。setLeft()
方法设置左元素或键对。setRight()方法设置右元素或对的值。
import org.apache.commons.lang3.tuple.MutablePair;
public class PairsInJava
{
public static void main(String[] args)
{
MutablePair<String, Double> studentNameGPAPair = new MutablePair<>("Justin", 8.76);
System.out.println("Pair before using setters: " + studentNameGPAPair.toString());
studentNameGPAPair.setLeft("Jessica");
studentNameGPAPair.setRight(8.13);
System.out.println("Pair After using setters: " + studentNameGPAPair.toString());
}
}
使用沉降片前偶对:(贾斯汀,8.76)
使用沉降片后偶对:(杰西卡,8.13)
使用 javatuples 偶对类
javatuples 库提供了不同的类来实现 Java 中的不可变元组。这个库的 Pair 类可以用来创建两个元素的元组。我们有 getValue() 和 getValueX() 方法(其中 X 表示索引)来按索引获取对元素。我们通常将键存储在索引 0 处,将值存储在索引 1 处。我们需要使用 getValue()方法进行强制转换。
import org.javatuples.Pair;
public class PairDemo
{
public static void main(String[] args)
{
Pair<String, Double> studentNameGPAPair1 = Pair.with("Justin", 8.76);
Pair<String, Double> studentNameGPAPair2 = Pair.with("Jessica", 8.13);
String key1 = studentNameGPAPair1.getValue0();
Double value1 = studentNameGPAPair1.getValue1();
//casting
String key2 = (String) studentNameGPAPair2.getValue(0);
Double value2 = (Double) studentNameGPAPair2.getValue(1);
System.out.println("Key-1 " + key1 + " Value-1 " + value1);
System.out.println("Key-2 " + key2 + " Value-2 " + value2);
}
}
键-1 贾斯汀值-1 8.76
键-2 杰西卡值-2 8.13
我们还有一个setAtX()
方法,它不会改变原来的偶对,但会返回一个有变化的新偶对。
import org.javatuples.Pair;
public class PairDemo
{
public static void main(String[] args)
{
Pair<String, Double> studentNameGPAPair1 = Pair.with("Justin", 8.76);
Pair<String, Double> studentNameGPAPair2 = studentNameGPAPair1.setAt1(8.80);
System.out.println("Original Pair: " + studentNameGPAPair1);
System.out.println("Modified Pair: " + studentNameGPAPair2);
}
}
原始对:[贾斯汀,8.76]
修改对:[贾斯汀,8.8]
使用虚拟图书馆的 Tuple2 类
Vavr 库的 Tuple2 类可以用来创建一个不可变的对。我们可以使用 _1() 方法获取密钥。同样,可以使用 _2() 方法从该对中获取值。
import io.vavr.Tuple2;
public class PairsInJava
{
public static void main(String[] args)
{
Tuple2<String, Double> studentNameGPA = new Tuple2<>("Justin", 8.78);
String key = studentNameGPA._1();
Double value = studentNameGPA._2();
System.out.println("Key = " + key);
System.out.println("Value = " + value);
}
}
键=贾斯汀
值= 8.78
我们还有 update1() 和 update2() 方法,它们用更新返回一个新的 tuple2 对象。请注意,这些方法不会改变原始对。
import io.vavr.Tuple2;
public class PairsInJava
{
public static void main(String[] args)
{
Tuple2<String, Double> studentNameGPA1 = new Tuple2<>("Justin", 8.78);
Tuple2<String, Double> studentNameGPA2 = studentNameGPA1.update2(8.80);
System.out.println("Original pair: " + studentNameGPA1);
System.out.println("Modified pair: " + studentNameGPA2);
}
}
原始对:(贾斯汀,8.78)
修改对:(贾斯汀,8.8)
用户定义的偶对类
如果我们不想使用外部库,那么我们可以实现自己的自定义类来创建对。它将有两个所需数据类型的成员变量。我们还将添加 getter 和 setter 方法。我们可以根据自己的需求创建额外的方法。
class Pair
{
private String name;
private Double gpa;
Pair(String name, Double gpa)
{
this.name = name;
this.gpa = gpa;
}
public String getKey()
{
return name;
}
public void setKey(String name)
{
this.name = name;
}
public Double getValue()
{
return gpa;
}
public void setValue(Double gpa)
{
this.gpa = gpa;
}
}
public class PairsInJava
{
public static void main(String[] args)
{
Pair studentNameGPA = new Pair("Justin", 8.76);
System.out.println("Key: " + studentNameGPA.getKey());
System.out.println("Value: " + studentNameGPA.getValue());
studentNameGPA.setValue(8.80);
System.out.println("New Value: " + studentNameGPA.getValue());
}
}
键:贾斯汀
值:8.76
新值:8.8
用对象数组在 Java 中创建对
外部库的另一种替代方法是使用对象数组。因为所有类都扩展了对象类,所以我们可以很容易地在这个数组中存储任何类对象。
public class PairsInJava
{
public static void main(String[] args)
{
String key = "Justin";
Double value = 8.78;
Object[] objArr = new Object[2];
objArr[0] = key;
objArr[1] = value;
System.out.println("Key = " + objArr[0]);
System.out.println("Value = " + objArr[1]);
}
}
键=贾斯汀
值= 8.78
摘要
对是存储两个数据项的一种简单方法,这两个数据项之间有一个映射。偶对通常存储一个键及其相应的值。在 Java 中有很多使用 Pairs 的方法。我们可以使用外部库,如 Apache Commons 或 Vavr 库来实现对。我们还可以定义自己的 pair 类,它可以有额外的方法来满足我们的需求。
Java 中的排序
原文:https://www.studytonight.com/java-examples/sorting-in-java
排序是一种非常常见的操作,Java 提供了不同的内置方法,可以用来对不同的数据结构进行排序。本教程将解释如何在 Java 中对数组、集合和用户定义的类实例进行排序。
Java 中的数组排序
数组是一种简单的数据结构,用于以有序的方式存储相似类型的数据。Arrays 类的 sort() 方法可用于对整个数组或数组的一部分进行排序。在内部,该方法使用双轴快速排序算法对原始数据类型进行排序。对于对象数组,它使用归并排序算法。
public static void main(String[] args)
{
int[] arrToSort = {7, 9, 1, 0, 2, 5, 6, 11};
System.out.println("Array Before Sorting: " + Arrays.toString(arrToSort));
Arrays.sort(arrToSort);
System.out.println("Array After Sorting: " + Arrays.toString(arrToSort));
}
排序前的数组:[7,9,1,0,2,5,6,11]
排序后的数组:[0,1,2,5,6,7,9,11]
我们可以向 Arrays.sort()方法传递一个开始索引和一个结束索引,只对数组的一部分进行排序。由索引定义的范围是排他的(不包括结束索引元素)。
public static void main(String[] args)
{
//Sorting the left half of an Array
int[] arrToSort = {7, 9, 1, 0, 2, 6, 11, 5, -1, 20};
System.out.println("Array Before Sorting: " + Arrays.toString(arrToSort));
int from = 0;
int to = arrToSort.length / 2;
Arrays.sort(arrToSort, from, to);
System.out.println("Array After Sorting: " + Arrays.toString(arrToSort));
}
排序前的数组:[7,9,1,0,2,6,11,5,-1,20]
排序后的数组:[0,1,2,7,9,6,11,5,-1,20]
Java 8 有一个新的parallels art()方法,使用多线程来同时对数组的不同部分进行排序。这种方法首先将数组分成较小的数组,然后不同的线程对这些较小的数组进行并行排序。然后它们被合并回一个单独的排序数组。就像 Arrays.sort()方法一样,我们可以使用 parallelSort()对数组的一部分进行排序。
public static void main(String[] args)
{
//Sorting using parallel sort
int[] arrToSort = {7, 9, 1, 0, 2, 5, 6, 11};
System.out.println("Array Before Sorting: " + Arrays.toString(arrToSort));
Arrays.parallelSort(arrToSort);
System.out.println("Array After Sorting: " + Arrays.toString(arrToSort));
}
排序前的数组:[7,9,1,0,2,5,6,11]
排序后的数组:[0,1,2,5,6,7,9,11]
在 Java 中对集合进行排序
Java 中的 Collections 框架提供了多种数据结构来存储和操作数据。列表、集合和映射是最常用的集合。在本节中,我们将学习如何对这些集合进行排序。
排序列表
集合框架提供了一种对列表进行排序的 Collections.sort() 方法。该方法还可以将Comparator
作为参数,并相应地对列表进行排序。
public static void main(String[] args)
{
//Sorting Lists
List<Integer> listToSort = new ArrayList<Integer>();
listToSort.add(7);
listToSort.add(9);
listToSort.add(0);
listToSort.add(1);
listToSort.add(-1);
System.out.println("List Before Sorting: " + listToSort);
Collections.sort(listToSort);
System.out.println("List After Sorting: " + listToSort);
}
排序前列表:[7,9,0,1,-1]
排序后列表:[-1,0,1,7,9]
我们可以使用collections . reverse order()方法对列表进行降序排序。这个方法返回一个Comparator
对象,我们可以将其传递给 Collections.sort()方法。
public static void main(String[] args)
{
//Sorting lists in reverse order
List<Integer> listToSort = new ArrayList<Integer>();
listToSort.add(7);
listToSort.add(9);
listToSort.add(0);
listToSort.add(1);
listToSort.add(-1);
System.out.println("List Before Sorting: " + listToSort);
Collections.sort(listToSort, Collections.reverseOrder());
System.out.println("List After Sorting in descending order: " + listToSort);
}
排序前列表:[7,9,0,1,-1]
排序后列表按降序排列:[9,7,1,0,-1]
排序集
集合用于存储无重复的无序数据。与列表不同,我们没有为集合定义 sort()方法。HashSet 类不维护插入顺序,所以我们不能直接排序。但是我们可以通过将Hashtable
的所有元素转移到一个列表中,然后对列表进行排序来查看排序后的值。
public static void main(String[] args)
{
//Sorting Sets using lists
HashSet<Integer> setToSort = new HashSet<Integer>();
setToSort.add(7);
setToSort.add(9);
setToSort.add(0);
setToSort.add(1);
setToSort.add(-1);
System.out.println("Set Before Sorting: " + setToSort);
ArrayList<Integer> listOfSet = new ArrayList<Integer>(setToSort);
Collections.sort(listOfSet);
System.out.println("Sorted Values of the Set: " + listOfSet);
}
排序前设置:[0,-1,1,7,9]
集合的排序值:[-1,0,1,7,9]
同样的方法也可以用于 LinkedHashSet。LinkedHashSet 维护元素的插入顺序,排序后的值可以存储回其中。
public static void main(String[] args)
{
//Sorting Sets using lists
LinkedHashSet<Integer> setToSort = new LinkedHashSet<Integer>();
setToSort.add(7);
setToSort.add(9);
setToSort.add(0);
setToSort.add(1);
setToSort.add(-1);
System.out.println("Set Before Sorting: " + setToSort);
ArrayList<Integer> listOfSet = new ArrayList<Integer>(setToSort);
Collections.sort(listOfSet);
//Transferring sorted values to the set
setToSort = new LinkedHashSet<Integer>();
for(Integer i : listOfSet)
{
setToSort.add(i);
}
System.out.println("Set After Sorting: " + setToSort);
}
排序前设置:【7,9,0,1,-1】
排序后设置:【-1,0,1,7,9】
TreeSet 按排序顺序存储元素。因此,我们可以将一个 HashSet 或 LinkedHashSet 转换为一个 TreeSet,并查看排序后的值。
public static void main(String[] args)
{
//Sorting Sets using TreeSets
HashSet<Integer> setToSort = new HashSet<Integer>();
setToSort.add(7);
setToSort.add(9);
setToSort.add(0);
setToSort.add(1);
setToSort.add(-1);
System.out.println("Set Before Sorting: " + setToSort);
TreeSet<Integer> sortedSet = new TreeSet<Integer>(setToSort);
System.out.println("Set After Sorting: " + sortedSet);
}
排序前设置:[0,-1,1,7,9]
排序后设置:[-1,0,1,7,9]
SortedMap
映射用于存储一系列键值对。就像集合一样,我们没有任何内置的映射排序()方法。我们可以根据关键字或值对映射进行排序。让我们学习如何按键和值对映射进行排序。
按关键字对映射进行排序
HashMaps 和 HashSets 一样,不维护插入顺序。我们仍然可以在列表的帮助下查看排序后的数据。我们将把Hashtable
的键转移到一个ArrayList
中,然后我们将对这个列表进行排序。我们可以通过使用映射的 get() 方法来获取排序关键字的值。
public static void main(String[] args)
{
//Sorting Map by Keys using Lists
HashMap<Integer, String> mapToSort = new HashMap<Integer, String>();
mapToSort.put(3, "Jessica");
mapToSort.put(112, "Victor");
mapToSort.put(15, "Harry");
mapToSort.put(104, "Simon");
mapToSort.put(21, "Justin");
System.out.println("Map before sorting: ");
for(Map.Entry<Integer, String> e : mapToSort.entrySet())
System.out.println(e.getKey() + " " + e.getValue());
ArrayList<Integer> sortedKeys = new ArrayList<Integer>(mapToSort.keySet());
Collections.sort(sortedKeys);
System.out.println("\nMap After sorting: ");
for(Integer i : sortedKeys)
System.out.println(i + " " + mapToSort.get(i));
}
排序前映射:
112 维克多
3 杰西卡
21 贾斯汀
104 西蒙
15 哈利
T7】排序后映射:
3 杰西卡
15 哈利
21 贾斯汀
104 西蒙
112 维克多
我们还可以创建一个新的 LinkedHashMap,并将排序后的键和相应的值添加到其中。LinkedHashMap 维护插入顺序。
public static void main(String[] args)
{
HashMap<Integer, String> mapToSort = new HashMap<Integer, String>();
mapToSort.put(3, "Jessica");
mapToSort.put(112, "Victor");
mapToSort.put(15, "Harry");
mapToSort.put(104, "Simon");
mapToSort.put(21, "Justin");
System.out.println("Map before sorting: ");
for(Map.Entry<Integer, String> e : mapToSort.entrySet())
System.out.println(e.getKey() + " " + e.getValue());
ArrayList<Integer> sortedKeys = new ArrayList<Integer>(mapToSort.keySet());
Collections.sort(sortedKeys);
//Creating a new LinkedHashMap
LinkedHashMap<Integer, String> sortedMap = new LinkedHashMap<Integer, String>();
for(Integer i : sortedKeys)
sortedMap.put(i, mapToSort.get(i));
System.out.println("\nThe Sorted Map is:");
for(Map.Entry<Integer, String> e : sortedMap.entrySet())
System.out.println(e.getKey() + " " + e.getValue());
}
排序前的映射:
112 维克多
3 杰西卡
21 贾斯汀
104 西蒙
15 哈利
T7【排序后的映射是:
3 杰西卡
15 哈利
21 贾斯汀
104 西蒙
112 维克多
另一种按键排序映射的简单方法是使用树形映射。默认情况下,TreeMap
按排序顺序存储键值对。
public static void main(String[] args)
{
//Sorting Map by Keys using TreeMap
HashMap<Integer, String> mapToSort = new HashMap<Integer, String>();
mapToSort.put(3, "Jessica");
mapToSort.put(112, "Victor");
mapToSort.put(15, "Harry");
mapToSort.put(104, "Simon");
mapToSort.put(21, "Justin");
System.out.println("Map before sorting: ");
for(Map.Entry<Integer, String> e : mapToSort.entrySet())
System.out.println(e.getKey() + " " + e.getValue());
TreeMap<Integer, String> sortedMap = new TreeMap<Integer, String>();
sortedMap.putAll(mapToSort);
System.out.println("\nSorted TreeMap: ");
for(Map.Entry<Integer, String> e : sortedMap.entrySet())
System.out.println(e.getKey() + " " + e.getValue());
}
排序前的映射:
112 维克多
3 杰西卡
21 贾斯汀
104 西蒙
15 哈利
T7】排序后的树形映射:
3 杰西卡
15 哈利
21 贾斯汀
104 西蒙
112 维克多
按值排序映射
根据值对映射进行排序有点困难。我们将创建一个实现Comparator
接口的类。接下来,我们将在其中定义一个 compare()方法。这个类的代码如下所示。
class CompareMapValue implements Comparator<Map.Entry<Integer, String>>
{
@Override
public int compare(Entry<Integer, String> o1, Entry<Integer, String> o2)
{
String val1 = o1.getValue();
String val2 = o2.getValue();
return val1.compareTo(val2);
}
}
接下来,我们将创建一个包含所有键值对的ArrayList
,并使用 Collections.sort()方法对它们进行排序。我们将把先前定义的类的一个对象传递给 sort()方法。我们还可以使用 LinkedHashMap 来存储排序后的值。在我们的代码中,我们刚刚打印了排序后的值。
public static void main(String[] args)
{
//Sorting map by values
HashMap<Integer, String> mapToSort = new HashMap<Integer, String>();
mapToSort.put(3, "Jessica");
mapToSort.put(112, "Victor");
mapToSort.put(15, "Harry");
mapToSort.put(104, "Simon");
mapToSort.put(21, "Justin");
System.out.println("Map before sorting: ");
for(Map.Entry<Integer, String> e : mapToSort.entrySet())
System.out.println(e.getKey() + " " + e.getValue());
ArrayList<Map.Entry<Integer, String>> list = new ArrayList<>(mapToSort.entrySet());
CompareMapValue c = new CompareMapValue();
Collections.sort(list, c);
System.out.println("\nSorted Values: ");
for (Map.Entry<Integer, String> e : list)
{
System.out.println(e.getKey() + " " + e.getValue());
}
}
排序前的映射:
112 维克多
3 杰西卡
21 贾斯汀
104 西蒙
15 哈利
T7】排序后的值:
15 哈利
3 杰西卡
21 贾斯汀
104 西蒙
112 维克多
对用户定义的类对象进行排序
我们可以通过使用 Comparable 和 Comparator 接口对用户定义的类对象进行排序。请参考我们关于Comparator
和Comparator
的文章,了解如何使用它们。
要使用Comparator
,我们需要创建一个单独的类,但是 Java 8 为我们提供了 Lambda 表达式,可以用来更有效地实现Comparator
。假设我们需要以相反的顺序对整数数组进行排序。我们可以创建一个实现 Comparator 接口并覆盖 compare()方法的类,如下所示。
class CompareReverse implements Comparator<Integer>
{
@Override
public int compare(Integer o1, Integer o2) {
return -o1.compareTo(o2);
}
}
或者我们可以编写下面的 Lambda 表达式来做同样的事情。
Comparator<Integer> c = (x, y) -> -(Integer.compare(x, y));
两者给出的输出是一样的。
public static void main(String[] args)
{
Integer[] arr = {4, 9, 1, -1, 0, 5};
List<Integer> arrList1 = Arrays.asList(arr);
List<Integer> arrList2 = Arrays.asList(arr);
CompareReverse c1 = new CompareReverse();
Comparator<Integer> c2 = (x, y) -> -(Integer.compare(x, y));
Collections.sort(arrList1, c1);
Collections.sort(arrList2, c2);
System.out.println(arrList1);
System.out.println(arrList2);
}
【9,5,4,1,0,-1】
【9,5,4,1,0,-1】
使用比较()和比较()方法
comparing()和 then comparison()方法也是使用Comparator
对用户定义的类实例进行排序的好方法。考虑一个以姓名和平均绩点为属性的学生班级。
class Student
{
String name;
Double gpa;
Student(String name, Double gpa)
{
this.name = name;
this.gpa = gpa;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getGpa() {
return gpa;
}
public void setGpa(Double gpa) {
this.gpa = gpa;
}
}
如果我们希望根据学生的平均成绩对他们进行排序,那么我们可以使用 comparing()方法,如下所示。
public static void main(String[] args)
{
ArrayList<Student> listOfStudents = new ArrayList<Student>();
listOfStudents.add(new Student("Rachel", 8.08));
listOfStudents.add(new Student("Justin", 8.08));
listOfStudents.add(new Student("Clay", 9.75));
listOfStudents.add(new Student("Austin", 9.75));
listOfStudents.add(new Student("Chloe", 9.33));
Comparator<Student> c = Comparator.comparing(Student :: getGpa);
Collections.sort(listOfStudents, c);
for(Student s : listOfStudents)
System.out.println(s.getName() + " " + s.getGpa());
}
瑞秋 8.08
贾斯汀 8.08
克洛伊 9.33
克莱 9.75
奥斯汀 9.75
让我们先按学生姓名,然后按学生的 GPA 对上面的数组进行排序。我们可以使用 then comparing()方法和 comparising()方法来实现这一点。这个场景的代码如下所示。确保定义适当的吸气剂与这些方法一起使用。
public static void main(String[] args)
{
ArrayList<Student> listOfStudents = new ArrayList<Student>();
listOfStudents.add(new Student("Rachel", 8.08));
listOfStudents.add(new Student("Justin", 8.08));
listOfStudents.add(new Student("Clay", 9.75));
listOfStudents.add(new Student("Austin", 9.75));
listOfStudents.add(new Student("Chloe", 9.33));
Comparator<Student> c = Comparator.comparing(Student :: getGpa).thenComparing(Student :: getName);
Collections.sort(listOfStudents, c);
for(Student s : listOfStudents)
System.out.println(s.getName() + " " + s.getGpa());
}
贾斯汀 8.08
瑞秋 8.08
克洛伊 9.33
奥斯汀 9.75
克莱 9.75
摘要
本教程解释了如何在 Java 中对不同的数据结构(如数组、列表、集合和映射)进行排序。可以使用 Arrays.sort()方法对数组进行排序。如果我们有一个更大的数组,那么建议使用 parallelSort(),因为它比普通的 Sort()方法更有效。集合框架为列表接口提供了一个 sort()方法。我们还可以使用列表对集合和映射进行排序。TreeSet 也可以用来按排序顺序存储值。同样,TreeMap
也可以用来对映射进行排序。
Java 中的三元运算符
原文:https://www.studytonight.com/java-examples/ternary-operator-in-java
条件语句用于检查条件是真还是假,并根据结果决定下一步。Java 中的三元运算符用于替换条件语句。它们之所以这样叫,是因为它们对三个操作数进行运算。它们提供了更清晰的和更易读的代码,我们可以在一行代码中编写 if-else 逻辑。让我们学习一下如何在 Java 中使用三元运算符。****
三元运算符使用问号(?)和冒号(😃**分隔条件和将根据条件结果评估的表达式。三元运算符的一般语法如下所示。
如果条件评估为真,那么表达式 1 将被执行,否则表达式 2 将被执行。上述逻辑可以使用 if-else 语句编写,如下所示。
if(condition)
variable = expression1;
else
variable = expression2;
这里需要注意的一点是表达式必须返回值。我们不能使用返回空值的方法。考虑下面的 if-else 代码。
public static void main(String args[])
{
if (10 > 5)
System.out.print("True");
else
System.out.print("False");
}
真
我们不能用三元运算符做同样的事情。下面使用三元运算符编写的代码将返回一个错误。
public static void main(String args[])
{
(10 > 5) ? System.out.print("True"): System.out.print("False");
}
示例:Java 中的三元运算符
让我们有两个变量,一个是 int 数据类型,另一个是 String 数据类型。如果整数等于 10,那么字符串的值应该是十,否则应该是而不是十。
使用三元运算符的 Java 代码可以写成如下所示。
public static void main(String args[])
{
int i = 11;
String s;
s = (i == 10) ? "ten" : "not ten";
System.out.print(s);
}
不是十点
示例:Java 中的嵌套三元运算符
像嵌套的 if-else 一样,三元运算符也可以嵌套。在这里,我们试图根据一个学生的分数来找到他的分数。如果他的分数大于 90,那么成绩就是 A,如果分数在 50 到 90 之间,那么成绩就是 B,否则成绩就是 c。
下面的 Java 代码正在实现嵌套三元运算符。
public static void main(String args[])
{
int marks = 65;
char grade;
grade = (marks >= 90) ? 'A' : (marks < 90 && marks >= 50) ? 'B' : 'C';
System.out.print(grade);
}
B
为了更好的可读性,我们还可以用下面的格式编写上面的代码。
public static void main(String args[])
{
int marks = 65;
char grade;
grade = (marks >= 90) ? 'A'
:(marks < 90 && marks >= 50) ? 'B'
:'C';
System.out.print(grade);
}
B
摘要
三元运算符用于在单行中编写 if-else 条件语句。它们可以使我们的代码更简洁,也更容易理解。然而,对于嵌套的 if-else 语句和 if-else if-else 语句,三元运算符可能很难理解。它们应该主要用于替换简单的 if-else 语句。
如何在 Java 中读取 CSV 文件
原文:https://www.studytonight.com/java-examples/how-to-read-a-csv-file-in-java
在这篇文章中,我们将使用 Java 代码读取一个 CSV 文件。CSV 是一个逗号分隔的文件,用于存储数据。
我们可以通过几种方式读取 CSV 文件,例如使用 Scanner 类或第三方提供的OpenCSV
库。你可以在这里下载 opencsv 的 JAR 文件。
在这里,我们有两个例子来理解 Java 中 CSV 文件的读取过程。
我们有一个示例 CSV 文件 students.csv ,用于从 Java 中读取数据。
//学生. csv
101,'Rohan','India'
102,'Kumar','SriLanka'
103,'David','USA'
举例时间:
让我们创建一个读取 CSV 文件的示例。在这里,我们使用 OpenCSV 库和CSVReader
类来读取文件。该库对于 CSV 文件处理非常有用。
import com.opencsv.*;
import java.io.FileReader;
import java.io.IOException;
public class Main {
public static void main(String[] args){
String csvFile = "students.csv";
CSVReader csvReader = null;
try {
csvReader = new CSVReader(new FileReader(csvFile));
String[] value;
while ((value = csvReader.readNext()) != null) {
System.out.println(value[0] + " " + value[1] + " " + value[2]);
}
} catch (IOException e) {
System.out.println(e);
}
}
}
101“罗汉”“印度”
102“库马尔”“斯里兰卡”
103“大卫”“美国”
另一个例子的时间:
但是,还有另一种读取 CSV 文件的方法,使用Scanner
类,该类用于从文件或输入资源中读取输入。这里,我们使用 Scanner 类和useDelimeter()
方法来指定值分隔符。
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException{
//Reading file using scanner
Scanner scanner = new Scanner(new File("students.csv"));
//Comma as a delimiter
scanner.useDelimiter(",");
while (scanner.hasNext())
{
System.out.print(scanner.next() + " ");
}
// Closing the scanner
scanner.close();
}
}
101“罗汉”“印度”
102“库马尔”“斯里兰卡”
103“大卫”“美国”
如何从ArrayList
中删除重复项
原文:https://www.studytonight.com/java-examples/how-to-remove-duplicates-from-arraylist
在这篇文章中,我们将从 Java 中的ArrayList
中移除重复的元素。ArrayList
是集合框架中 List 接口的实现类,用于存储数据的类。
由于ArrayList
允许我们存储重复的元素,因此有时我们需要从ArrayList
中获取唯一的元素,然后我们必须删除重复的元素。
要删除重复项,有一个简单易行的方法,只需将ArrayList
转换为HashSet
,即可获得唯一的元素。因为 HashSet 只存储唯一的元素。它会自动删除所有重复项。
因此,为了消除重复,我们使用了两种方法,一种是转换为 HashSet,另一种是使用 stream 的 distinct()方法,该方法从流中返回唯一的元素。请看例子。
举例时间:
让我们创建一个从ArrayList
中删除所有重复项的例子。在这里,我们使用 HashSet 并将 Arraylist 作为 n 参数传递给它的构造器。它返回一个唯一的集合,但是我们需要一个ArrayList
,所以通过将它传递给ArrayList
构造器,将其转换回ArrayList
。
import java.util.ArrayList;
import java.util.HashSet;
public class Main {
public static void main(String[] args){
ArrayList<Integer> arrList1 = new ArrayList<>();
arrList1.add(1030);
arrList1.add(1020);
arrList1.add(1010);
arrList1.add(1030);
System.out.println(arrList1);
// Remove duplicates
HashSet<Integer> set = new HashSet<Integer>(arrList1);
// Convert back to ArrayList
arrList1 = new ArrayList<Integer>(set);
System.out.println(arrList1);
}
}
【1030,1020,1010,1030】
【1010,1030,1020】
示例:
如果你不想把ArrayList
转换成HashSet
,那么你可以使用另一种方法蒸汽 API。流提供了一个distinct()
方法,从流中删除重复项,toList()
方法返回一个唯一元素的列表。
import java.util.ArrayList;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args){
ArrayList<Integer> arrList1 = new ArrayList<>();
arrList1.add(1030);
arrList1.add(1020);
arrList1.add(1010);
arrList1.add(1030);
System.out.println(arrList1);
// Remove duplicates
arrList1 = (ArrayList<Integer>)arrList1.stream().distinct().collect(Collectors.toList());
System.out.println(arrList1);
}
}
【1030,1020,1010,1030】
【1030,1020,1010】
如何在 Java 中把long
转换成字符串
原文:https://www.studytonight.com/java-examples/how-to-convert-long-to-string-in-java
在这篇文章中,我们将在 Java 中将 long 转换为字符串。long 是 Java 数据类型之一,用于存储大范围的数值,而 String 是字符序列。
要将Long
类型转换为字符串,可以使用 string 类的valueOf()
方法或 Long 类的toString()
方法。Long 是 Java 中用于处理Long
类型对象的包装类。
String 类的 valueOf()方法用于从 long 获取字符串。它接受一个参数并返回一个指定类型的字符串。
Long 类的 toString()方法返回一个Long
类型值的字符串。
我们还使用了加号(+)运算符将 long 转换为 string,因为该运算符用于连接两个对象并返回一个字符串。
举例时间:
让我们举个例子把 long 转换成 string。这里,我们使用的是返回字符串的 String 类的valueOf()
方法。
public class Main {
public static void main(String[] args){
long val = 210;
System.out.println(val);
// long to String
String str = String.valueOf(val);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
210
210
Java 岛
示例:
让我们再举一个例子,从Long
类型中获取一个字符串。这里,我们使用 long 类的toString()
方法,通过转换 Long 返回一个字符串。
public class Main {
public static void main(String[] args){
long val = 210;
System.out.println(val);
// long to String
String str = Long.toString(val);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
210
210
Java 岛
示例:
在本例中,我们使用加号(+)运算符将长值与字符串值连接起来。加号运算符在连接后返回一个字符串值。
public class Main {
public static void main(String[] args){
long val = 210;
System.out.println(val);
// long to String
String str = ""+val;
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
210
210
Java 岛
如何从 Java 映射中移除元素
原文:https://www.studytonight.com/java-examples/how-to-remove-element-from-a-java-map
在本教程中,我们将学习如何从 Java 映射中移除元素。在 Java 中,映射是一个接口,也是 Java Collection 框架的一部分。它用于将元素收集到键和值对中。
从 Java 映射中移除元素的示例
要修改 Java Map 中的元素,我们有两个函数remove()
和replace().
在下面的代码片段中,我们在 Map 上使用 remove()方法,它将从给定的键元素中返回一个删除的值。在我们的例子中,它将返回 68。
Map.remove(Key);
移除元素并返回相应的值。
import java.util.*;
public class StudyTonight
{
public static void main(String args[])
{
Map<String,Integer> map = new HashMap<>();
map.put("A", 65);
map.put("B", 66);
map.put("C", 67);
map.put("D", 68);
map.put("E", 69);
// removing
int result = map.remove("D");
System.out.println("Removed Element is : "+result);
}
}
移除元素为:68
从 Java 映射中移除元素的示例
在给定的示例中,我们调用了Map.remove()
方法,该方法与我们在第一个示例中所做的略有不同。
如果在函数中传递的元素的键和值存在于映射中,并且此方法将移除该元素,则返回 true。但是如果相应的值不存在,并且唯一的键存在,那么它也将返回 false。
remove(Key, Value);
当且仅当键和值都存在于映射中时,它移除元素并返回真,否则它将返回假。
import java.util.*;
public class StudyTonight
{
public static void main(String args[])
{
Map<String,Integer> map = new HashMap<>();
map.put("A", 65);
map.put("B", 66);
map.put("C", 67);
map.put("D", 68);
map.put("E", 69);
System.out.println(map.remove("D", 68));
}
}
真
如果我们只关心在这种情况下从映射中添加和移除元素等操作所需的时间,我们可以使用Map.replace(Key,Value);
直接执行替换操作
从映射中替换元素的示例
在本例中Map.replace();
方法将替换旧值“D”,即 68 到 90。您可以从下面的输出中清楚地验证这一点。当我们想要在移除操作后向映射添加新成员时,此操作非常有用。
import java.util.*;
public class StudyTonight
{
public static void main(String args[])
{
Map<String,Integer> map = new HashMap<>();
map.put("A", 65);
map.put("B", 66);
map.put("C", 67);
map.put("D", 68);
map.put("E", 69);
// replace
map.replace("D", 90);
System.out.println(map);
}
}
{A=65,B=66,C=69,D=90}
从映射中替换元素的Map.replace(Key, oldValue, newValue)
示例
在本例中,如果映射元素已经存在,我们将替换它的现有值。这就是为什么我们提到参数名为旧值和新值。
import java.util.*;
public class StudyTonight
{
public static void main(String args[])
{
Map<String,Integer> dictionary = new HashMap<>();
dictionary.put("A", 65);
dictionary.put("B", 66);
dictionary.put("C", 67);
dictionary.put("D", 68);
dictionary.put("E", 69);
dictionary.replace("D", 68, 5);
System.out.println(dictionary);
}
}
{A=65,B=66,C=67,D=5,E=69}
结论:
在本文中,我们学习了从映射中移除一个元素,我们可以使用Map.remove()
或Map.replace()
函数,这两个函数都有特定的变化来检查给定值是否存在,这导致操作更加精确。功能的所有变化如下所述:
- Map.remove(键);
- Map.remove(键,值);
- 映射.替换(键,值);
- 映射.替换(键、旧值、新值);
如何在 Java 中创建交换函数
原文:https://www.studytonight.com/java-examples/how-to-create-a-swap-function-in-java
在本文中,我将向您介绍一些交换原始类型和非原始类型数据类型的示例。相比之下,在原始数据类型上,我们可以很容易地执行交换,但是在非原始数据类型的情况下,这是非常复杂的工作。java.util.Collections
类支持swap()
,用于交换原始类型和非原始类型数据类型列表中的元素。
在继续使用swap()
方法之前,让我们看看两个变量交换的经典例子。
交换两个变量的示例
这是交换两个变量的常规方式。假设我们有两个变量a
和b
,那么a
的值将被赋给b
,类似地b
的值被赋给a
的值。一个变量一次只能保存一个值,这就是为什么我们创建temp
变量来保存临时值。从输出值可以观察到两个变量都在变化。
public class StudyTonight
{
public static void main(String[] args)
{
int a=10;
int b=20;
int temp;
System.out.println("Before Swap: a="+a+" b:"+b);
temp=a;
a=b;
b=temp;
System.out.println("After Swap: a="+a+" b:"+b);
}
}
互换前:a=10 b:20
互换后:a=20 b:10
我们可以看到上面的代码可以很好地交换两个变量,但是需要额外的内存。为了节省内存,我们可以使用交换公式:
a=a+b;
b=a-b;
a=a-b;
当我们想要处理两个元素时,这些方法是很好的。如果有必要在对象列表中进行交换,该怎么办?
在这种情况下Collections.swap()
功能非常有帮助:
public static void swap(List<?> list, int indexOne, int indexTwo)
list
:是我们要进行交换的列表
indexOne, indexTwo
:这些是列表中的索引,将通过函数进行交换
如果任何一个索引越过了列表的边界,这个方法会抛出一个异常IndexOutOfBoundException
。
使用 swap()函数交换列表中元素的示例
在下面的例子中,我们制作了一个 String 的 ArrayList,然后在第 0 个和第 2 个元素上使用Collections,swap()
方法执行了一个交换操作。通过比较交换前后的列表,可以很容易地注意到元素的交换。
交换前:[ 班加罗尔、德里、诺伊达、孟买]
交换后:[ 诺伊达,德里,班加罗尔,孟买]
import java.util.*;
public class StudyTonight
{
public static void main(String[] args)
{
ArrayList<String> list = new ArrayList<String>();
list.add("Bangalore");
list.add("Delhi");
list.add("Noida");
list.add("Mumbai");
System.out.println("List Before Swapping : " +list);
Collections.swap(list, 0, 2);
System.out.println("List after swapping : " +list);
}
}
交换前列表:【班加罗尔、德里、诺伊达、孟买】
交换后列表:【诺伊达、德里、班加罗尔、孟买】
结论:
要交换基本元素,我们可以简单地使用一个临时变量并交换值。但是在对象列表的情况下,我们最终可能会使用大量的额外空间。在这些情况下,使用 Collections.swap()方法交换列表中的元素是非常有益的。我们可以想做多少次就做多少次。我们只需要照顾IndexOutOfBoundException
。当我们处理大型对象列表以节省创建临时对象的额外开销时,这种方法非常有用。
Java 中的整数除法
原文:https://www.studytonight.com/java-examples/integer-division-in-java
在本教程中,我们将学习 Java 中的整数除法。假设我们有两个Integer
类型的变量a=25
和b=5
,我们想要执行除法。
当涉及到保持精度或避免精度的决定时,主要是在除法运算时,因为在进行除法运算时,很有可能会失去精度。
简单除法的例子
在给定的示例中,我们有三个 int 类型的变量a
、b
、c
,我们将a
、&、b
的除法存储到c
中。我们建议您运行这个示例,观察输出,并将您的观察结果与我们下面讨论的内容进行匹配。
public class StudyTonight
{
public static void main(String[] args)
{
int a = 25;
int b = 5;
int c = a / b;
System.out.println(a+"/"+b+"="+c);
}
}
25/5=5
在上面的情况下,除法会很精细,因为所有变量都是整数形式的,5
将25
完全除。想想10/3
肯定c
不能存储3.3333...
,因为它是一个整型变量,只能存储整数数据,只能保存 3
。在以下情况下,它不考虑提醒。
示例:丢失数据
这里,我们将两个整数相除,并将结果存储到 int 中,这将导致数据丢失,因为整数不包含小数位值。
public class StudyTonight
{
public static void main(String[] args)
{
int a = 10;
int b = 3;
int c = a / b;
System.out.println(a+"/"+b+"="+c);
}
}
10/3=3
现在让我们提出进行实数除法的想法,我们将在double.
中存储值
例子
在下面给出的代码中,为了观察当我们将变量的数据类型从 float 更改为 int 时会发生什么的输出,反之亦然。你会得到整数或实数。
public class StudyTonight
{
public static void main(String[] args)
{
int ans1 = 10 / 3;
double ans2 = 10.0 / 3;
double ans3 = 10 / 3.0;
double ans4 = 10.0 / 3.0;
double ans5 = 10 / 3;
System.out.println("10 / 3 = "+ans1);
System.out.println("10.0 / 3 = "+ans2);
System.out.println("10 / 3.0 = "+ans3);
System.out.println("10.0 / 3.0 = "+ans4);
System.out.println("10 / 3 = "+ans5);
}
}
10/3 = 3
10.0/3 = 3.3333333333335
10/3.0 = 3.33333333335
10.0/3.0 = 3.3333333333335
10/3 = 3.0
结论:
在实现了所有上述代码之后,我们可以根据除数和被除数的数据类型得出一些重要的结论
int / int = int
double / int = double
int / double = double
双倍/双倍=双倍
Java 整数到二进制的转换
原文:https://www.studytonight.com/java-examples/java-integer-to-binary-conversion
在本文中,我们将在 Java 中讨论整数到二进制的转换。通常,有两种方法可以将整数转换为二进制数。
- toBinaryString()
- 数学长除法
首先我们将学习toBinaryString()
方法。这是一个Integer
类方法,在将整型转换为二进制后返回一个字符串。
public static String toBinaryString(int val)
这里val
是我们要转换成二进制数系统的值。然后这个方法将返回字符串格式的二进制值。
示例:使用 toBinaryString()方法进行 Int 到二进制的转换
在下面的例子中,我们正在调用Integer.toBinaryString()
方法,int 将以 String 格式返回一个二进制值。
import java.lang.Math;
public class StudyTonight
{
public static void main(String[] args)
{
int val=183;
System.out.println("Value in binary system is: " + Integer.toBinaryString(val));
}
}
二进制中的值为:10110111
除了这个内置方法,我们使用长除法从头开始实现。
示例:使用长除法进行整数到二进制的转换
这种方法完全是数学上的,这里我们通过考虑 32 位二进制表示来声明一个大小为 32 的 int 数组。每次我们将一个数字除以 2,并将提醒存储在 int 数组中。最后,为了得到结果,我们以相反的方式遍历它。
public class StudyTonight
{
public static void main(String[] args)
{
int val=183;
int num[] = new int[32];
int pos=0;
while(val>0)
{
num[pos++]=val%2;
val=val/2;
}
System.out.print("Value in binary system is:");
for(int i=pos-1; i>=0; i--)
{
System.out.print(num[i]);
}
}
}
二进制数值为:10110111
在上面的方法中,我们可以看到每次我们使用 mod 操作计算提醒时都要进行长除法运算,而且这些运算与位操作相比成本很高,我们可以使用下面给出的位操作进行相同的运算。
示例:使用位操作的整数到二进制转换
使用右移位运算符,我们可以将任何值减半,由于我们是在位级别上工作,因此这是一个非常低成本的操作,其余的事情与上面示例中提到的相同。最后,我们使用反转存储在 StringBuilder 对象中的值来打印值,以使其正确地以二进制形式显示。
public class StudyTonight
{
public static void main(String[] args)
{
int val = 183;
StringBuilder binary = new StringBuilder(32);
while (val > 0 ) {
binary.append( val % 2 );
val >>= 1;
}
binary.reverse().toString();
System.out.print("Value in binary system is:"+binary.reverse().toString());
}
}
二进制数值为:11101101
在java.lang.Integer
类 bu 中有一个更有趣的方法,使用Integer.toString()
方法,该方法接受第一个参数作为数字,第二个参数作为radix
(这里基数是数字系统的基数),对于二进制数可以是 2,对于八进制数可以是 8,对于十六进制数可以是 16,对于二进制数可以是 2
Integer.toString(int val, int radix)
示例:使用 Integer.toString()进行整数到二进制的转换
Integer.toString()是一种内置方法,它将第一个参数作为我们要转换的值,将第二个参数作为基数,基数也称为数字系统的基数。在我们的例子中,我们对二进制数感兴趣,所以我们传递 2,它将以字符串格式返回给定值的二进制数。
public class StudyTonight
{
public static void main(String[] args)
{
int val = 183;
System.out.print("Value in binary system is:"+Integer.toString(val, 2));
}
}
二进制数值为:10110111
结论:
在 java 中,我们可以使用两种方法将 int 转换为二进制:第一种方法非常简单,我们使用Integer
类中的 toBinaryString()
方法,这将产生一个二进制数的字符串,该字符串相当于作为参数提供给该函数的数。在第二种方法中,我们每次对一个数进行 2 的长除法并存储进位,这是一种将 int 转换为二进制数的纯数学方法。
如何在 Java 中创建一个对象
原文:https://www.studytonight.com/java-examples/how-to-create-an-object-in-java
Java 是一种面向对象的编程语言。Java 支持创建类和对象,这是面向对象程序设计的一个基本概念。
在本教程中,我们将学习如何创建类的对象。类是一个实体,它代表一个真实的实体,该实体具有类似真实实体的属性。让我们举一个著名的汽车例子。汽车可以有颜色、品牌名称、制造年份和其他不同的属性。
我们用这样一个类来表示现实生活中的实体:
public class Car
{
private String car_color;
private String brand;
private String fuel_type;
public void Start()
{
...
}
public void Stop()
{
...
}
}
这个给定的类是我们应该如何制造汽车的蓝图,就像我们从蓝图中制造汽车一样,我们创建了一个类的对象,它也被称为类的实例。
为了创建对象,下面是理解对象创建的信息图:
1:这是一个班级的名字
2:它是我们想要创建的对象的名称。它是对一个对象的引用。
3:是为类的对象分配内存的新关键字。
4:它看起来像一个函数,但它是一个构造器,在创建对象时会自动调用。
非常有趣的事实是一个用于在堆中创建的对象内存和引用用于存储在栈中。
Java 中的对象创建示例:
在下面的代码中,我们使用new
关键字为每个对象创建了Car
类的对象car
,我们可以使用.
(点)运算符调用方法。在这里我们使用car
对象调用Start()
和Stop()
方法。
public class Car
{
private String car_color;
private String brand;
private String fuel_type;
public void Start()
{
System.out.println("Car Started");
}
public void Stop()
{
System.out.println("Car Stopped");
}
public static void main(String args[])
{
//creating an object of Car class
Car car = new Car();
//Calling method Start() using object
car.Start();
//Calling method Stop() using object
car.Stop();
}
}
汽车启动
汽车停止
在大多数情况下,我们将使用上述方法创建对象,但是创建对象的方法更多。
示例:使用 Class 类的 newInstance()方法
在下面给出的程序中,我们使用Class
类的newInstance()
方法创建了一个对象。在这个方法中,我们使用方法来代替new
关键字,然后这个方法将创建一个类的实例,并将它存储到引用中。
class Student
{
String stud_name;
int roll_no;
}
public class StudyTonight
{
public static void main(String args[]) throws Exception
{
//creating an object using newInstance() method
Student arr = Student.class.newInstance();
arr.stud_name = "ABC";
arr.roll_no = 123;
//printing data ob an object
System.out.print("Name: "+arr.stud_name+" Roll No: "+arr.roll_no);
}
}
名称:中航卷号:123
示例:使用克隆()方法
在下面给出的程序中,我们使用 clone()
方法创建了一个学生类的对象。当且仅当至少已经创建了类的一个对象时,才可以使用此方法。还确保Cloneable
类在一个类中实现。在调用clone()
方法时,我们要求覆盖它,因为它受到保护。
class Student implements Cloneable
{
String stud_name;
int roll_no;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class StudyTonight
{
public static void main(String args[]) throws Exception
{
Student student = new Student();
student.stud_name = "ABC";
student.roll_no = 123;
//cloning student object to obj
Student obj = (Student) student.clone();
//printing data of an object
System.out.print("Name: "+obj.stud_name+" Roll No: "+obj.roll_no);
}
}
名称:中航卷号:123
示例:使用反序列化创建对象
**在下面给出的示例中,我们使用反序列化来创建类的对象,与创建对象相比,该方法更注重序列化和反序列化。首先,确保要创建对象的类必须是 Serializable 标签,这样才能实现 Serializable 类。在此之后,您只需要反序列化一个对象,然后反序列化时将该对象分配给新对象。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class Student implements Serializable
{
String stud_name;
int roll_no;
}
public class StudyTonight
{
public static void main(String args[]) throws Exception
{
Student student = new Student();
student.stud_name = "ABC";
student.roll_no = 123;
// Serialization of a student object
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.obj"))){
out.writeObject(student);
}
Student obj;
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"))) {
obj = (Student) in.readObject();
}
//printing data of an object
System.out.print("Name: "+obj.stud_name+" Roll No: "+obj.roll_no);
}
}
名称:中航卷号:123
结论:
类是表示现实实体的对象的蓝图。该对象是在堆中创建的类的实例,但引用了存储在栈中的对象。
如何在 Java 中调用一个方法
原文:https://www.studytonight.com/java-examples/how-to-call-a-method-in-java
在本教程中,我们将学习如何在 Java 中调用方法。java 中的方法是一组特定的任务,它们在多次定义一次调用时起作用。这些方法可以是:
- 内置方法
- 用户定义的方法
要调用静态方法我们不需要创建一个对象它可以通过使用方法名直接调用。
如何在 Java 中调用内置方法
在这个例子中,Math.sqrt()
是一个内置的方法,它将一个数字作为参数并返回它的平方根。这里我们传递这个数字,它会返回这个数字的平方根。我们将这个调用分配给一个变量ans
,因为当这个方法返回一个数字时,应该有一个变量来接受这个值。
public class StudyTonight
{
public static void main(String[] args)
{
double num=16;
double ans = Math.sqrt(num);
System.out.println("Square Root of "+num+" = "+ans);
}
}
16.0 的平方根= 4.0
如何在 Java 中调用用户定义的方法
在给定的代码中,我们调用了两个方法Show()
,这是一个静态方法,因此不需要创建对象。另一方面,Hello()
是用户定义的非静态方法,要调用这样的方法必须创建对象。
public class StudyTonight
{
public void Hello()
{
System.out.println("Hello");
}
public static void Show()
{
System.out.println("Show is Called");
}
public static void main(String[] args)
{
//calling static method
Show();
//calling method of other class
StudyTonight obj = new StudyTonight();
obj.Hello();
}
}
节目叫
你好
结论:
Java 方法可以是用户定义的,也可以是内置的两种方法都是一样的,唯一不同的是程序员明确定义了自定义逻辑的用户定义方法。我们以同样的方式调用这两种方法。在调用这些方法时,我们需要注意参数和返回值。
在 Java 中检查输入是否为整数
原文:https://www.studytonight.com/java-examples/check-if-input-is-integer-in-java
在本教程中,我们将学习如何确定给定的输入是否是整数。如果整个输入只包含数字,即0-9
,那么它将被认为是一个整数。为了实现检查有效整数的程序,我们将使用三种方法:
- 使用
Integer.parseInt()
方法检查有效整数 - 使用
Scanner.hasNextInt()
方法检查有效整数 - 使用
Character.isDigit()
方法检查有效整数
1)使用 Integer.parseInt()检查有效整数的示例
在本例中,我们将尝试将一个字符串解析为整数,如果该字符串只包含数字,那么它不会抛出异常,我们可以打印输出,表明给定的输入是有效的整数。如果给定的输入不是有效的整数,那么它会抛出一个异常,这时我们可以通过给出一个消息来处理一个异常,即当前的输入不是有效的整数。
public class StudyTonight
{
public static void main(String[] args)
{
String input = "1234";
try
{
Integer.parseInt(input);
System.out.println(input + " is a valid integer");
}
catch (NumberFormatException e)
{
System.out.println(input + " is not a valid integer");
}
}
}
1234 是有效整数
另一方面,如果我们提供整数以外的输入,它将给出输出,因为给定的字符串不是有效的整数。
public class StudyTonight
{
public static void main(String[] args)
{
String input = "ab1234c";
try
{
Integer.parseInt(input);
System.out.println(input + " is a valid integer");
}
catch (NumberFormatException e)
{
System.out.println(input + " is not a valid integer");
}
}
}
ab1234c 不是有效的整数
2)使用 Scanner.hasNextInt()方法检查有效整数的示例
Scanner.hasNextInt()
方法检查当前输入是否包含整数。如果输入中出现整数,此方法将返回 true,否则将返回 false。
import java.util.Scanner;
public class StudyTonight
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
if(sc.hasNextInt()) {
System.out.println(sc.nextInt()+" is valid Integer");
}
else
{
System.out.println(sc.nextInt()+" is valid Integer");
}
sc.close();
}
}
123
123 为有效整数
3)使用 Character.isDigit()方法检查有效整数的示例
Character.isDigit()
是检查当前字符是数字(数字)还是任何其他字符的方法。这个代码背后的逻辑是,给我们一个字符串,我们将检查每个字符和任何不是数字的字符,然后我们设置一个标志为假,标志必须设置为真。遍历字符串后,我们检查标志的状态,如果它为真,那么我们将打印当前输入的有效整数。
public class StudyTonight
{
public static void main(String[] args)
{
String input = "1234";
Boolean flag=true;
for(int a=0;a<input.length();a++)
{
if(a==0 && input.charAt(a) == '-')
continue;
if( !Character.isDigit(input.charAt(a)))
flag=false;
}
if(flag)
{
System.out.println(input+" is valid Integer");
}
}
}
1234 是有效整数
结论:
在本文中,我们学习了检查给定的输入是否是有效的整数。首先我们可以使用Integer.parseInt()
方法、Scanner.hasNextInt()
方法和Character.isDigit()
方法所有的方法都同样有效。Scanner.hasNextInt()只能在我们使用Scanner
类接受输入的情况下使用。
在 Java 中为字符串添加换行符
原文:https://www.studytonight.com/java-examples/adding-a-newline-character-to-a-string-in-java
字符串在 Java 中是一种重要的数据类型,我们必须知道如何格式化字符串以返回多行输出。向字符串中添加新行可以通过许多不同的方式来完成。换行符依赖于平台,但是 Java 也提供了一些独立于平台的行分隔符,我们可以在 Java 代码中使用。让我们学习如何使用它们。
平台相关换行符
\n 或 \r 或两者的组合可用于为字符串添加新行。我们只需要将它添加到新行的输出位置。例如,如果我们想将“Java 很棒”分成三行,字符串看起来像“Java \n 是 \n 棒极了”。
\n 称为换行(LF) ,用于将光标移动到新行。\r 称为回车符(CR) ,用于将光标移动到当前行的开头。
然而,这些换行符依赖于平台。不同的操作系统以不同的方式定义了一个新的系列。
-
对于 Windows,使用 \r\n (CRLF)
-
对于基于 Unix 的操作系统(包括现代 Macs),使用 \n( LF)
-
对于旧的苹果操作系统(在操作系统-X 之前),使用 \r (CR)
考虑下面演示 CRLF 用法的例子。
public static void main(String[] args)
{
String str1 = "Java is awesome";
System.out.println(str1);
String str2 = "Java\r\nis\r\nawesome";
System.out.print(str2);
}
Java 很牛逼
Java
很牛逼
独立于平台的行分隔符
换行符 CR 和 LF 可用于添加新行,但它们依赖于平台。Java 为我们提供了一些根据操作系统返回行分隔符的方法。
这使得我们的代码与平台无关。
我们可以使用System.lineSeparator()
在字符串之间添加新行。
public static void main(String args[])
{
String str1 = "Java is awesome";
System.out.println(str1);
String newline = System.lineSeparator();
String str2 = "Java" + newline + "is" + newline + "awesome";
System.out.print(str2);
}
Java 很牛逼
Java
很牛逼
或者我们可以用line.separator
作为参数的getProperty()
方法。
public static void main(String args[])
{
String str1 = "Java is awesome";
System.out.println(str1);
String newline = System.getProperty("line.separator");
String str2 = "Java" + newline + "is" + newline + "awesome";
System.out.print(str2);
}
Java 很牛逼
Java
很牛逼
与平台无关的换行符
%n 是一个独立于平台的换行符,与我们已经讨论过的其他方法相比,它更容易使用。只要你想移动到新的一行,只需添加**%n**
。
确保使用printf()
方法将字符串打印到控制台。
public static void main(String args[])
{
String str1 = "Java is awesome";
System.out.println(str1);
String str2 = "Java%nis%nawesome";
System.out.printf(str2);
}
Java 很牛逼
Java
很牛逼
使用System.out.println()
方法
打印字符串时,还有另一种方法可以将字符串添加到新行中。我们可以使用println()
方法来做到这一点。它首先将字符串打印到控制台,然后将光标移到新的一行。然而,这不是格式化字符串的好方法,因为如果我们有几个字符串,我们的代码会变得很长。
例如,如果我们希望在十条不同的线上打印十个字符串,那么我们将不得不写System.out.println()
十个不同的时间。
public static void main(String args[])
{
String str1 = "Java";
String str2 = "is ";
String str3 = "awesome";
System.out.println(str1);
System.out.println(str2);
System.out.print(str3);//Not using println() as we do not need a new line after this
}
Java
是
牛逼
摘要
我们将非常频繁地处理字符串,如果我们希望返回多行输出,了解如何正确格式化字符串是很重要的。如果我们确定我们的代码不会在其他操作系统上使用,我们可以使用平台相关的换行符,比如回车符和换行符。像lineSeparator()
和getProperty()
这样的方法会根据操作系统返回适当的行分隔符。
%n
是另一个换行符,但它与平台无关。
文件和输入/输出
在 Java 中读取 CSV 文件
原文:https://www.studytonight.com/java-examples/reading-a-csv-file-in-java
CSV 代表逗号分隔值,是一种非常流行的File
类型。CSV 文件用于存储由逗号分隔的信息。文件的每一行都用来表示一个数据记录。在本教程中,我们将学习如何读取 CSV 文件并将其内容复制到数组或列表中。在本教程中,我们将使用一个仅包含三条记录的简单 CSV 文件。文件的内容如下所示。
Justin, 101, 9.1
Jessica, 102, 8.7
Clark, 103, 7.1
使用BufferedReader
读取 CSV 文件
java.io
包的BufferedReader
类可以用来读取基本的 CSV 文件。我们将使用readLine()
方法简单地阅读文件的每一行。然后我们可以使用split()
方法并通过逗号作为分隔符来拆分行。
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
public class ReadingCSV
{
public static void main(String[] args)
{
try
{
List< List<String> > data = new ArrayList<>();//list of lists to store data
String file = "C:\\Users\\Lenovo\\Desktop\\demo.csv";//file path
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
//Reading until we run out of lines
String line = br.readLine();
while(line != null)
{
List<String> lineData = Arrays.asList(line.split(","));//splitting lines
data.add(lineData);
line = br.readLine();
}
//printing the fetched data
for(List<String> list : data)
{
for(String str : list)
System.out.print(str + " ");
System.out.println();
}
br.close();
}
catch(Exception e)
{
System.out.print(e);
}
}
}
贾斯汀 101 9.1
杰西卡 102 8.7
克拉克 103 7.1
请注意,我们不能使用这种方法来读取更复杂的 CSV 文件或逗号本身是值的文件。例如,考虑一个 CSV 文件,其中第二列用于存储标点符号。
Full Stop,"."
Comma,","
Exclamation,"!"
如果我们试图读取这个文件,那么下面的数据就存储在列表中。我们可以看到文件的第二行没有存储任何值(逗号被省略了)。我们也不需要引号。
完全停止。”
逗号“
感叹“!”
使用扫描仪类读取 CSV 文件
我们也可以使用java.util
包的Scanner
类读取一个 CSV 文件。这种方法与BufferedReader
非常相似。我们将简单地读取文件的每一行,然后使用逗号作为分隔符将其拆分。然后我们可以将单个记录存储在列表中。
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Arrays;
public class ReadingCSV
{
public static void main(String[] args)
{
try
{
List< List<String> > data = new ArrayList<>();//list of lists to store data
String filePath = "C:\\Users\\Lenovo\\Desktop\\demo.csv";//file path
File file = new File(filePath);
Scanner s = new Scanner(file);
//Reading until we run out of lines
while(s.hasNextLine())
{
List<String> lineData = Arrays.asList(s.nextLine().split(","));//splitting lines
data.add(lineData);
}
//printing the fetched data
for(List<String> list : data)
{
for(String str : list)
System.out.print(str + " ");
System.out.println();
}
s.close();
}
catch(Exception e)
{
System.out.print(e);
}
}
}
贾斯汀 101 9.1
杰西卡 102 8.7
克拉克 103 7.1
就像BufferedReader
一样,Scanner
类方法不能用于复杂的 CSV 文件。
使用 opencv 库读取 csv 文件
OpenCSV
是一个 CSV 文件解析库,可以让从 CSV 文件中读取变得容易很多。CSVReader
被用作FileReader
的包装材料。我们将使用CSVReader
的readNext()
方法逐行读取文件。它返回一个字符串数组,我们不需要担心拆分行。
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import com.opencsv.CSVReader;
import java.util.Arrays;
public class ReadingCSV
{
public static void main(String[] args)
{
try
{
List< List<String> > data = new ArrayList<>();//list of lists to store data
String filePath = "C:\\Users\\Lenovo\\Desktop\\demo.csv";//file path
FileReader fr = new FileReader(filePath);
CSVReader reader = new CSVReader(fr);
String[] lineData = reader.readNext();
//Reading until we run out of lines
while(lineData != null)
{
data.add(Arrays.asList(lineData));
lineData = reader.readNext();
}
//printing the fetched data
for(List<String> list : data)
{
for(String str : list)
System.out.print(str + " ");
System.out.println();
}
reader.close();
}
catch(Exception e)
{
System.out.print(e);
}
}
}
贾斯汀 101 9.1
杰西卡 102 8.7
克拉克 103 7.1
让我们将上面的代码用于 CSV 文件,其中我们有一个值为逗号的单元格。我们可以看到,逗号被CSVReader
认为是一个值而不是一个分隔符。甚至报价被删除,数据以更好的格式呈现。
句号。
逗号,
感叹号!
摘要
CSV 文件用于存储由逗号(在某些情况下是分号)分隔的数据。CSV 文件的每一行代表一条记录。我们可以使用BufferedReader
或Scanner
轻松读取基本 CSV 文件中的数据。但是我们在阅读更复杂的 CSV 文件时,可能得不到预期的结果。读取 CSV 文件最简单的方法是使用像OpenCSV
这样的外部库。
在 Java 中中的printf()
执行格式化
原文:https://www.studytonight.com/java-examples/formatting-with-printf-in-java
Java printf()是属于 PrintStream 类的一个方法,和 c 语言中的 printf()函数非常相似,用来格式化输出并打印到控制台。这个方法使用 java.util.Formatter 类来解析和格式化输出。在本教程中,我们将学习如何使用 printf()方法。
Java Printf()方法
如上所述,printf()方法用于在 Java 中格式化字符串。该方法的一般语法如下所示。
System.out.printf(string)
System.out.printf(format string, comma separated variables values or objects)
System.out.printf(locale, format string, comma-separated variables values or objects)
- 如果传递了区域设置,则根据所提到的区域进行格式化。
- 我们通常只使用两个参数——一个是格式化字符串,另一个包括对象、变量或值。
- 格式字符串定义了用户如何看到输出。格式化字符串的一般结构如下所示。如果我们希望输出一些值,必须包含转换字符,但是其他修饰符是可选的。
%[flags][width][.precision][conversion-characters]
- 没有任何说明符和变量,printf()的工作方式与 print()或 println()完全一样。下面的示例演示了如果不使用格式化字符串,printf()和 println()的输出是如何相同的。
public static void main(String args[])
{
System.out.println("Printing using println().");
System.out.printf("Printing using printf().");
}
使用 println()打印。
使用 printf()打印。
在 Java 中使用 print()格式化字符
根据我们试图打印的变量或值的数据类型,格式字符串必须包含转换字符。以下列表包括一些最常用的转换字符。
- c 格式化字符或字符。
- s 格式化字符串。
- d 格式化整数。
- f 格式化浮点或小数。
- t 格式化日期和时间。
- b 格式化布尔值或条件表达式。
- e 格式化指数浮点数。
- %n 用作换行符,将光标移到下一行。
public static void main(String args[])
{
System.out.printf("Printing an integer %d %n", 10);
System.out.printf("Printing a floating-point number %f %n", 10.0);
System.out.printf("Printing an exponential floating-point number %e %n", 10.0);
System.out.printf("Printing a string %s %n", "String");
System.out.printf("Printing a character %c %n", 'A');
}
打印整数 10
打印浮点数 10.000000
打印指数浮点数 1.000000e+01
打印字符串
打印字符 A
我们必须根据变量或值的数据类型使用正确的转换字符。如果它们不匹配,那么我们将得到一个非法格式转换异常。考虑以下示例,其中整数的转换字符用于格式化字符串。
public static void main(String args[])
{
System.out.printf("%d", "ABC");
}
线程“main”中出现异常 Java . util . illegalformationconversationexception:d!= java.lang.String
位于 java . base/Java . util . formatter $ format 说明符. fail conversion(formatter . Java:4426)
位于 Java . base/Java . util . formatter $ format 说明符. print integer(formatter . Java:2938)
位于 Java . base/Java . util . formatter $ format 说明符. print(Formatter.java:2892)
位于 Java . base/Java . util . formatter . format(formatter . Java:2673)
位于 Java
一些转换字符也可以用来将字母转换成大写。例如,如果我们使用“C”而不是“C”,那么字符值将以大写形式打印。同样的规则可以应用于字符串和布尔值。请记住,这不会反过来工作,即“c”不会将大写字母转换为小写字母。
示例:打印时格式化小写和大写()
下面的代码示例演示了大写和小写转换字符的使用。
public static void main(String args[])
{
System.out.printf("%c%n", 'a');
System.out.printf("%C%n", 'a');
System.out.printf("%s%n", "lowercase");
System.out.printf("%S%n", "uppercase");
System.out.printf("%b%n", 10 < 5);
System.out.printf("%B%n", 10 < 5);
}
a
A
小写
大写
假
假
printf()方法中的标志
标志用于以不同的方式修改格式化的输出。例如,连字符(-) 可用于左对齐我们的字符串,逗号(,可用于添加千位分隔符。
public static void main(String args[])
{
System.out.printf("%d%n", 1000000);//without flag
System.out.printf("%,d", 1000000);//with flag
}
1000000
1000000
使用 printf()方法设置宽度
宽度用于指定控制台中输出的最小空格数。例如,如果我们使用“%5s”,那么将分配至少 5 个位置。如果要打印的值具有较小的长度,那么将在它的前面添加填充,否则该值将按原样打印。考虑下面的例子来更好地理解它。
public static void main(String args[])
{
System.out.printf("%5s", "string");
}
上述代码的输出将仅仅是单词“string”。
但是,带有填充的输出看起来像“'- string”,其中连字符表示一个空格。
public static void main(String args[])
{
System.out.printf("'%15s'", "string");
}
使用 printf()方法设置精度
精度可用于指定浮点数小数点后的位数。它也可以用来提取子字符串。
public static void main(String args[])
{
System.out.printf("%.4f %n", 3.14159265359);//rounding pi up to 4 decimal places
System.out.printf("%.3s", "string");//first three characters of the string
}
3.1416
str
使用 printf()格式化数字
如上所述,%d 用于格式化整数,%f 用于格式化浮点数。默认情况下,%f 将在输出中添加额外的零。我们可以通过使用精度修饰符来限制它们。
public static void main(String args[])
{
System.out.printf("Integer: %d%n", 10);
System.out.printf("Float: %f", 10.01);
}
整数:10
浮点数:10.010000
我们也可以使用逗号标志用千位分隔符来格式化数字。我们还可以使用区域设置来指定区域。例如,在意大利使用点,但英语使用逗号。
public static void main(String args[])
{
System.out.printf(Locale.ENGLISH, "%,d%n", 1000000);
System.out.printf(Locale.ITALY, "%,d", 1000000);
}
100 万
100 万
我们还可以通过在转换字符前输入 0 并指定宽度来用零填充数字。
public static void main(String args[])
{
System.out.printf("%010d%n",158);
}
0000000158
使用 printf()格式化日期和时间
对于日期和时间格式,我们必须使用某些后缀和“t”转换字符。让我们分别看一下日期和时间格式。
时间格式
我们可以简单地通过使用带有“T”转换字符的“T”后缀来打印日期的时间部分。
public static void main(String args[])
{
Date date = new Date();
System.out.printf("Time: %tT", date);
}
时间:18:07:38
下列后缀用于时间格式化。
- H 用于提取日期的小时部分。
- M 用于提取日期的分部分。
- S 用于提取日期的秒部分。
- L 用于提取日期的毫秒部分。
- n 用于提取日期的纳秒部分。
- p 用于打印上午或下午。
- z 用于打印时区。
看看下面的代码,以便更好地理解时间格式。
public static void main(String args[])
{
Date date = new Date();
System.out.printf("Hours: %tH Minutes: %tM Seconds: %tS Milliseconds: %tL%n", date, date, date, date);
}
小时:17 分钟:58 秒:26 毫秒:793
正如我们在上面的代码中看到的,我们需要多次提到日期变量。通过使用格式字符串中的索引引用 1$ ,有一个简单的方法可以解决这个问题。
public static void main(String args[])
{
Date date = new Date();
System.out.printf("Hours: %1$tH Minutes: %1$tM Seconds: %1$tS Milliseconds: %1$tL%n",
date);
}
小时:18 分 01 秒:32 毫秒:783
日期格式
以下是日期格式最常用的后缀列表。
- A 用来打印当天的全称。
- 一个用来打印当天的缩写名称
- B 用于打印月全称。
- b 用于打印月份的简称。
- d 用于打印当月的两位数日。
- m 用于打印年度的两位数月份。
- Y 用于输出四位数的年份。
- y 用于输出两位数的年份。
考虑下面的例子,以更好地理解日期格式。
public static void main(String args[])
{
Date date = new Date();
System.out.printf("Day: %tA Date: %td Month: %tB Year: %tY%n",
date, date, date, date);
}
日:周四日期:08 月:7 月年份:2021
我们也可以使用 1 美元的索引引用进行日期格式化。
public static void main(String args[])
{
Date date = new Date();
System.out.printf("Day: %1$tA Date: %1$td Month: %1$tB Year: %1$tY%n",
date);
}
日:周四日期:08 月:7 月年份:2021
摘要
人们必须知道如何正确地格式化和打印输出,以便于阅读和理解。Java 有一个 printf()方法,用于格式化输出。它使用由转换字符和可选修饰符组成的格式字符串。在本教程中,我们学习了如何使用 printf()方法格式化整数、字符串、布尔值、日期和时间。
Java BufferedReader
原文:https://www.studytonight.com/java-examples/java-bufferedreader
BufferedReader
类是java.io
包的一部分,扩展了Reader
类。BufferedReader 用于从字符输入流中读取文本,并缓冲字符以获得更好的性能。
在本教程中,我们将了解更多关于此类的信息。
什么是 BufferedReader?
- 如上所述,
BufferedReader
是一个用于从某个源(如文件或套接字)读取文本的类。 - BufferedReader 包装另一个读取器或输入流,以提高我们程序的整体效率和性能。
- 缓冲区缓存器使用缓冲区来存储从源中读取的数据。它减少了所需的输入/输出操作数量。
- 像
FileReader
和InputStreamReader
这样的几个读取器读取操作成本很高,最好用 BufferedReader 打包。
缓冲恐惧者构造器
BufferedReader 类提供了两个构造器。它们中的每一个都以 Reader 为参数。我们还可以在构造器中指定底层缓冲区的大小。默认缓冲区大小为 8KB 。
BufferedReader?(Reader in)
BufferedReader?(Reader in, int bufferSize)
另一个读取器的缓冲恐惧器
让我们用缓冲恐惧器包装一个FileReader
。我们可以用它来读取文件中的数据。
String path = "C:\\Users\\Lenovo\\Desktop\\Demo.txt";
FileReader fileReader = new FileReader(path);
BufferedReader bufferedReader = new BufferedReader(fileReader);//Creating a BufferedReader by wrapping the FileReader
在后面的部分中,我们将使用它以不同的方式从文件中读取数据。
带流的缓存器
我们可以使用一个输入流作为源来创建一个缓存器。
让我们包装InputStreamReader
并从系统读取数据。它会读取我们用键盘输入的数据。下面的代码演示了这一点。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Demo
{
public static void main(String[] args) throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader bufferedReader = new BufferedReader(isr);//Creating a BufferedReader
System.out.println("Enter Something");
String line = bufferedReader.readLine();
System.out.print("You Entered: " + line);
bufferedReader.close();//Closing the stream
}
}
下图显示了输出。
关闭流
我们应该始终使用 BufferedReader 的 close() 方法来释放与读取器相关联的所有系统资源。如果我们使用的是资源试用块,我们不需要显式调用这个方法。
bufferedreader vs 扫描仪
扫描仪和缓存器都可以从外部源读取数据。然而,这两者之间有一些区别。
- BufferedReader 类是同步的和线程安全的,而 Scanner 类是不同步的。
- 扫描仪类有一个较小的固定大小的缓冲区(1KB)。缓存器缓存器可以改变缓存器的大小。另外,BufferedReader 使用的默认缓冲区大小比 Scanner 类大得多。
- BufferedReader 比 Scanner 更快,因为它无需解析数据即可读取数据。
- 扫描仪将隐藏 IOException。有了缓冲恐惧器,我们需要处理这个异常。
逐行读取文件
BufferedReader
类提供了几种读取数据的方法。 readLine() 方法一次读取一行。如果我们到达流的末尾,这个方法返回 null。让我们用这个方法读一个文件。演示文件包含以下几行。
This is a Demo File.
We will read this file using BufferedReader.
This is the end of file.
读取文件的代码如下所示。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Demo
{
public static void main(String[] args) throws IOException
{
String path = "C:\\Users\\Lenovo\\Desktop\\Demo.txt";
FileReader fileReader = new FileReader(path);
BufferedReader bufferedReader = new BufferedReader(fileReader);//Creating a BufferedReader
String line;
int lineCount = 0;
//Reading the file line by line
while( (line = bufferedReader.readLine()) != null )
{
lineCount += 1;
System.out.println("Line: " + lineCount);
System.out.println(line + "\n");
}
bufferedReader.close();//Closing the stream
}
}
行:1
这是一个演示文件。
行:2
我们将使用 BufferedReader 读取此文件。
行:3
这是文件结束。
从文件中读取单个字符
我们也可以使用 BufferedReader 类的 read() 方法一次读取一个字符。此方法返回整数形式的字符读数。如果我们到达流的末端,那么它返回-1。下面的代码演示了这个方法的工作原理。我们的文件包含文本“你好世界!”。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Demo
{
public static void main(String[] args) throws IOException
{
String path = "C:\\Users\\Lenovo\\Desktop\\Demo.txt";
FileReader fileReader = new FileReader(path);
BufferedReader bufferedReader = new BufferedReader(fileReader);//Creating a BufferedReader
int charRead;
//Reading the file one char at a time
while( (charRead = bufferedReader.read()) != -1 )
{
System.out.println((char)charRead);
}
bufferedReader.close();//Closing the stream
}
}
H
e
l
l
o
T6】W
o
r
l
d
!
从文件中读取多个字符
read()方法也可以一次读取多个字符。我们需要传递一个 char 数组来存储数据。我们还需要使用一个偏移量来指示字符数组的起始索引。存储的数据从这个索引开始。我们还需要提到要阅读的最大字符长度。
我们的文件包含文本“HelloWorld”。我们想从文件中读出“你好”。下面的代码演示了如何做到这一点。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Demo
{
public static void main(String[] args) throws IOException
{
String path = "C:\\Users\\Lenovo\\Desktop\\Demo.txt";
FileReader fileReader = new FileReader(path);
BufferedReader bufferedReader = new BufferedReader(fileReader);//Creating a BufferedReader
char[] charArr = new char[5];
bufferedReader.read(charArr, 0, 5);//reading 5 characters into the charArr
System.out.print(charArr);
bufferedReader.close();//Closing the stream
}
}
你好
跳过字符
BufferedReader 类提供了一个 skip() 方法,我们可以用它来跳过字符。它需要一个Long
类型参数。假设我们的文件包含文本“Hello”。读完每个字符后,我们需要跳过一个字符,因为我们不想读星号。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Demo
{
public static void main(String[] args) throws IOException
{
String path = "C:\\Users\\Lenovo\\Desktop\\Demo.txt";
FileReader fileReader = new FileReader(path);
BufferedReader bufferedReader = new BufferedReader(fileReader);//Creating a BufferedReader
int charRead;
StringBuilder sb = new StringBuilder();
//Reading the file one char at a time
while( (charRead = bufferedReader.read()) != -1 )
{
sb.append((char)charRead);
bufferedReader.skip(1L);//Skipping one character
}
System.out.print(sb);
bufferedReader.close();//Closing the stream
}
}
你好
标记并重置
BufferedReader 类为我们提供了标记()方法来标记特定的字符。使用重置()方法,我们可以在将来的任何时候回到这个标记的字符。mak()方法接受一个整数作为输入,该整数表示在标记无效之前可以读取的最大字节数。
假设我们的文件包含文本“He*llo”。我们将阅读所有的字符,但标出星号。然后我们将使用 reset()回到这个标记。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Demo
{
public static void main(String[] args) throws IOException
{
String path = "C:\\Users\\Lenovo\\Desktop\\Demo.txt";
FileReader fileReader = new FileReader(path);
BufferedReader bufferedReader = new BufferedReader(fileReader);//Creating a BufferedReader
char[] charArr = new char[5];
charArr[0] = (char)bufferedReader.read();//H
charArr[1] = (char)bufferedReader.read();//e
bufferedReader.mark(10);//Marked the asterisk
bufferedReader.skip(1);//Skipped the asterisk
charArr[2] = (char)bufferedReader.read();//l
charArr[3] = (char)bufferedReader.read();//l
charArr[4] = (char)bufferedReader.read();//o
System.out.println(charArr);
bufferedReader.reset();//Going back to the mark
char asterisk = (char) bufferedReader.read();//Reading the asterisk
System.out.print(asterisk);
bufferedReader.close();//Closing the stream
}
}
你好
*
摘要
BufferedReader 类从文件或流等源中读取数据。它通过使用减少输入/输出操作数量的缓冲区来提高其他读取器的性能。BufferedReader 类提供了几种方便的方法来读取数据。我们可以使用 readLine()方法来读取单独的行。read()方法可以读取单个或多个字符。
如何在 Java 中读取文件
原文:https://www.studytonight.com/java-examples/how-to-read-a-file-in-java
在这篇文章中,我们将学习使用 Java 输入/输出方法读取文件数据。Java 提供了一个Files
类,用于 Java 中的文件处理操作。
Files
类提供了一种方法lines()
,用于读取具有指定字符集的文件数据。默认情况下,字符集是 UTF 8,方法返回一个字符串流,因此我们也可以执行流操作。
这里,我们有两个例子来理解 Java 中的文件读取过程。
我们有一个 abc.txt 文本文件,将用于阅读目的。文件内容如下。
//文件:abc.txt
This is a text file
This is another line of the file
举例时间:
让我们阅读文件的所有行,即文件的所有数据。这里,我们使用File
类和返回字符串流的lines()
方法。
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) throws IOException{
Path path = Paths.get("abc.txt");
Stream<String> str = Files.lines(path, StandardCharsets.UTF_8);
str.forEach(System.out::println);
}
}
这是一个文本文件
这是文件的另一行
另一个例子的时间:
让我们举另一个例子来读取文件的所有行。这里,我们使用一个File
类的readAllLines()
方法,它返回一个字符串列表。因为我们希望我们的数据在字符串中,所以我们使用join()
方法将列表转换成字符串。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException{
Path path = Paths.get("abc.txt");
List<String> str = Files.readAllLines(path);
String data = String.join("\n", str);
System.out.println(data);
}
}
这是一个文本文件
这是文件的另一行
如何在 Java 中编写文件
原文:https://www.studytonight.com/java-examples/how-to-write-a-file-in-java
在这篇文章中,我们将学习如何将数据写入文件。数据可以是单个字符、字符序列或多行字符串。
要将数据写入文件,我们使用的是 Java 的Files
类。Files
类提供了几种将数据写入文件的方法,如写入字节、字符串或可迭代等。
在这里,我们将使用write()
方法编写一个字符串以及字符串列表。出于书写的目的,我们使用一个文件 outfile.txt 来存储书写的数据。
我们建议您在编写之前创建一个文件,但是,如果文件不存在,Java 会自动创建该文件。
举例时间:
现在,让我们看一个将数据写入文件的例子。这里,我们有一个文件 outfile.txt 将用于存储数据,Files
类的write()
方法用于此目的。该方法以字节格式写入数据,因此我们使用getBytes()
方法将字符串转换为字节。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) throws IOException{
String lines = "Welcome to Studytonight.com \n It is technical portal.";
Path path = Paths.get("outfile.txt");
Files.write(path, lines.getBytes());
}
}
执行完上面的代码,就可以打开看到同一个目录下的文件 outfile.txt 。
另一个例子的时间:
让我们再举一个将数据写入文件的例子。这里,我们向文件中写入一个字符串列表,并且在write()
方法中,我们还指定了标准字符集。该方法是write()
方法的替代版本之一。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.nio.charset.*;
public class Main {
public static void main(String[] args) throws IOException{
List<String> lines = Arrays.asList("Welcome to Studytonight.com", "It is technical portal.");
Path path = Paths.get("outfile.txt");
Files.write(path, lines, StandardCharsets.UTF_8);
}
}
成功执行上述代码后,您可以看到 outfile.txt 文件,该文件必须包含如下所示的写入数据。
//文件:outfile.txt
欢迎来到 Studytonight.com
是技术门户。
如何在 Java 中将一个文件复制到另一个文件
原文:https://www.studytonight.com/java-examples/how-to-copy-a-file-to-another-file-in-java
在这篇文章中,我们将学习如何将文件数据复制到另一个文件中。这是我们在处理文件和输入/输出操作时面临的一个普遍问题。
有几种方法可以复制数据,例如使用FileInputStream
、FileOutputStream
、Files
类。所有这些类都用于文件处理操作。
但是Files
类更容易使用,因为它提供了copy()
方法,可以将源文件即时复制到目标文件,而在FileInputStream
则没有复制方法。因此,我们需要先读取数据,然后将它们写入目标文件。
这里,我们有一些示例来说明对文件的复制操作。下面我们有一个文件 outfile.txt 包含一些数据,将被写入到 abc.txt 空文件中。
//文件:outfile.txt
Welcome to Studytonight.com
It is technical portal.
举个例子
让我们创建一个将一个文件复制到另一个文件的示例。这里,我们使用的是将源复制到目的地的Files
类的copy()
方法。
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) throws IOException{
Path path = Paths.get("outfile.txt");
OutputStream os = new FileOutputStream("abc.txt");
Files.copy(path,os);
}
}
另一个例子的时间:
我们再举一个例子,将一个文件复制到另一个文件。这里,我们使用FileInputStream
和FileOutputStream
来读写数据。通过使用FileInputStream
类的read()
方法,我们从源文件中读取数据,并使用文件输出流的write()
方法写入数据。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
File source = new File("outfile.txt");
File dest = new File("abc.txt");
try{
FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
}catch(Exception e) {
System.out.println(e);
}
}
}
成功执行上述代码后。您可以看到 abc.txt 文件将具有与 outfile.txt 中相同的数据。这意味着数据复制成功。
如何在 Java 中读取 XML 文件
原文:https://www.studytonight.com/java-examples/how-to-read-xml-file-in-java
在这篇文章中,我们将学习使用 Java 代码读取 XML 文件。XML 是一种可扩展标记语言文档文件,用于存储和传输数据。
Java 提供了一个 XML 解析器库来读取 XML 文档。因此,我们必须在编写代码读取文件之前导入这些库。
在这里,我们使用了一个包含一些数据的示例 XML 文件 students.xml ,我们将使用 Java 代码阅读该文件。
// students.xml
<students>
<student id="101">
<Name>John</Name>
<id>11001</id>
<location>India</location>
</student>
<student id="102">
<Name>Alex</Name>
<id>11002</id>
<location>Russia</location>
</student>
<student id="103">
<Name>Rohan</Name>
<id>11003</id>
<location>USA</location>
</student>
</students>
举例时间:
让我们创建一个读取 XML 文件的示例。在这里,我们首先创建了一个 doucment 的实例,然后解析它来读取文件。getDocumentElement()
方法用于读取根元素,然后通过使用循环,我们迭代文档的所有标签。
package myjavaproject;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import javax.xml.parsers.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException, ParserConfigurationException, SAXException{
DocumentBuilderFactory dBfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dBfactory.newDocumentBuilder();
// Fetch XML File
Document document = builder.parse(new File("students.xml"));
document.getDocumentElement().normalize();
//Get root node
Element root = document.getDocumentElement();
System.out.println(root.getNodeName());
//Get all students
NodeList nList = document.getElementsByTagName("student");
System.out.println(".................................");
for (int i = 0; i < nList.getLength(); i++)
{
Node node = nList.item(i);
System.out.println(); //Just a separator
if (node.getNodeType() == Node.ELEMENT_NODE)
{
//Print each student's detail
Element element = (Element) node;
System.out.println("Student id : " + element.getAttribute("id"));
System.out.println("Name : " + element.getElementsByTagName("Name").item(0).getTextContent());
System.out.println("Roll No : " + element.getElementsByTagName("id").item(0).getTextContent());
System.out.println("Location : " + element.getElementsByTagName("location").item(0).getTextContent());
}
}
}
}
学生
.................................
学号:101
姓名:约翰
卷号:11001
地点:印度
学号:102
姓名:亚历克斯
卷号:11002
地点:俄罗斯
学号:103
姓名:罗翰
卷号:11003
地点:美国
实时示例:
您可以使用在线 Java 编译器测试这些 Java 代码。这里,我们附加了一个 XML 文件来读取数据。
如何将数据写入 CSV 文件
原文:https://www.studytonight.com/java-examples/how-to-write-data-into-csv-file
在这篇文章中,我们将学习如何使用 Java 代码将数据写入 CSV 文件。在前一篇文章中,我们学习了从 CSV 文件中读取数据。你可以在这里参考这个帖子“用 JAVA 阅读 CSV”。
要将数据写入 CSV 文件,我们使用的是第三方库OpenCSV
库。因此,您必须从这里下载 JARs。下载 OpenCSV 罐子。
下载 JARs 后,将它们导入到您的项目中。这个库包含两个重要的类CSVReader
和CSVWriter
,用于在 CSV 文件中进行读写操作。
在这里,我们使用CSVWriter
类将数据写入 CSV 文件学生. csv 。
举例时间:
让我们创建一个将数据写入 CSV 文件的示例。在这里,我们要给学生. csv 文件写四条记录。所以,我们用CSVWriter
类的writeNext()
方法写数据。
import java.io.FileWriter;
import java.io.IOException;
import com.opencsv.CSVWriter;
public class Main {
public static void main(String[] args) throws IOException{
String csvFile = "students.csv";
CSVWriter cw = new CSVWriter(new FileWriter(csvFile));
String line1[] = {"Id", "Name", "Country"};
String line2[] = {"1", "Sohan", "India"};
String line3[] = {"2", "Rohan", "USA"};
String line4[] = {"3", "Abhishek", "UK"};
//Writing data to the csv file
cw.writeNext(line1);
cw.writeNext(line2);
cw.writeNext(line3);
cw.writeNext(line4);
//close the file
cw.close();
}
}
成功执行上述代码后, students.csv 文件会有以下数据。
//学生. csv
“身份证”、“姓名”、“国家”
“1”、“索汉”、“印度”
“2”、“罗汉”、“美国”
“3”、“阿布舍克”、“英国”
另一个例子的时间:追加 CSV
我们再举一个例子来写 CSV 文件。这里,我们以追加模式打开 CSV 文件来写入数据。追加模式的好处是,它不会替换文件的旧数据。要启用追加模式,请使用FilWriter()
构造器中的true
文字,就像我们在下面的示例中所做的那样。
import java.io.FileWriter;
import java.io.IOException;
import com.opencsv.CSVWriter;
public class Main {
public static void main(String[] args) throws IOException{
String csvFile = "students.csv";
CSVWriter cw = new CSVWriter(new FileWriter(csvFile,true));
String[] line = {"4", "David", "USA"};
//Writing data to the csv file
cw.writeNext(line);
//close the file
cw.close();
}
}
看,我们在文件中写了一个条目,它写在文件的末尾,这意味着我们的代码可以正常工作。
// student.csv
“Id”、“姓名”、“国家”
“1”、“Sohan”、“印度”
“2”、“Rohan”、“美国”
“3”、“Abhishek”、“英国”
“4”、“大卫”、“美国”
如何在 Java 中读取多个文本文件
原文:https://www.studytonight.com/java-examples/how-to-read-multiple-text-files-in-java
在这篇文章中,我们将使用 Java 代码读取多个文本文件。当我们处理一个需要从多个资源中读取数据的大型项目时,这很有帮助。
在这里,我们使用了一个File
类,用于处理 Java 中与文件相关的操作。
要读取多个文件,可能有几种情况,但在这里,我们从一个文件夹或两个单独的文件中读取文件。
出于示例的目的,我们有两个文件 file1.txt 和 file2.txt ,它们位于一个文件夹 filefolder 中。这两个文件包含下面给出的一些数据。
// file1.txt
The default port for mysql is 3306
Oracle db is running at port 8080
示例:
让我们举一个使用 Java 代码读取多个文件的例子。在这里,我们有一个文件夹包含我们将要阅读的两个文件。我们使用File
类获取文件实例,BufferReader
类读取文件数据。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
File dir = new File("filefolder");
File[] files = dir.listFiles();
// Fetching all the files
for (File file : files) {
if(file.isFile()) {
BufferedReader inputStream = null;
String line;
try {
inputStream = new BufferedReader(new FileReader(file));
while ((line = inputStream.readLine()) != null) {
System.out.println(line);
}
}catch(IOException e) {
System.out.println(e);
}
finally {
if (inputStream != null) {
inputStream.close();
}
}
}
}
}
}
【mysql 的默认端口是 3306
Oracle db 运行在端口 8080
实时示例:
试试这个例子,我们在文件夹外有两个单独的文本文件,并读取它们。您可以编辑这些文本文件来检查代码是否产生了所需的结果。
如何在 Java 中读写 PDF 文件
原文:https://www.studytonight.com/java-examples/how-to-read-and-write-pdf-file-in-java
在这篇文章中,我们将学习使用 Java 代码读写 pdf 文件。pdf 是一个便携式文档文件,用于传输信息文档。它是广泛使用的文件格式之一。
为了处理 Java 中的 pdf 文件,我们使用了由 apache 基金会设计和开发的 pdfbox 库。它用于以高效的方式创建、读取、写入和追加 pdf 文件。
在阅读 pdf 文件之前,您必须下载此库。可以在这里下载。下载的文件基本上都是 JARs 文件,所以请将它们导入到您的项目中,并开始使用 pdf。
有一些重要的类PDDocument
、PDPage
、PDPageContentStream
等需要加载和获取数据。
如果您正在使用 maven 项目,那么在您的 pom.xml 文件中使用以下依赖项。
//POM . XML
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.studytonight.pdfExample</groupId>
<artifactId>pdfExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.12</version>
</dependency>
</dependencies>
</project>
它会自动下载你项目中所有需要的 JARs。所以,你不需要手动下载罐子。添加这些依赖项后,在您的 Java 项目中使用下面的示例代码来读写 PDF 文件。
**## 举例时间:
让我们从一个使用 PDFBox 库读取 pdf 文件的例子开始。在这里,我们有一个 pdf 文件test.pdf,我们用load()
方法加载,用getText()
方法读取。
import java.io.File;
import java.io.IOException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
public class Main {
public static void main(String[] args) throws IOException{
try {
// Creating file instance
File file = new File("test.pdf");
// Loading pdf file
PDDocument document = PDDocument.load(file);
PDFTextStripper pdfStripper = new PDFTextStripper();
// Fetching PDF document
String text = pdfStripper.getText(document);
System.out.println(text);
// Closing the document
document.close();
}catch(Exception e) {
System.out.println(e);
}
}
}
示例:
由于 PDFBox 是为 pdf 处理而制作的,所以我们可以将数据写入 pdf 文件。这里,我们在追加模式下向test.pdf文件写入数据,对于追加模式,我们在PDPageContentStream
中使用了APPEND
常量,这样文件数据就不会被替换。我们使用setFont()
方法设置字体,save()
方法保存对文件的更改。
import java.io.File;
import java.io.IOException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
public class Main {
public static void main(String[] args) throws IOException{
PDDocument document = PDDocument.load(new File("test.pdf"));
PDPage page = document.getPage(0);
PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND,true,true);
contentStream.beginText();
//Setting the font
contentStream.setFont(PDType1Font.TIMES_ROMAN, 12);
//Setting the text position
contentStream.newLineAtOffset(25, 500);
String text = "This message is writtern to the pdf file.";
contentStream.showText(text);
contentStream.endText();
contentStream.close();
// Saving file after writing
document.save(new File("test.pdf"));
document.close();
}
}
执行此程序后,将在当前目录中创建一个 PDF 文件test.pdf。您可以打开该文件,看到它包含我们用代码保存的文本。
如何在 Java 中获取文件扩展名
原文:https://www.studytonight.com/java-examples/how-to-get-file-extension-in-java
在这篇文章中,我们将学习如何使用 Java 代码获取文件的扩展名。文件的扩展名是一个标志,表示文件的类型,如 pdf、txt、doc 等。“计算机”字段中有几个文件扩展名,用于区分文件和其他文件。
扩展名是文件名的一部分,放在文件名的末尾,如 test.txt、officefile.doc 等。
这里,我们有一些例子展示了如何在 Java 程序中获取任何文件的扩展名。在读取文件并将文件上传到服务器时,知道文件扩展名非常有帮助,这样我们只能获得所需类型的文件。
举例时间:
让我们创建一个获取文件扩展名的示例。这里,我们有一个文本文件 file.txt ,我们正在获取它的扩展名。我们使用了String
类的lastIndexOf()
和substring()
方法来识别扩展。
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
String extension = "null";
String fileName = "file.txt";
int i = fileName.lastIndexOf('.');
if (i > 0) {
extension = fileName.substring(i+1);
}
System.out.println(extension);
}
}
txt
另一个例子的时间:
如果文件被加密或压缩,那么它可能有不止一个扩展名。在这种情况下,我们可以使用下面的 Java 代码,其中文件是压缩的,扩展名为. tar.gz。
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
String extension = null;
String fileName = "file.tar.gz";
int i = fileName.lastIndexOf('.');
if (i > 0) {
extension = fileName.substring(i+1);
}
System.out.println(extension);
}
}
gz
文件在 Java 中的最后修改时间
原文:https://www.studytonight.com/java-examples/files-last-modified-time-in-java
在这篇文章中,我们将使用 Java 代码获取文件的最后修改时间。上次修改时间表示上次文件更新的时间。
Java 提供lastModified()
或getLastModifiedTime()
等内置方法获取文件上次更新时间。我们可以使用 java.io 包的File
类或者 java.nio 包的Files
类。您可以自行决定使用哪个软件包。
lastModified()
方法属于File
类,返回一个时间。而getLastModifiedTime()
方法属于Files
类,以Long
类型返回时间,可以进一步转换为日期时间。
举例时间:
让我们创建一个示例来获取文件的最后修改时间。这里,我们使用的是 File 类的lastModified()
方法,它以Long
类型返回时间,所以我们需要显式地将其转换为时间,就像我们在下面的例子中所做的那样。
import java.io.File;
import java.io.IOException;
import java.time.Instant;
public class Main {
public static void main(String[] args) throws IOException{
try {
File file = new File("abc.txt");
long time = file.lastModified(); // file modified time
System.out.println(time);
// Convert long time to date time
System.out.println(Instant.ofEpochMilli(time));
}catch(Exception e) {
System.out.println(e);
}
}
}
1592912186419
2020-06-23t 11:36:26.419 z
另一个例子的时间:
让我们举另一个例子来获得文件的最后修改时间。这里我们使用的是Files
类的getLastModifiedTime()
方法,返回带有日期的时间。见下面的例子。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;
public class Main {
public static void main(String[] args) throws IOException{
try {
Path path = Paths.get("abc.txt");
FileTime time = Files.getLastModifiedTime(path); // file modified time
System.out.println("Last modified time of the file:");
System.out.println(time);
}catch(Exception e) {
System.out.println(e);
}
}
}
文件上次修改时间:
2020-06-23T11:36:26.419959Z
在 Java 中检查是否存在文件
原文:https://www.studytonight.com/java-examples/check-if-a-file-exists-in-java
在这篇文章中,我们将检查文件是否存在于指定的位置或路径。我们正在使用 Java 代码来检查指定文件的存在。
File 类的exists()
方法用于测试路径所表示的文件或目录是否存在。它也可以用来检查文件和目录的存在。
如果文件或目录存在,此方法返回 true。我们可以使用isFile()
方法来检查现有的文件是文件只是不是目录。
这里,我们有一些使用 exists()和 isFile()方法的例子。
举例时间:
让我们举个例子来检查文件是否存在。这里,我们使用的是exists()
方法,如果文件存在则返回 true,否则返回 false。请看下面的例子。
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
try {
File file = new File("path/to/file/abc.txt");
boolean isexist = file.exists();
if(isexist) {
System.out.println("File is present");
}else {
System.out.println("File does not present");
}
}catch(Exception e) {
System.out.println(e);
}
}
}
文件存在
另一个例子的时间:
让我们举另一个例子来检查文件是否存在。
这里我们是用isFile()
方法配合exists()
方法来保证现有的文件是文件,而不是目录。如果现有文件是文件,isFile()
方法返回真,否则返回假。
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
try {
File file = new File("path/to/file/abc.txt");
boolean isExist = file.exists(); // Check for valid path
boolean isFile = file.isFile(); // Check for file
if(isExist && isFile) {
System.out.println("File is present");
}else {
System.out.println("File does not present");
}
}catch(Exception e) {
System.out.println(e);
}
}
}
文件存在
检查文件是否是目录
原文:https://www.studytonight.com/java-examples/check-if-the-file-is-a-directory
在这篇文章中,我们将检查目录是否存在于指定的位置或路径。java.io.File
和java.nio.Files
类都提供了检查目录的方法。
isDirectory()
方法属于File
类,如果目录存在,则返回 true。而Files
类提供了一个静态方法isDirectory()
,该方法将目录路径作为参数。
这里,我们已经创建了使用类File
和Files
检查目录的例子。
举例时间:
让我们举个例子,检查目录是否存在。这里,我们使用的是返回真或假的File
类的 isDirectory()方法。
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
try {
File file = new File("path/to/directory/");
boolean isDirectory = file.isDirectory(); // Check for directory
if(isDirectory) {
System.out.println("It is a directory");
}else {
System.out.println("It is not directory");
}
}catch(Exception e) {
System.out.println(e);
}
}
}
是一个目录
另一个例子的时间:
让我们创建另一个示例来检查目录。这里,我们使用的是Files
类的isDirectory()
方法,该方法需要目录的路径,如果路径属于某个目录,则返回 true,否则返回 false。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) throws IOException{
try {
Path path = Paths.get("path/to/directory/");
boolean isDirectory = Files.isDirectory(path); // Check for directory
if(isDirectory) {
System.out.println("It is a directory");
}else {
System.out.println("It is not directory");
}
}catch(Exception e) {
System.out.println(e);
}
}
}
是一个目录
如何检查文件是否可读和可写
原文:https://www.studytonight.com/java-examples/how-to-check-if-a-file-is-readable-and-writable
在这篇文章中,我们将检查一个文件是否可读和可写。计算机系统中的每个文件都有指定其是否可以读取、写入或执行的属性。
出于某些安全原因,所有文件都不是公开可读或可写的。所以 Java File 类提供了在程序执行期间检查文件这些属性的方法。
为了检查读取属性,我们使用canRead()
方法,对于写入,我们使用File
类的canWrite()
方法。
canRead()和 canWrite()方法都返回真或假的布尔值。如果文件是可读或可写的,那么我们可以从这两种方法中得到真实的结果。
举例时间:
让我们创建一个例子来检查一个文件是否可读。这里,我们使用的是 File 类的canRead()
方法。
import java.io.File;
public class Main {
public static void main(String[] args){
try {
File file = new File("abc.txt");
boolean canRead = file.canRead();
if(canRead) {
System.out.println("File can be read");
}else {
System.out.println("File can't be read");
}
}catch(Exception e) {
System.out.println(e);
}
}
}
文件可读取
示例:
让我们创建一个示例来检查文件是否可写。这里,我们使用的是返回布尔值的 File 类的canWrite()
方法。
import java.io.File;
public class Main {
public static void main(String[] args){
try {
File file = new File("abc.txt");
boolean canWrite = file.canWrite();
if(canWrite) {
System.out.println("File is writeable");
}else {
System.out.println("File is not writeable");
}
}catch(Exception e) {
System.out.println(e);
}
}
}
文件可写
示例:
如果一个文件是可写的,并且我们想用 Java 代码使它不可写,那么我们可以使用使文件不可写的File
类的setWritable()
方法,见下面的例子。
import java.io.File;
public class Main {
public static void main(String[] args){
try {
File file = new File("abc.txt");
boolean canWrite = file.canWrite();
// Setting file not to writable
file.setWritable(false);
if(canWrite) {
System.out.println("File is writeable");
}else {
System.out.println("File is not writeable");
}
}catch(Exception e) {
System.out.println(e);
}
}
}
文件不可写
如何在 Java 中删除文件或目录
原文:https://www.studytonight.com/java-examples/how-to-delete-a-file-or-directory-in-java
在这篇文章中,我们将使用 Java 代码删除一个文件或目录。Java 提供了一个File
类,它包含像delete()
和deleteOnExit()
这样的方法来删除指定的资源文件或目录。
当我们希望在创建新版本文件来替换旧版本文件后使用代码删除文件时,这很有帮助。
delete()
方法删除位置表示的文件或目录。如果指定的位置路径表示一个目录,则该目录必须为空。
如果文件或目录无法删除,则抛出IOException
。
此方法返回真或假的布尔值。
时间举例
让我们创建一个使用delete()
方法删除文件的例子。如果文件被成功删除,此方法返回 true。
import java.io.File;
public class Main {
public static void main(String[] args){
try {
File file = new File("abc.txt");
boolean delete = file.delete();
if(delete) {
System.out.println("File is deleted");
}else {
System.out.println("File is not deleted");
}
}catch(Exception e) {
System.out.println(e);
}
}
}
文件被删除
示例:删除目录
我们也可以使用delete()
方法删除一个目录。确保指定的目录路径表示一个空目录,如果删除失败,它将向调用者函数返回 false。
import java.io.File;
public class Main {
public static void main(String[] args){
try {
File file = new File("path/to/directory/Trash");
boolean delete = file.delete();
if(delete) {
System.out.println("Directory is deleted");
}else {
System.out.println("Directory is not deleted");
}
}catch(Exception e) {
System.out.println(e);
}
}
}
目录被删除
示例:deleteOnExit()方法
还有另一种方法deleteOnExit()
,用于在虚拟机终止时删除文件或目录。这意味着它会在程序实例终止时删除。
应该谨慎使用此方法,因为一旦请求删除,就不可能取消请求。它不返回值意味着将 void 返回给被调用的函数。
import java.io.File;
public class Main {
public static void main(String[] args){
try {
File file = new File("abc.txt");
// Delete file while exit
file.deleteOnExit();
}catch(Exception e) {
System.out.println(e);
}
}
}
Java 字符串
计算一个字符在 Java 中的出现次数
原文:https://www.studytonight.com/java-examples/count-occurrences-of-a-character-in-java
字符串只是一个字符序列。在本教程中,我们将学习统计字符串中特定字符出现次数的不同方法。
方法 1 -迭代方法
我们将遍历字符串中的每个字符。如果这个字符与我们正在寻找的字符匹配,我们将增加一个计数。下面的代码演示了这种方法。
public static int countChars(String str, char c)
{
int count = 0;
for(int i = 0; i < str.length(); i++)
{
char currChar = str.charAt(i);
if(currChar == c)
count += 1;
}
return count;
}
让我们使用这个方法,并检查它是否给出理想的输出。
public static void main(String[] args)
{
String s = "Java is an awesome language!";
int charCountOfA = countChars(s, 'a');
int charCountOfG = countChars(s, 'g');
int charCountOfE = countChars(s, 'e');
System.out.println("The String is: " + s);
System.out.println("Character count of 'a': " + charCountOfA);
System.out.println("Character count of 'g': " + charCountOfG);
System.out.println("Character count of 'e': " + charCountOfE);
}
字符串是:Java 是一门牛逼的语言!
字符数“a”:6
字符数“g”:2
字符数“e”:3
方法 2 -递归方法
看到这个问题,递归不会是第一个想到的。但是,我们可以用递归来解决这个问题。我们将使用两种方法而不是一种。第一个方法是递归的,第二个方法调用第一个方法。该方法与上一节中讨论的方法非常相似。
public static int countCharsRecur(String str, char c, int idx)
{
if(idx >= str.length())
return 0;
else {
int count = 0;
if(str.charAt(idx) == c)
count = 1;
return count + countCharsRecur(str, c, idx + 1);
}
}
public static int countChars(String s, char c)
{
return countCharsRecur(s, c, 0);
}
让我们使用上述方法并查看输出。
public static void main(String[] args)
{
String s = "Java is an awesome language!";
int charCountOfA = countChars(s, 'a');
int charCountOfG = countChars(s, 'g');
int charCountOfE = countChars(s, 'e');
System.out.println("The String is: " + s);
System.out.println("Character count of 'a': " + charCountOfA);
System.out.println("Character count of 'g': " + charCountOfG);
System.out.println("Character count of 'e': " + charCountOfE);
}
字符串是:Java 是一门牛逼的语言!
字符数“a”:6
字符数“g”:2
字符数“e”:3
方法 3 -使用 Java 8 流
Java 8 Streams 还提供了一种简单的方法来计算字符串中字符的出现次数。我们将首先使用 chars()方法将字符串转换为一个输入流。我们也可以使用 codePoints()方法来代替 chars()。接下来,我们将使用带有 Lambda 表达式的 filter()方法来过滤掉所有匹配的字符。最后,我们将使用 count()方法返回过滤流中元素的计数。
public class Demo
{
public static void main(String[] args)
{
String s = "Java is an awesome language!";
int charCountOfA = (int) s.chars().filter(c -> c == 'a').count();
int charCountOfG = (int) s.chars().filter(c -> c == 'g').count();
int charCountOfE = (int) s.chars().filter(c -> c == 'e').count();
System.out.println("The String is: " + s);
System.out.println("Character count of 'a': " + charCountOfA);
System.out.println("Character count of 'g': " + charCountOfG);
System.out.println("Character count of 'e': " + charCountOfE);
}
}
字符串是:Java 是一门牛逼的语言!
字符数“a”:6
字符数“g”:2
字符数“e”:3
方法 4 -使用正则表达式
正则表达式也可以解决这个问题。然而,用正则表达式来解决这样一个简单的问题并不是一个好主意。下面的代码演示了如何使用正则表达式来解决这个问题。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo
{
public static int countChars(String str, char c)
{
String regex = String.valueOf(c);
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
int count = 0;
while(matcher.find())
count += 1;
return count;
}
public static void main(String[] args)
{
String s = "Java is an awesome language!";
int charCountOfA = countChars(s, 'a');
int charCountOfG = countChars(s, 'g');
int charCountOfE = countChars(s, 'e');
System.out.println("The String is: " + s);
System.out.println("Character count of 'a': " + charCountOfA);
System.out.println("Character count of 'g': " + charCountOfG);
System.out.println("Character count of 'e': " + charCountOfE);
}
}
字符串是:Java 是一门牛逼的语言!
字符数“a”:6
字符数“g”:2
字符数“e”:3
方法 5 -外部库
计算字符串中某个字符的出现次数是非常常见的,以至于许多外部库都有内置函数来实现这一点。让我们使用一些外部库来解决这个问题。
使用番石榴图书馆
番石榴库提供了 CharMatcher 类,可以计算给定字符出现的次数。首先,我们将使用这个类的静态 is() 方法。此方法创建一个 CharMatcher 实例来匹配特定的字符。接下来,我们将使用 countIn() 方法,该方法将一个字符串作为参数,并返回该字符串中字符的计数。
import com.google.common.base.CharMatcher;
public class Demo
{
public static void main(String[] args)
{
String str = "Java is an awesome language!";
CharMatcher cm = CharMatcher.is('a'); //Creating the CharMatcher
int charCountOfA = cm.countIn(str); //Counting the occurences
System.out.println("The String is: " + str);
System.out.println("Character count of 'a': " + charCountOfA);
}
}
字符串是:Java 是一门牛逼的语言!
字符数“a”:6
使用阿帕奇图书馆
阿帕奇公共库提供了一个String
类。这个类有一个方便的 countMatches() 方法,该方法将一个字符和一个字符串作为输入,并将该字符串中的字符计数作为输出返回。
import org.apache.commons.lang3.StringUtils;
public class Demo
{
public static void main(String[] args)
{
String s = "Java is an awesome language!";
int charCountOfA = StringUtils.countMatches(s, 'a');
int charCountOfG = StringUtils.countMatches(s, 'g');
int charCountOfE = StringUtils.countMatches(s, 'e');
System.out.println("The String is: " + s);
System.out.println("Character count of 'a': " + charCountOfA);
System.out.println("Character count of 'g': " + charCountOfG);
System.out.println("Character count of 'e': " + charCountOfE);
}
}
字符串是:Java 是一门牛逼的语言!
字符数“a”:6
字符数“g”:2
字符数“e”:3
摘要
计算字符串中某个字符的出现次数是一项非常简单的任务。我们可以使用核心 Java 迭代或递归地解决这个问题。流也可以在一行代码中解决这个问题。我们也可以使用正则表达式,但是它们提供了次优的解决方案。
Java toString()
方法
原文:https://www.studytonight.com/java-examples/java-tostring-method
toString()
方法是 Object 类的一部分,返回一个对象的字符串表示。这个方法提供了一种用 Java 文本表示对象的方法。所有的 Java 类在内部都继承了对象类。所以,所有的 Java 类都可以覆盖这个方法。
在本教程中,我们将学习 toString()函数。
默认实现
对象类为 toString()方法提供了一个实现。然而,这个实现并没有给出很多关于对象及其字段的信息。它只返回一个包含对象类名和对象 hashcode 的字符串。这两个组件由 @ 隔开。
public String toString()
{
return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
让我们创建一个类并查看这个方法给出的输出。
class Student
{
String name;
double gpa;
Student(String s, double d)
{
this.name = s;
this.gpa = d;
}
}
public class Demo
{
public static void main(String[] args)
{
Student s = new Student("Justin", 8.81);
String studentDetail = s.toString();
System.out.print(studentDetail);
}
}
学生@7a81197d
注意这个方法也被 System.out.print() 方法隐式调用。下面的代码演示了这一点。
class Student
{
String name;
double gpa;
Student(String s, double d)
{
this.name = s;
this.gpa = d;
}
}
public class Demo
{
public static void main(String[] args)
{
Student s = new Student("Justin", 8.81);
System.out.print(s);// toString() called implicitly
}
}
学生@7a81197d
覆盖默认实现
如上所述,所有的类都扩展了对象类,它们可以覆盖 toString()方法。默认实现没有提供关于对象字段的大量信息。让我们在学生课上覆盖这个方法。
class Student
{
String name;
double gpa;
Student(String s, double d)
{
this.name = s;
this.gpa = d;
}
//Returning the object fields by overriding toString()
@Override
public String toString()
{
return "Student[ Name:" + name + " GPA:" + gpa +" ]";
}
}
public class Demo
{
public static void main(String[] args)
{
Student s = new Student("Justin", 8.81);
String studentDetail = s.toString();
System.out.print(studentDetail);
}
}
学生【姓名:贾斯汀 GPA:8.81】
覆盖复杂对象的默认实现
如果我们的类包含对其他对象的引用,那么我们还需要覆盖被引用对象类中的 toString()方法。
例如,让我们向学生类中添加一个地址类字段,并查看覆盖的 toString()方法的输出。
class Student
{
String name;
double gpa;
Address studentAddress;//referenced object
Student(String s, double d, Address add)
{
this.name = s;
this.gpa = d;
this.studentAddress = add;
}
@Override
public String toString()
{
return "Student[ Name:" + name + " GPA:" + gpa + " Address:" + studentAddress +" ]";
}
}
class Address
{
int postalCode;
Address(int i)
{
this.postalCode = i;
}
}
public class Demo
{
public static void main(String[] args)
{
Address add = new Address(100012);
Student s = new Student("Justin", 8.81, add);
String studentDetail = s.toString();
System.out.print(studentDetail);
}
}
学生【姓名:贾斯汀 GPA:8.81 地址:地址@24d46ca6】
如我们所见,Address 类使用默认实现。我们得到地址类名和对象哈希码,但它不包括邮政编码。我们需要覆盖 Address 类中的 toString()方法来纠正这个问题。
class Student
{
String name;
double gpa;
Address studentAddress;
Student(String s, double d, Address add)
{
this.name = s;
this.gpa = d;
this.studentAddress = add;
}
//toString() method for Student class
@Override
public String toString()
{
return "Student[ Name:" + name + " GPA:" + gpa
+ " Address:" + studentAddress +" ]";
}
}
class Address
{
int postalCode;
Address(int i)
{
this.postalCode = i;
}
//toString() method for Address class
@Override
public String toString()
{
return "Address[ Postal Code:" + postalCode +" ]";
}
}
public class Demo
{
public static void main(String[] args)
{
Address add = new Address(100012);
String addressStr = add.toString();
System.out.println(addressStr);
Student s = new Student("Justin", 8.81, add);
String studentDetail = s.toString();
System.out.print(studentDetail);
}
}
地址【邮政编码:100012】
学生【姓名:贾斯汀 GPA:8.81 地址:地址【邮政编码:100012】】
Arrays.toString()方法
Arrays 类还提供了一个 toString()方法来显示数组的内容。如果我们的类包含一个数组数据成员,我们必须在覆盖的 toString()方法中使用 Arrays.toString() 。让我们首先在不使用 Arrays.toString()的情况下查看输出。
class Student
{
String name;
double gpa;
double[] marks;
Student(String s, double d, double[] marks)
{
this.name = s;
this.gpa = d;
this.marks = marks;
}
//Overriding toString() method without using Arrays.toString()
@Override
public String toString()
{
return "Student[ Name:" + name + " GPA:" + gpa + " Marks:" + marks + " ]";
}
}
public class Demo
{
public static void main(String[] args)
{
double[] marks = {10.5, 12.21, 19.0};
Student s = new Student("Justin", 8.81, marks);
String studentDetail = s.toString();
System.out.print(studentDetail);
}
}
学生【姓名:贾斯汀 GPA:8.81 分:【D@5ca881b5】
我们可以看到,显示的是数组的 hashcode,而不是内容。让我们在 toString()方法中使用 Arrays.toString()方法。
import java.util.Arrays;
class Student
{
String name;
double gpa;
double[] marks;
Student(String s, double d, double[] marks)
{
this.name = s;
this.gpa = d;
this.marks = marks;
}
//Using Arrays.toString()
@Override
public String toString()
{
return "Student[ Name:" + name + " GPA:" + gpa + " Marks:" + Arrays.toString(marks) + " ]";
}
}
public class Demo
{
public static void main(String[] args)
{
double[] marks = {10.5, 12.21, 19.0};
Student s = new Student("Justin", 8.81, marks);
String studentDetail = s.toString();
System.out.print(studentDetail);
}
}
学生【姓名:贾斯汀 GPA:8.81 分:【10.5,12.21,19.0】】
还有一个 deepToString() 方法,为多维数组返回合适的字符串表示。
import java.util.Arrays;
public class Demo
{
public static void main(String[] args)
{
int[][] multiDimArr = {
{1, 2, 3},
{4, 5, 6},
{6, 7, 8},
{7, 8, 9}
};
String multiDimStr = Arrays.deepToString(multiDimArr);
System.out.print(multiDimStr);
}
}
[[1,2,3],[4,5,6],[6,7,8],[7,8,9]]
包装器、集合和字符串缓冲区
许多预定义的类都有一个针对 toString()方法的覆盖实现。这是为了确保打印这些类的对象的有意义的字符串表示。如果我们有这些类的数据成员,我们就不需要在被覆盖的 toString()方法中使用任何其他方法。下面的代码演示了这一点。
import java.util.ArrayList;
class Student
{
StringBuffer name;
Double gpa;
ArrayList<Double> marks;
Student(StringBuffer s, double d, ArrayList<Double> marks)
{
this.name = s;
this.gpa = d;
this.marks = marks;
}
//No need to use any special method for any fields inside the toString() method
@Override
public String toString()
{
return "Student[ Name:" + name + " GPA:" + gpa + " Marks:" + marks + " ]";
}
}
public class Demo
{
public static void main(String[] args)
{
ArrayList<Double> marks = new ArrayList<>();
marks.add(10.5); marks.add(12.21); marks.add(19.0);
Student s = new Student(new StringBuffer("Justin"), 8.81, marks);
String studentDetail = s.toString();
System.out.print(studentDetail);
}
}
学生【姓名:贾斯汀 GPA:8.81 分:【10.5,12.21,19.0】】
摘要
对象类提供了一个 toString()方法,该方法返回 Java 对象的字符串表示形式。然而,这个方法在 Object 类中的实现不是很有用。由于这个原因,许多预定义的 Java 类,如整数、双精度、ArrayList
、字符串缓冲区覆盖了这个方法。在用户定义的 Java 类中覆盖这个方法也是一个很好的做法。
Java 字符串format()
方法
原文:https://www.studytonight.com/java-examples/java-string-format-method
String 类的 format()方法使用区域设置、格式化字符串和参数来格式化字符串。这是一个静态方法,返回一个字符串。String
类包含两个重载的 format()方法。
public static String format(String formatString, Object... args)
public static String format(Locale locale, String formatString, Object... args)
这两种重载方法都采用可变的对象类型参数。让我们进一步了解这个方法以及如何使用它来格式化字符串。
格式化字符串
格式化字符串格式化给定的参数,并使用它们生成一个字符串。格式化字符串包含参数索引、标志、宽度定义、精度修饰符和转换字符。
它可能包括我们想要添加到最终格式化字符串中的附加字符串。下面显示了格式化字符串的一般结构。
%[argument-index$][flags][width][.precision][conversion-character]
转换字符
转换字符是格式化字符串的强制部分。数据类型存在不同的转换字符。
让我们尝试使用 String.format()方法格式化字符串。在下面的代码中, %s 格式化String
类型, %d 格式化Integer
类型, %f 格式化浮动数据类型。 %n 字符新增一行。
public class Demo
{
public static void main(String[] args)
{
String name = "Justin";
int regno = 1001;
double marks = 15.21;
String summary = String.format("Student Name: %s %nReg.No: %d %nMarks: %f", name, regno, marks);
System.out.print(summary);
}
}
学生姓名:贾斯汀
Reg。编号:1001
商标:15.21 万
使用参数索引
传递给 format()方法的每个参数都可以通过使用索引来访问。指数从 1 开始,后面跟着一个美元符号($) 。这个索引帮助我们在格式化字符串中多次访问同一个参数。
在下面的代码中,我们两次访问第二个参数(名称)。然后,我们访问第一个参数(标记)。
public class Demo
{
public static void main(String[] args)
{
String name = "Justin";
double marks = 15.21;
String s = String.format("Name: %2$s Name: %2$s Marks: %1$f", marks, name);
System.out.print(s);
}
}
姓名:贾斯汀姓名:贾斯丁·马科斯 15.21 万
Precision 编辑
我们可以使用精度修饰符来舍入浮点数。一点(。)后面跟着的精确位数就是用于此的。让我们把圆周率的值四舍五入到小数点后四位。
public class Demo
{
public static void main(String[] args)
{
double pi = 3.14159265359;
String s = String.format("PI: %.4f", pi);
System.out.print(s);
}
}
PI: 3.1416
对于其他数据类型,它限制最终字符串中包含的字符数。
public class Demo
{
public static void main(String[] args)
{
String str1 = String.format("Precision with Strings Number: %.5s", "Hello World");
String str2 = String.format("Precision with Boolean: %.3b", false);
System.out.println(str1);
System.out.println(str2);
}
}
带字符串数字的精度:您好
带布尔值的精度:fal
宽度
Width 表示参数应该采用的最小空格数。如果一个参数占用的空间较少,则添加空格。
我们可以通过在格式化字符串中使用整数值来添加填充。
例如,在下面的代码中,整数 13 表示返回字符串的总长度。如果原始参数占用的空间较少,则在左侧添加额外的填充。
public class Demo
{
public static void main(String[] args)
{
String name = "Justin";
String s = String.format("%13s", name);//A padding of 7(13 - name.length()) is added
System.out.print("||" + s + "||");
}
}
||贾斯汀||
旗帜
标志是用于修改和格式化输出的字符。我们可以使用减号(-) 来左对齐文本。一个逗号(,可以作为添加千位分隔符的标志。
public class Demo
{
public static void main(String[] args)
{
String str1 = String.format("Left Justify:%-15d", 1000000000);
String str2 = String.format("Thousands-separator: %,d", 1000000000);
System.out.println("||" + str1 + "||");
System.out.println(str2);
}
}
| |左对齐:100000000 | |
千位分隔符:1,000,000,000
使用区域设置
如果没有提到 Locale,format()方法通过调用 Locale.getDefault() 方法使用默认的 Locale。让我们尝试使用其他语言环境来格式化带有千位分隔符的整数。
import java.util.Locale;
public class Demo
{
public static void main(String[] args)
{
int million = 1000000;
String s1 = String.format(Locale.GERMAN, "%,d", million);
System.out.println(s1);
String s2 = String.format(Locale.US, "%,d", million);
System.out.print(s2);
}
}
1,000,000
1,000,000
格式化日期和时间
像 LocalDate 和 LocalTime 这样的日期和时间类也可以使用 format()方法格式化并转换为字符串。
格式化日期和时间的所有转换字符包括或。我们可以使用 %tD 来格式化本地日期。同样,我们可以使用 %tr 来格式化 LocalTime。****
import java.time.*;
public class Demo
{
public static void main(String[] args)
{
LocalDate date = LocalDate.now();
String strDate = String.format("The Date is: %tD", date);
LocalTime time = LocalTime.now();
String strTime = String.format("The Time is: %tr", time);
System.out.println(strDate);
System.out.print(strTime);
}
}
日期为:08/20/21
时间为:上午 09:19:39
我们还可以从本地日期中提取不同的组件。我们可以用 %tA 取日名, %tB 取月名, %tC 取一年中的世纪部分。
import java.time.*;
public class Demo
{
public static void main(String[] args)
{
LocalDate date = LocalDate.now();
String day = String.format("The Day is: %tA", date);
String month = String.format("The Month is: %tB", date);
String century = String.format("The Century part of year is: %tC", date);
System.out.println(day);
System.out.println(month);
System.out.print(century);
}
}
日为:星期五
月为:八月
一年中的世纪部分为:20
同样,我们可以使用 %tI 从 LocalTime 实例中获取小时部分。使用 %tM 获取分钟,使用 %tS 获取秒钟。
import java.time.*;
public class Demo
{
public static void main(String[] args)
{
LocalTime time = LocalTime.now();
String hour = String.format("The Hour is: %tI", time);
String minute = String.format("The Month is: %tM", time);
String seconds = String.format("The Century part of year is: %tS", time);
System.out.println("Time is: " + time);
System.out.println(hour);
System.out.println(minute);
System.out.print(seconds);
}
}
时间为:11:34:22.275791700
小时为:11
月为:34
年的世纪部分为:22
格式化大写和小写
我们可以格式化某些数据类型,如字符串、字符、大写或小写的布尔值。对于大写,我们可以使用大写转换字符。例如, %S 将字符串转换为大写, %C 将字符转换为大写。
public class Demo
{
public static void main(String[] args)
{
String str1 = String.format("Boolean Uppercase: %B", false);
String str2 = String.format("String Uppercase: %S", "Hello World");
String str3 = String.format("String Uppercase: %C", 'c');
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
}
}
布尔大写:FALSE
字符串大写:HELLO WORLD
字符串大写:C
没有转换字符可以将大写转换为小写。例如,%s 不会将“HELLO WORLD”转换为小写。
public class Demo
{
public static void main(String[] args)
{
String str1 = String.format("String: %s", "HELLO WORLD");
String str2 = String.format("Character: %c", 'C');
System.out.println(str1);
System.out.println(str2);
}
}
字符串:HELLO WORLD
字符:C
格式化数字和浮点
我们可以使用数字转换字符来格式化数据类型,如 int、short、byte 和 long。
- %d 格式为十进制数(以 10 为基数)。
- %o 转换为八进制表示(基数 8) 。
- %x 转换为十六进制数(基数 16) 。%X 会将字符改为大写。
public class Demo
{
public static void main(String[] args)
{
String decimal = String.format("Decimal: %d", 43);
String octal = String.format("Octal: %o", 43);
String hexaUppercase = String.format("Hexadecimal(Uppercase): %X", 43);
String hexaLowercase = String.format("Hexadecimal(Lowercase): %x", 43);
System.out.println(decimal);
System.out.println(octal);
System.out.println(hexaUppercase);
System.out.println(hexaLowercase);
}
}
十进制:43
八进制:53
十六进制(大写):2B
十六进制(小写):2B
%f 转换字符用于双精度或浮点等浮点数据类型。我们也可以使用 %e 或 %E (大写的“E”字符)来格式化科学符号。
public class Demo
{
public static void main(String[] args)
{
String str1 = String.format("Floating Point: %f", 102301.12022);
String str2 = String.format("Scientific Notation: %e", 102301.12022);
String str3 = String.format("Scientific Notation(Uppercase): %E", 102301.12022);
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
}
}
浮点:102301.120220
科学记数法:1.023011e+05
科学记数法(大写):1.023011e+05
抛出异常
当格式化字符串为空时,String.format()方法抛出空指针异常。
public class Demo
{
public static void main(String[] args)
{
double marks = 15.21;
String s = String.format(null, marks);
System.out.print(s);
}
}
在 Java . base/Java . util . regex . matcher . gettextlength(matcher . Java:1770)
处的线程“main”Java . lang . nullpointerexception
在 Java . base/Java . util . regex . matcher . reset(matcher . Java:416)
在 Java . base/Java . util . regex . pattern . matcher(pattern . Java:1133)处的 init>(Matcher.java:253)
该方法还抛出illegalformateexception或该异常的子类。当格式字符串的语法无效时,会出现此异常。下面的代码演示了这一点。
public class Demo
{
public static void main(String[] args)
{
double marks = 15.21;
try {
String s = String.format("%y", marks);
}
catch(Exception e){
System.out.print(e.getClass().getSuperclass().getName());
}
}
}
Java . util . illegal format exception
上面代码抛出的实际异常是未知格式转换异常。它是 IllegalFormatException 的子类。
public class Demo
{
public static void main(String[] args)
{
double marks = 15.21;
String s = String.format("%y", marks);
}
}
线程“main”中出现异常 Java . util . unknowntformaconversionexception:Conversion = ' y '
在 Java . base/Java . util . formatter $ format 说明符. Conversion(formatter . Java:2839)
在 java.base/java.util.Formatter$FormatSpecifier.
在 Java . base/Java . util . formatter . parse(formatter . Java:2713)
在 Java . base/Java . util . formatter . format(formatter . Java:2655)【异常
摘要
String.format()是将不同的参数连接成一个字符串的方便方法。它采用一个格式化字符串和一个变量对象作为参数和一个可选的区域设置。如果未提供明确的区域设置,则使用默认区域设置。请确保格式字符串的语法正确,以避免出现 IllegalFormatException。如果格式化字符串为空,则会出现空指针异常。
字符串和字节数组之间的转换
原文:https://www.studytonight.com/java-examples/conversion-between-string-and-byte-array
我们经常需要将一个字符串转换成字节数组(编码),或者将一个字节数组转换成字符串(解码)。字符串是 Unicode 字符值的序列(或数组)。我们可以将数组的每个字符映射到一个字节值,并生成一个字节数组。字符集提供字符和字节之间的映射。在编码和解码过程中需要这个字符集。在本教程中,我们将学习字符串和字节数组之间的转换。
字符串到字节数组(编码)
有几种方法可以从字符串中获取字节数组。让我们学习如何做到这一点。
使用 getBytes()方法
String 类的 getBytes()方法提供了一种获取字节数组的便捷方法。String
类包含 getBytes()方法的三个重载版本。
- getBytes() -使用平台的默认字符集生成字节数组。
- getBytes(字符串字符集名称)-使用提供的命名字符集生成字节数组。
- getBytes(字符集字符集)-使用字符集实例生成字节数组。
让我们使用其中的每一个并查看输出。
import java.util.Arrays;
public class Demo
{
public static void main(String[] args)
{
String s = "demo!";
byte[] byteArr = s.getBytes();
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字符串为字节:[100,101,109,111,33]
没有任何字符集的 getBytes()方法使用平台的默认字符集。这使得字节数组依赖于平台,在其他系统上可能无法正确解码。我们可以通过使用 Charset.defaultCharset()方法来查看默认的字符集。
import java.nio.charset.Charset;
public class Demo
{
public static void main(String[] args)
{
System.out.print("Default Charset: " + Charset.defaultCharset());
}
}
默认字符集:UTF-8
字符串获取字节(字符串字符集名)方法
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Demo
{
public static void main(String[] args) throws UnsupportedEncodingException
{
String s = "demo!";
String namedCharset = "UTF-16";
byte[] byteArr = s.getBytes(namedCharset);
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字节形式的字符串:[-2,-1,0,100,0,101,0,109,0,111,0,33]
我们需要确保使用有效命名的字符集。否则,我们将获得不支持编码异常。
import java.io.UnsupportedEncodingException;
public class Demo
{
public static void main(String[] args) throws UnsupportedEncodingException
{
String s = "demo!";
String namedCharset = "UTF-40";//UTF-40 is not a valid encoding
byte[] byteArr = s.getBytes(namedCharset);
}
}
线程“main”Java . io . unsupportdencodingenexception:UTF-40
在 Java . base/Java . lang . stringcoding . encode(stringcoding . Java:440)
在 Java . base/Java . lang . string . getbytes(string . Java:959)
在 Demo.main(Demo.java:10)
字符串获取字节(字符集)方法
import java.nio.charset.Charset;
import java.util.Arrays;
public class Demo
{
public static void main(String[] args)
{
String s = "demo!";
Charset charset = Charset.forName("UTF-16");
byte[] byteArr = s.getBytes(charset);
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字节形式的字符串:[-2,-1,0,100,0,101,0,109,0,111,0,33]
我们还可以使用标准字符集来创建字符集实例。
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class Demo
{
public static void main(String[] args)
{
String s = "demo!";
Charset charset = StandardCharsets.UTF_16;
byte[] byteArr = s.getBytes(charset);
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字节形式的字符串:[-2,-1,0,100,0,101,0,109,0,111,0,33]
使用字符集实例将用默认替换字节替换不支持的字符。在不支持字符的情况下,其他两个重载没有定义的行为。我们可以在下面的输出中看到,所有表情符号都被默认替换字节值 63 所替换。
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class Demo
{
public static void main(String[] args)
{
String s = "demo????????????";
Charset charset = StandardCharsets.ISO_8859_1;
byte[] byteArr = s.getBytes(charset);
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字符串为字节:[100,101,109,111,63,63,63]
使用字符集编码()方法
我们可以直接使用 Charset 类的 encode()方法,而不是使用 getBytes(Charset charset)方法。此方法还将使用默认替换字节来替换不支持的字符。它返回一个 CharBuffer,我们使用 array()方法将其转换为字节数组。
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class Demo{
public static void main(String args[])
{
String s = "demo????????????";
Charset charset = StandardCharsets.ISO_8859_1;
byte[] byteArr = charset.encode(s).array();
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字符串为字节:[100,101,109,111,63,63,63,0,0,0]
使用字符集编码器
CharsetEncoder 为我们提供了更多对编码过程的控制。我们可以在不支持的字符或格式错误的输入(如果字符序列不是有效的 Unicode 序列)的情况下定义编码。
我们将首先创建一个字符集编码器,并定义编码过程。我们可以使用像 onMalformedInput()或 onUnmappableCharacter()这样的方法来实现这一点。
接下来,我们将使用 encode()方法来执行编码。
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class Demo {
public static void main(String args[]) throws CharacterCodingException
{
String s = "demo????????????";
//Creating the encoder and defining the encoding behavior
CharsetEncoder charsetEncoder = StandardCharsets.ISO_8859_1.newEncoder();
charsetEncoder.onMalformedInput(CodingErrorAction.IGNORE);//Ignore malformed input
charsetEncoder.onUnmappableCharacter(CodingErrorAction.REPLACE)
.replaceWith(new byte[] {-121});//Replace unmappable character with 0
byte[] byteArr = charsetEncoder.encode(CharBuffer.wrap(s)).array();
System.out.print("String as Bytes: " + Arrays.toString(byteArr));
}
}
字符串为字节:[100,101,109,111,-121,-121,-121,0,0,0]
在上面的代码中,我们忽略了格式错误的输入,我们用-121 替换了不可映射的字符(在我们的例子中是表情符号)。我们也可以使用 REPORT 返回一个 CoderResult 对象或者抛出一个 CharacterCodingException。
字节数组到字符串
就像编码一样,解码也需要字符集。让我们学习如何解码字节数组以获取底层字符串。
使用字符串构造器
字符串构造器可以接受一个字节数组,并使用该数组初始化一个字符串。这种方法与 getBytes()方法正好相反。
我们只需要将字节数组传递给构造器,字符串将使用系统的默认字符集生成。不建议使用这种方法,因为字符串可能没有使用相同的默认字符集进行编码。在下面的示例中,原始字符串是使用 UTF-16 字符集编码的,但是系统的默认解码是 UTF-8。因为它,我们不会得到预期的结果。
public class Demo
{
public static void main(String args[])
{
byte[] byteArr = {-2, -1, 0, 100, 0, 101, 0, 109, 0, 111, 0, 33};//the original string is "demo!"
String stringFromBytes = new String(byteArr);
System.out.print("String from the byte array: " + stringFromBytes);
}
}
字节数组中的字符串:??d e m o!
使用命名字符集:
我们还可以向构造器传递一个命名字符集。如果提到无效字符集,则会引发错误。
import java.io.UnsupportedEncodingException;
public class Demo
{
public static void main(String args[]) throws UnsupportedEncodingException
{
byte[] byteArr = {-2, -1, 0, 100, 0, 101, 0, 109, 0, 111, 0, 33};//the original string is "demo!"
String stringFromBytes = new String(byteArr, "UTF-16");
System.out.print("String from the byte array: " + stringFromBytes);
}
}
字节数组中的字符串:演示!
使用字符集实例:
字符串构造器也可以采用一个字符集类实例进行解码。
import java.nio.charset.Charset;
public class Demo
{
public static void main(String args[])
{
byte[] byteArr = {-2, -1, 0, 100, 0, 101, 0, 109, 0, 111, 0, 33};//the original string is "demo!"
Charset charset = Charset.forName("UTF-16");
String stringFromBytes = new String(byteArr, charset);
System.out.print("String from the byte array: " + stringFromBytes);
}
}
字节数组中的字符串:演示!
我们也可以使用标准字符集。
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class Demo
{
public static void main(String args[])
{
byte[] byteArr = {-2, -1, 0, 100, 0, 101, 0, 109, 0, 111, 0, 33};//the original string is "demo!"
Charset charset = StandardCharsets.UTF_16;
String stringFromBytes = new String(byteArr, charset);
System.out.print("String from the byte array: " + stringFromBytes);
}
}
字节数组中的字符串:演示!
使用 Charset.decode()方法
像 encode()方法一样,Charset 类提供了一个 decode()方法来解码字节数组。如果数组包含无效输入,则用默认字符替换它。
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class Demo
{
public static void main(String[] args)
{
byte[] byteArr = {-2, -1, 0, 100, 0, 101, 0, 109, 0, 111, 0, 33, -10};
Charset charset = StandardCharsets.UTF_16;
String stringFromBytes = charset.decode(ByteBuffer.wrap(byteArr)).toString();
System.out.print("String from byte array: " + stringFromBytes);
}
}
字节数组中的字符串:演示!?
使用字符集解码器
上面讨论的所有方法都在内部使用字符集解码器。它为我们提供了对解码过程的更多控制。就像字符集编码器一样,我们可以忽略、替换或报告不可映射的字符或格式错误的字符。在下面的代码中,我们将这些字符替换为星号(*)。
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
public class Demo
{
public static void main(String[] args) throws CharacterCodingException
{
byte[] byteArr = {-2, -1, 0, 100, 0, 101, 0, 109, 0, 111, 0, 33, -10};
CharsetDecoder charsetDecoder = StandardCharsets.UTF_16.newDecoder();
charsetDecoder.onUnmappableCharacter(CodingErrorAction.REPLACE)
.onMalformedInput(CodingErrorAction.REPLACE)
.replaceWith("*");//Replace unmappable and malformed characters with *
String stringFromBytes = charsetDecoder.decode(ByteBuffer.wrap(byteArr)).toString();
System.out.print("String from Byte Array: " + stringFromBytes);
}
}
字节数组中的字符串:演示!*
摘要
有许多不同的方法可以将字符串转换为字节数组,反之亦然。String
类本身提供了三个重载的 getBytes()方法来创建一个字节数组。我们可以使用String
类构造器从字节数组中获取字符串。建议使用字符集编码器和字符集解码器进行转换。它们为编码和解码过程提供了更多的自由和控制。
在 Java 中将字符串转换为日期
原文:https://www.studytonight.com/java-examples/convert-string-to-date-in-java
字符串可以存储日期,但不能用于执行常见的日期操作,例如从日期中提取一年中的月份。在本教程中,我们将学习如何在 Java
中将字符串转换为日期,以便对其应用与日期相关的操作。
将字符串转换为本地日期和本地日期时间
String
对象可以使用parse()
方法轻松转换为LocalDate
和LocalDateTime
类的对象。确保字符串包含有效的日期和时间格式,否则我们可能会得到一个DateTimeParseException
。
public static void main(String[] args)
{
//LocalDate
String strDate = "2021-07-23";
LocalDate date = LocalDate.parse(strDate);
System.out.println(date);
//LocalDateTime
String strDateTime = "2021-07-23T10:30:59";
LocalDateTime dateTime = LocalDateTime.parse(strDateTime);
System.out.println(dateTime);
}
2021-07-23
2021-07-23t 10:30:59
这种方法的一个缺点是,如果字符串包含一些不被parse()
方法识别的其他日期格式,那么我们将得到一个DateTimeParseException
。下面的代码演示了这个场景。
public static void main(String[] args)
{
String strDate = "2021-July-23";
LocalDate date = LocalDate.parse(strDate);
System.out.println(date);
}
线程“main”Java . time . format . datetime arseeexception 中的异常:无法在索引 5 处解析文本“2021-7-23”
使用自定义格式化器将String
转换为Date
有时字符串可能包含其他格式的日期,parse()
方法可能无法识别这种格式。在这种情况下,我们可以使用自定义格式化器。Java 有一个DateTimeFormatter
类和一个SimpleDateFormat
类,可以用来为我们的字符串指定一种格式。然后,我们可以使用这些类的parse()
方法来解析字符串,并将其转换为适当的日期。
下面的列表显示了格式化字符串时最常用的日期和时间模式。
- 像 2021 年,或者 21 年
- 一年中的 m 月,比如 7 月,或者 07 年
- 一个月中的第几天
- 像星期五或 Fri 这样的电子日名称
- 上午/下午标记
- 小时(0-23)
- 上午和下午的小时数(0-12)
- 米-分钟(0-59)
- 秒(0-59)
下面显示了几个 DateTimeFormatter 类的例子。
格式日期-年-月-日
让我们尝试将一个简单的日期格式从字符串转换为本地日期。我们将使用 yyyy 作为年,单个 M 作为月,单个 d 作为月日。
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class demo
{
public static void main(String[] args)
{
String strDate1 = "2021-07-23";
DateTimeFormatter f1 = DateTimeFormatter.ofPattern("yyyy-M-d");
LocalDate d1 = LocalDate.parse(strDate1, f1);
System.out.println(d1);
}
}
2021-07-23
格式日期-日名、月名、年
现在,日期中还包含了日期名称。为了解析这个字符串,我们将使用 EEEE 作为全天名称。日期用 d ,月份用 M ,年份用yyy。
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class demo
{
public static void main(String[] args)
{
String strDate1 = "Friday, 23/07/2021";
DateTimeFormatter f1 = DateTimeFormatter.ofPattern("EEEE, d/M/yyyy");
LocalDate d1 = LocalDate.parse(strDate1, f1);
System.out.println(d1);
}
}
2021-07-23
格式日期-三个字母的日名、日月名、年
这一次,我们在字符串中有一个三个字母的日名称和完整的月名称。我们将使用 EEE 作为日名, MMMM 作为月名。字母 d 表示日期,yyy表示年份。
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class demo
{
public static void main(String[] args)
{
String strDate1 = "Fri, 23 July, 2021";
DateTimeFormatter f1 = DateTimeFormatter.ofPattern("EEE, d MMMM, yyyy");
LocalDate d1 = LocalDate.parse(strDate1, f1);
System.out.println(d1);
}
}
2021-07-23
格式的日期和时间-日-月-年时:分:秒上午/下午
我们也把时间包含在字符串中。对于时间的小时部分,我们将使用 HH 。几分钟内,我们将使用 mm ,几秒钟内,我们将使用 ss 。我们也将使用字母 a 表示上午和下午。
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class demo
{
public static void main(String[] args)
{
String strDate1 = "23-07-2021 10:30:59 AM";
DateTimeFormatter f1 = DateTimeFormatter.ofPattern("d-M-yyyy HH:mm:ss a");
LocalDate d1 = LocalDate.parse(strDate1, f1);
System.out.println(d1);
}
}
2021-07-23
简单日期格式类的工作如下所示。我们需要将代码放在一个 try-catch 块中,以避免 ParseException。
格式日期-年-月-日
我们用 yyyy 表示年份, M 表示月份,用单个 d 表示月份的日期。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo
{
public static void main(String[] args)
{
String strDate1 = "2021-07-23";
SimpleDateFormat f1 = new SimpleDateFormat("yyyy-M-d");
try
{
Date d1 = f1.parse(strDate1);
System.out.println(d1);
}
catch(ParseException e)
{
System.out.println(e);
}
}
}
寒冷的 7 月 23 日 00:00:00 是 2021
格式日期-全天名称,年月日
我们将使用 EEEE 作为完整的日名称来解析带有日名称的字符串。日期用 d ,月份用 M ,年份用yyy。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo
{
public static void main(String[] args)
{
String strDate1 = "Friday, 23/07/2021";
SimpleDateFormat f1 = new SimpleDateFormat("EEEE, d/M/yyyy");
try
{
Date d1 = f1.parse(strDate1);
System.out.println(d1);
}
catch(ParseException e)
{
System.out.println(e);
}
}
}
fri jul 23:00:00 是 2021
格式日期-三个字母的日名、日月名、年
三个字母的日名可以用 EEE 来表示。我们将使用 MMM 作为完整的月份名称。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo
{
public static void main(String[] args)
{
String strDate1 = "Fri, 23 July, 2021";
SimpleDateFormat f1 = new SimpleDateFormat("EEE, d MMM, yyyy");
try
{
Date d1 = f1.parse(strDate1);
System.out.println(d1);
}
catch(ParseException e)
{
System.out.println(e);
}
}
}
fri jul 23:00:00 是 2021
格式的日期和时间-日-月-年时:分:秒上午/下午
对于时间的小时部分,我们将使用 HH 。使用 mm 分钟,我们将使用 ss 秒钟。我们也将使用字母 a 表示上午和下午。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo
{
public static void main(String[] args)
{
String strDate1 = "23-07-2021 10:30:59 AM";
SimpleDateFormat f1 = new SimpleDateFormat("d-M-yyyy HH:mm:ss a");
try
{
Date d1 = f1.parse(strDate1);
System.out.println(d1);
}
catch(ParseException e)
{
System.out.println(e);
}
}
}
fri jul 23:00:00 是 2021
使用时区
日期字符串中的字符 Z 用于表示时区。默认情况下,SimpleDateFormat 类将显示我们为 JVM 设置的时区。我们可以使用 SimpleDateFormat 类的 setTimeZone()方法来查看不同的时间。然后,这个时间被转换为 JVM 时区。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class demo
{
public static void main(String[] args)
{
String strDate1 = "23-07-2021 10:30:59Z";
SimpleDateFormat f1 = new SimpleDateFormat("d-M-yyyy HH:mm:ss");
SimpleDateFormat f2 = new SimpleDateFormat("d-M-yyyy HH:mm:ss");
f2.setTimeZone(TimeZone.getTimeZone("GMT"));
try
{
Date d1 = f1.parse(strDate1);
Date d2 = f2.parse(strDate1);
System.out.println(d1);
System.out.println(d2);
}
catch(ParseException e)
{
System.out.println(e);
}
}
}
Fri Jul 23 10:30:59 是 2021
Fri Jul 23 16:00:59 是 2021
我们也可以使用 ZonedDateTime 来处理时区。
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class demo
{
public static void main(String[] args)
{
DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
ZonedDateTime z1 = ZonedDateTime.parse("2021-07-23 10:30:59 Europe/London", f);
ZonedDateTime z2 = ZonedDateTime.parse("2021-07-23 10:30:59 Europe/Madrid", f);
System.out.println(z1);
System.out.println(z2);
}
}
2021-07-23t 10:30:59+01:00[欧洲/伦敦]
2021-07-23t 10:30:59+02:00[欧洲/马德里]
使用 Apache 公共语言 3
Apache Commons 是一个著名的库,它提供了一个 DateUtils 类来处理日期。我们可以通过使用 parseDate()方法并传递一个日期格式数组来将字符串转换为日期。
import java.text.ParseException;
import java.util.Date;
import org.apache.commons.lang3.time.DateUtils;
public class StringToDate
{
public static void main(String[] args)
{
try
{
String dateInString = "2021-07-23";
Date date = DateUtils.parseDate(dateInString, new String[] {"yyyy-MM-dd"});
System.out.println(date);
}
catch (ParseException e)
{
System.out.print(e);
}
}
}
寒冷的 7 月 23 日 00:00:00 是 2021
摘要
本教程解释了如何将字符串转换为日期。如果我们只想存储日期并打印它们,字符串就可以了,但是它们不允许我们执行日期值的其他操作。我们可以使用 LocalDate 和 LocalDateTime 类的 parse()方法将包含日期的字符串转换为标准格式。如果字符串是其他日期格式,那么我们可以使用 DateTimeFormatter 类或 SimpleDateFormat 类定义一个自定义格式化器。
Java 字符串连接
原文:https://www.studytonight.com/java-examples/java-string-concatenation
字符串连接是将多个字符串组合成一个字符串的过程。Java 提供了多种方法来执行字符串连接。让我们学习如何在 Java 中连接字符串。
使用加法运算符连接字符串
组合或添加字符串的最简单方法是使用加法运算符。该运算符被重载以处理字符串。下面的代码演示了它的工作原理。
public class ConcatenateStrings
{
public static void main(String[] args)
{
String str1 = "Concatenate";
String str2 = "Three";
String str3 = "Strings";
String concatString = str1 + str2 + str3;
System.out.println("The concatenated string is: " + concatString);
}
}
连接字符串是:连接三个字符串
使用字符串生成器连接字符串
Java 中的 StringBuilder 类用于将字符串表示为可变字符数组。我们可以使用这个类的**append()**
方法将另一个字符串追加(或添加到末尾)到StringBuilder
中已经存在的字符串。最后,我们可以使用**toString()**
方法将 StringBuilder 对象转换为字符串。我们必须创建适当大小的 StringBuilder 对象来容纳字符串。
假设,我们有三个字符串,我们想要创建第四个字符串,它是这三个字符串的组合。我们将使用下面的代码来实现这一点。
public class ConcatenateStrings
{
public static void main(String[] args)
{
String str1 = "Concatenate";
String str2 = "Three";
String str3 = "Strings";
StringBuilder strBuilder = new StringBuilder(40);
strBuilder.append(str1);
strBuilder.append(str2);
strBuilder.append(str3);
String concatString = strBuilder.toString();
System.out.println("The concatenated string is: " + concatString);
}
}
连接字符串是:连接三个字符串
使用String.concat()
方法连接字符串
字符串类还提供了多种方法来连接字符串,其中一种方法是**String.concat()**
。下面的代码将三个字符串连接成一个字符串。
public class ConcatenateStrings
{
public static void main(String[] args)
{
String str1 = "Concatenate";
String str2 = "Strings";
String concatString = str1.concat(str2);
System.out.println("The concatenated string is: " + concatString);
}
}
连接字符串为:连接字符串
我们也可以多次使用concat()
方法在一行代码中连接两个以上的字符串。
public class ConcatenateStrings
{
public static void main(String[] args)
{
String str1 = "Concatenate";
String str2 = "Three";
String str3 = "Strings";
String str4 = "Into";
String str5 = "One";
String concatString = str1.concat(str2).concat(str3).concat(str4).concat(str5);
System.out.println("The concatenated string is: " + concatString);
}
}
连接字符串为:连接三个字符串一个
使用String.format()
方法连接字符串
字符串类的format()
方法可用于将字符串格式化为单个字符串。它采用格式字符串和要连接的字符串作为参数,并返回组合字符串。
public class ConcatenateStrings
{
public static void main(String[] args)
{
String str1 = "Concatenate";
String str2 = "Three";
String str3 = "Strings";
String concatString = String.format("%s%s%s", str1, str2, str3);
System.out.println("The concatenated string is: " + concatString);
}
}
连接字符串是:连接三个字符串
我们还可以在字符串之间添加分隔符,并使用精度修饰符仅追加字符串的前几个字符。例如,在下面的代码中,我们添加星号作为分隔符,并且只获取第三个字符串的前三个字符。
public class ConcatenateStrings
{
public static void main(String[] args)
{
String str1 = "Concatenate";
String str2 = "Three";
String str3 = "Strings";
String concatString = String.format("%s*%s*%.3s", str1, str2, str3);
System.out.println("The concatenated string is: " + concatString);
}
}
连接字符串为:连接三字符串
使用String.join()
方法连接字符串
Java 8 的String.join()
方法可以用来将多个字符串连接成一个字符串。我们还需要传递一个分隔符,组合字符串将使用这个分隔符来分隔原始字符串。如果我们不想添加任何其他内容,也可以传递一个空字符串作为分隔符。例如,如果要连接的字符串是“Hello”和“World”,如果我们将分隔符作为“-”传递,那么组合的字符串将是“Hello-World”。
public class ConcatenateStrings
{
public static void main(String[] args)
{
String str1 = "Concatenate";
String str2 = "Three";
String str3 = "Strings";
String concatString = String.join("*", str1, str2, str3);
System.out.println("The concatenated string is: " + concatString);
}
}
连接字符串为:连接三个字符串
使用StringJoiner
类连接字符串
StringJoiner
类的工作方式与上面讨论的join()
方法一样。它适用于 Java 8 及以上版本。我们需要初始化这个类的一个对象,并且需要向它的构造器传递一个分隔符。我们可以使用add()
方法给它附加字符串。我们可以使用 toString()方法从StringJoiner
对象中获取连接字符串。
import java.util.StringJoiner;
public class ConcatenateStrings
{
public static void main(String[] args)
{
String str1 = "Concatenate";
String str2 = "Three";
String str3 = "Strings";
StringJoiner sj = new StringJoiner("*");
sj.add(str1);
sj.add(str2);
sj.add(str3);
String concatString = sj.toString();
System.out.println("The concatenated string is: " + concatString);
}
}
连接字符串为:连接三个字符串
我们还可以向构造器传递一个可选前缀和后缀。
import java.util.StringJoiner;
public class ConcatenateStrings
{
public static void main(String[] args)
{
String str1 = "Concatenate";
String str2 = "Three";
String str3 = "Strings";
String delimiter = "*";
String prefix = "##";
String suffix = "$$";
StringJoiner sj = new StringJoiner(delimiter, prefix, suffix);
sj.add(str1);
sj.add(str2);
sj.add(str3);
String concatString = sj.toString();
System.out.println("The concatenated string is: " + concatString);
}
}
连接字符串为:# #连接三个字符串$$
使用Arrays
类连接字符串
Arrays
类的toString()
方法也可以用于将字符串数组转换为单个组合字符串。但是,连接字符串将包含方括号,原始字符串将由逗号分隔。例如,如果数组是{“Hello”,“Hola”,“Ola”},并且我们对它使用了 toString()方法,那么它将返回字符串“[Hello,Hola,Ola]”。
import java.util.Arrays;
public class ConcatenateStrings
{
public static void main(String[] args)
{
String[] strArray = {"Concatenate", "Three", "Strings"};
String concatString = Arrays.toString(strArray);
System.out.println("The concatenated string is: " + concatString);
}
}
连接字符串为:【连接,三,字符串】
摘要
在 Java 中,连接字符串非常简单。组合字符串最简单的方法是使用加法运算符。我们还有很多其他方法和类可以在 Java 中用于连接。我们还可以添加分隔符来区分连接字符串中的原始字符串。可以使用String.join()
方法和StringJoiner
类添加分隔符。
一个由几个字符串组成的数组可以通过Arrays.toString()
方法转换成一个数组,但是我们的字符串中会出现不需要的字符。我们可以通过将字符串数组传递给 String.join()方法来连接字符串数组。
如何在 Java 中检查字符串是否为数字?
原文:https://www.studytonight.com/java-examples/how-to-check-if-a-string-is-numeric-in-java
字符串是一种非常常用的数据类型,可以用于各种任务。每当我们从文本字段或文本区域获取输入时,输入总是一个字符串。假设我们需要检查来自文本字段的输入是否是有效的数字。
在本教程中,我们将学习如何检查字符串是否是有效的数字。
通过分析检查字符串是否为数字
解析字符串可能是判断字符串是否是数字的最简单也是最好的方法。一些常见的内置解析方法如下所示。
- 整数.解析整数(字符串数)
- Double.parseDouble(字符串数字)
- Float.parseFloat(字符串编号)
- 长.秒长(字符串数)
这些方法将解析字符串,并将其转换为相应的数字数据类型(如 Double 或 Integer)。
如果这些方法没有抛出 NumberFormatException
,那么我们可以放心地假设这个字符串是数字。
请注意,如果传递空字符串,这些方法将抛出**NullPointerException**
。下面的代码演示了这个场景。
public static void main(String[] args)
{
String num = null;
Double d = Double.parseDouble(num);
}
在 Java . base/JDK . internal . math . floating decimal . readjavaformatstring(floating decimal . Java:1838)处的线程“main”Java . lang . nullpointerexception
在 Java . base/JDK . internal . math . floating decimal . parsedouble(floating decimal . Java:110)处的异常
在 Java . base/Java . lang . double . parsedouble(double . Java:549)处的异常
在 numericstring . main(numericstring)处的异常
示例:使用 parseDouble()方法
让我们使用 parseDouble()方法编写自己的方法。我们将使用试捕块来检测和捕捉NumberFormatException
。如果引发此异常,则该方法应返回 false。
public static boolean isStringNumeric(String number)
{
boolean isNumeric;
if(number == null)
isNumeric = false;
else
{
try
{
Double num = Double.parseDouble(number);
isNumeric = true;
}
catch(NumberFormatException e)
{
isNumeric = false;
}
}
return isNumeric;
}
public static void main(String[] args)
{
String num1 = "1001";
String num2 = "-101";
String num3 = "1a10";
String num4 = null;
System.out.println("String " + num1 + " is numeric: " + isStringNumeric(num1));
System.out.println("String " + num2 + " is numeric: " + isStringNumeric(num2));
System.out.println("String " + num3 + " is numeric: " + isStringNumeric(num3));
System.out.println("String " + num4 + " is numeric: " + isStringNumeric(num4));
}
字符串 1001 为数字:真
字符串-101 为数字:真
字符串 1a10 为数字:假
字符串 null 为数字:假
使用正则表达式检查字符串是否为数字
我们可以编写正则表达式来匹配字符串,并判断它们是否是数字。我们将使用字符串的 matches()方法来比较字符串数字和正则表达式。我们将使用正则表达式 "-?\d+(\。\d+)?”匹配字符串。让我们试着理解这个正则表达式。
- -?regex 的一部分通过查找连字符或减号(-),检查 is 数字是否为负数。问号用于使连字符的出现成为可选的,因为数字也可以是正数。
- \d+ 搜索字符串中的一个或多个数字。
- (\。\d+)?用于匹配带有十进制数字的数字。\.搜索小数点,\d+查找小数点后的一个或多个数字。结尾的问号表示括号内的整个正则表达式部分是可选的,因为数字可能不是小数。
我们还需要确保字符串不为空,以避免出现NullPointerException
。
public static boolean isStringNumeric(String number)
{
boolean isNumeric;
String regex = "-?\\d+(\\.\\d+)?";
if(number == null)
isNumeric = false;
else if(number.matches(regex))
isNumeric = true;
else
isNumeric = false;
return isNumeric;
}
public static void main(String[] args)
{
String num1 = "1001";
String num2 = "-101";
String num3 = "1a10";
String num4 = null;
System.out.println("String " + num1 + " is numeric: " + isStringNumeric(num1));
System.out.println("String " + num2 + " is numeric: " + isStringNumeric(num2));
System.out.println("String " + num3 + " is numeric: " + isStringNumeric(num3));
System.out.println("String " + num4 + " is numeric: " + isStringNumeric(num4));
}
字符串 1001 为数字:真
字符串-101 为数字:真
字符串 1a10 为数字:假
字符串 null 为数字:假
使用 Apache 公共库检查字符串是否为数字
Apache Commons 库提供了一些不同的方法,可以直接用来检查字符串是否是数字。让我们分别看每一个。
NumberUtils.isCreatable()方法
isCreatable()是一种简单方便的方法,可用于检查字符串是否为数字。它还接受以 0x 或 oX 开头的十六进制数字字符串、以 0 开头的八进制数字、使用字母 e 的科学符号,并且还接受用类型限定符标记的数字。
import org.apache.commons.lang3.math.NumberUtils;
public static void main(String[] args)
{
String num1 = "a10c";
String num2 = "-104";
String num3 = "100";
String num4 = "0xA10";
System.out.println("String " + num1 + " is numeric: " + NumberUtils.isCreatable(num1));
System.out.println("String " + num2 + " is numeric: " + NumberUtils.isCreatable(num2));
System.out.println("String " + num3 + " is numeric: " + NumberUtils.isCreatable(num3));
System.out.println("String " + num4 + " is numeric: " + NumberUtils.isCreatable(num4));
}
字符串 a10c 为数字:假
字符串-104 为数字:真
字符串 100 为数字:真
字符串 0xA10 为数字:真
NumberUtils.isParsable()方法
如前一节所述,如果一个字符串是可解析的,那么它就是一个数字字符串。isParsable()方法用于检查字符串是否可解析。它不能使用十六进制数字或科学符号,如 isCreatable()方法。
import org.apache.commons.lang3.math.NumberUtils;
public static void main(String[] args)
{
String num1 = "a10c";
String num2 = "-104";
String num3 = "100";
String num4 = "0xA10";
System.out.println("String " + num1 + " is numeric: " + NumberUtils.isParsable(num1));
System.out.println("String " + num2 + " is numeric: " + NumberUtils.isParsable(num2));
System.out.println("String " + num3 + " is numeric: " + NumberUtils.isParsable(num3));
System.out.println("String " + num4 + " is numeric: " + NumberUtils.isParsable(num4));
}
字符串 a10c 为数字:假
字符串-104 为数字:真
字符串 100 为数字:真
字符串 0xA10 为数字:假
StringUtils.isNumeric()方法
也可以使用 isNumeric()方法,但是它比其他方法稍微不太灵活。它将只检查 Unicode 数字,如果数字字符串表示负数或包含小数点,它将返回 false。所以这个方法只有在我们只是检查正整数的情况下才应该考虑。
import org.apache.commons.lang3.StringUtils;
public static void main(String[] args)
{
String num1 = "a10c";
String num2 = "-104";
String num3 = "100";
String num4 = "0.11";
System.out.println("String " + num1 + " is numeric: " + StringUtils.isNumeric(num1));
System.out.println("String " + num2 + " is numeric: " + StringUtils.isNumeric(num2));
System.out.println("String " + num3 + " is numeric: " + StringUtils.isNumeric(num3));
System.out.println("String " + num4 + " is numeric: " + StringUtils.isNumeric(num4));
}
字符串 a10c 为数字:假
字符串-104 为数字:假
字符串 100 为数字:真
字符串 0.11 为数字:假
StringUtils.isNumericSpace()方法
isNumericSpace()类似于 isNumeric()方法。唯一的补充是 isNumericSpace()也会检查空间。如果字符串的类型是“19 8”,那么这个方法将返回 true。如果字符串仅由空格组成,它也将返回 true。
public static void main(String[] args)
{
String num1 = "a10c";
String num2 = " ";
String num3 = "100";
String num4 = "0.11";
System.out.println("String " + num1 + " is numeric: " + StringUtils.isNumeric(num1));
System.out.println("String " + num2 + " is numeric: " + StringUtils.isNumeric(num2));
System.out.println("String " + num3 + " is numeric: " + StringUtils.isNumeric(num3));
System.out.println("String " + num4 + " is numeric: " + StringUtils.isNumeric(num4));
}
字符串 a10c 为数字:假
字符串为数字:假
字符串 100 为数字:真
字符串 0.11 为数字:假
摘要
有多种方法可以检查字符串是否为数字。我们可以解析这个字符串,如果我们没有得到一个数字格式异常,那么它就是一个数字字符串。我们还可以使用正则表达式和 matches()方法来检查数字字符串。Apache Commons 库也提供了一些检查数字字符串的方法。
Java 字符串split()
方法
原文:https://www.studytonight.com/java-examples/java-string-split-method
split()方法用于根据某个字符(分隔符)或正则表达式将字符串拆分为字符串数组。对于简单的日常任务,如从句子中提取单词或从段落中提取句子,这是一种非常有用的方法。这个 Java 方法也用于令牌化。让我们学习如何在 Java 中使用 split()方法。
方法签名
string split()方法有两个签名。我们可以简单地传递正则表达式或用于拆分字符串的分隔符。
public String[] split(String regularExpression)
我们还可以传递一个额外的整数参数 limit 来表示主字符串应该拆分成的最大字符串数。
public String[] split(String regularExpression, int limit)
- split()方法返回字符串数组。数组长度应小于或等于限制。
- 如果未将限制传递给方法,或者将限制设置为 0 或任何小于 0 的值,则返回的数组大小不受限制。
- 对于大于 0 的任何其他限制,该模式将最多应用 (limit - 1) 次,并且返回数组的最后一个字符串将具有最后一个匹配模式之后的所有字符。
字符串拆分()示例
让我们看一些例子来更好地理解 split()方法的工作原理。
例 1
让我们试着把一个简单的句子分成几个单词。为了简单起见,句子中只有用空格隔开的单词,不会使用其他标点符号。我们将使用 \s 作为代表空白的分隔符。我们不会传递极限参数。
public static void main(String args[])
{
String sentence = "this is a simple sentence";
String[] words = sentence.split("\\s");
System.out.println("The words are: ");
for(int i = 0; i <= words.length - 1; i++)
System.out.println(words[i]);
}
单词是:
这个
是
一个
简单的
句子
如果我们将极限参数作为 0 传递,上述代码的输出不会改变。下面的代码演示了这一点。
public static void main(String args[])
{
String sentence = "this is a simple sentence";
int limit = 0;
String[] words = sentence.split("\\s", limit);
System.out.println("The words are: ");
for(int i = 0; i <= words.length - 1; i++)
System.out.println(words[i]);
}
单词是:
这个
是
一个
简单的
句子
但是,如果我们传递一些其他的极限值,那么数组的最大长度将等于这个极限值。例如,如果我们将限制传递为 2,那么模式将只匹配 1 次(限制- 1),并且第一次匹配之后的所有字符都将包含在下一个字符串中。返回的数组只有两个字符串。
public static void main(String args[])
{
String sentence = "this is a simple sentence";
int limit = 2;
String[] words = sentence.split("\\s", limit);
System.out.println("The words are: ");
for(int i = 0; i <= words.length - 1; i++)
System.out.println(words[i]);
}
单词是:
这个
是一个简单的句子
现在,让我们通过一个大于句子字数的限制。这不会影响输出。
public static void main(String args[])
{
String sentence = "this is a simple sentence";
int limit = 7;
String[] words = sentence.split("\\s", limit);
System.out.println("The words are: ");
for(int i = 0; i <= words.length - 1; i++)
System.out.println(words[i]);
}
单词是:
这个
是
一个
简单的
句子
我们也可以通过一个负极限值,但是输出将保持不变。
public static void main(String args[])
{
String sentence = "this is a simple sentence";
int limit = -3;
String[] words = sentence.split("\\s", limit);
System.out.println("The words are: ");
for(int i = 0; i <= words.length - 1; i++)
System.out.println(words[i]);
}
单词是:
这个
是
一个
简单的
句子
示例:使用 Delimeter 拆分
现在,让我们试着拆分一个有标点符号如逗号和句号的句子。我们用来拆分的正则表达式将是“[\ \ p { Pick } \ \ s]+”。我们想把整个句子分开,所以我们不会设置限制。
public static void main(String args[])
{
String sentence = "this is: a simple. sentence, with! some? punctuation: marks.";
String regex = "[\\p{Punct}\\s]+";
String[] words = sentence.split(regex);
System.out.println("The words are: ");
for(int i = 0; i <= words.length - 1; i++)
System.out.println(words[i]);
}
单词是:
这个
是
一个
简单的
句子
加上
一些
标点
符号
示例:使用正则表达式拆分字符串
我们还可以将上述例子中获得的单个单词拆分成字符。让我们使用 split()方法两次,一次是将句子拆分成单词,然后将单词拆分成字符。
public static void main(String args[])
{
String sentence = "this is: a simple. sentence, with! some? punctuation: marks.";
String regex = "[\\p{Punct}\\s]+";
String[] words = sentence.split(regex);//splitting the sentence
String[] characters;
System.out.println("The words are: ");
for(int i = 0; i <= words.length - 1; i++)
{
characters = words[i].split("");//splitting the words
for(String character : characters)
System.out.print(character + " ");
System.out.println();
}
}
单词是:
t h I s
I s
a
s I m p l e
s e n t e n c e
w I t h
s o m e
p u n c t u a t I o n
m a r k s
摘要
在本教程中,我们学习了如何使用 split()方法拆分字符串。此方法采用正则表达式或分隔符作为输入,还采用可选的限制参数。如果正则表达式无效,那么它会抛出一个模式同步异常。它是处理字符串的一个很好的工具,可以在很多不同的情况下使用。
如何在 Java 中将InputStream
转换为字符串
原文:https://www.studytonight.com/java-examples/how-to-convert-inputstream-to-string-in-java
在这篇文章中,我们将使用InputStream
读取一个文件,然后将其转换为字符串。了解文件处理操作所需的转换和要求非常有用。
要转换输入流,有几种方法,下面介绍其中两种。我们使用 Java Scanner
类和 Java 8 Stream 概念将一个流转换成字符串。
这里,我们有一个示例文件 abc.txt ,其中包含一些数据,由 Scanner 类读取。
// abc.txt
Welcome to Studytonight.com
It is technical portal.
举例时间:
让我们创建一个从输入流中获取字符串的例子。InputStream
是 Java 中一个用来读取文件的接口,我们用 Scanner 类的nextLine()
方法读取文件数据并返回一个字符串。
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException{
File file = new File("abc.txt");
InputStream is = new FileInputStream(file);
Scanner s = new Scanner(is);
String s1 = "";
while(s.hasNext()) {
s1 += s.nextLine()+"\n";
}
System.out.println(s1);
is.close();
}
}
欢迎来到 Studytonight.com
是技术门户。
另一个例子的时间:
还有另一种从InputStream
获取字符串的方法,例如使用lines()
方法返回数据流,该数据流进一步由collect()
方法收集并作为字符串返回。最后,确保正确关闭文件连接。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) throws IOException{
File file = new File("abc.txt");
InputStream is = new FileInputStream(file);
String result = new BufferedReader(new InputStreamReader(is))
.lines().collect(Collectors.joining("\n"));
System.out.println(result);
is.close();
}
}
欢迎来到 Studytonight.com
是技术门户。
如何在 Java 中把字符串转换成字节
原文:https://www.studytonight.com/java-examples/how-to-convert-string-to-byte-in-java
在这篇文章中,我们将使用 Java 代码将字符串转换为字节。字符串是 Java 中的一个类,表示字符序列,字节用于引用字符串中每个字符的 Unicode 值。
要将字符串转换为字节,我们使用String
类的getBytes()
方法,该方法根据指定的字符集将该字符串编码为字节序列。如果未指定字符集,则使用平台的默认字符集。
字符集是 Java 中的一个类,它表示字符集,并提供创建解码器和编码器的方法,这些方法在压缩和解压缩技术中是有益的。
字符集支持以下标准字符集实现。
|
字符集
|
描述
|
| 美国-阿斯凯 | 七位 ASCII 码,也叫 ISO646-美国,也叫 Unicode 字符集的基本拉丁块 |
| 国际标准化组织 8859-1 | ISO 拉丁字母 1 号,a.k.a. ISO-LATIN-1 |
| UTF-8 | 八位统一通信系统转换格式 |
| UTF-16BE | 十六位统一通信系统转换格式,大端字节顺序 |
| UTF-16LE 编码 | 十六位统一通信系统转换格式,小端字节顺序 |
| UTF-16 | 十六位统一通信系统转换格式,字节顺序由可选的字节顺序标记标识 |
举例时间:
让我们创建一个获取字符串字节数组的例子。这里,我们使用的是返回字节数组的getBytes()
方法。因为我们没有在这里指定字符集,所以它将使用默认平台的字符集。
public class Main {
public static void main(String[] args){
String msg = "StudyTonight.com";
System.out.println(msg);
// string to byte conversion
byte[] bytes = msg.getBytes();
System.out.println(bytes);
}
}
StudyTonight.com
【B @ 4d c 63996
示例:指定字符集
让我们创建另一个例子,通过为getBytes()
方法指定字符集来获取字节数组。这里,我们将UTF-8
设置为字符集,从字符串中获取字节转换。
import java.nio.charset.Charset;
public class Main {
public static void main(String[] args){
String msg = "StudyTonight.com";
System.out.println(msg);
// string to byte conversion
byte[] bytes = msg.getBytes(Charset.forName("UTF-8"));
System.out.println(bytes);
}
}
StudyTonight.com
【B @ 4d c 63996
示例:
如果我们想从我们在上面的例子中创建的字节数组中获得一个字符串,那么您可以使用String
类构造器,它接受字节数组作为参数,并返回一个字符串作为结果。
import java.nio.charset.Charset;
public class Main {
public static void main(String[] args){
String msg = "StudyTonight.com";
System.out.println(msg);
// string to byte conversion
byte[] bytes = msg.getBytes(Charset.forName("UTF-8"));
System.out.println(bytes);
// Byte to String
String str = new String(bytes);
System.out.println(str);
}
}
StudyTonight.com
【B @ 4d c 63996
StudyTonight.com
Java 字符串到数组的转换
原文:https://www.studytonight.com/java-examples/java-string-to-array-conversion
在这篇文章中,我们将使用 Java 代码将字符串转换为数组。字符串是一个字符序列和 Java 中的一个类,而数组是一个基于索引的数据结构,用于存储类似类型的元素。
这里,我们使用的是 String 类的split()
方法,该方法用于根据指定的分隔符拆分字符串并返回一个数组。
这是一个常见的日常编程任务,其中我们有一些文本字符串,并希望将其作为数组处理,因此我们需要显式地将其转换为数组。
转换非常简单,不需要很多行代码。我们只需要使用 split()方法,参见下面的示例。
举例时间:
让我们举个例子来理解字符串到字符串数组的转换。这里,我们根据空间分隔符拆分数组,得到一个数组。
public class Main {
public static void main(String[] args){
String msg = "StudyTonight.com is a technical portal";
System.out.println(msg);
// string to string array
String[] arg = msg.split(" ");
for (int i = 0; i < arg.length; i++) {
System.out.println(arg[i]);
}
}
}
StudyTonight.com 是一个技术门户
StudyTonight.com
是
一个
技术门户
另一个例子的时间:
假设,我们有一个URL
字符串,并希望将其作为一个数组,那么我们可以通过指定分隔符来拆分网址,如下例所示:“/”。它以字符串数组的形式返回网址字符串。
public class Main {
public static void main(String[] args){
String msg = "StudyTonight.com/tutorial/java/string";
System.out.println(msg);
// string to string array
String[] arg = msg.split("/");
for (int i = 0; i < arg.length; i++) {
System.out.println(arg[i]);
}
}
}
StudyTonight.com/tutorial/java/string
StudyTonight.com
教程
Java
弦
如何从字符串中删除数值
原文:https://www.studytonight.com/java-examples/how-to-remove-numeric-values-from-string
在这篇文章中,我们将使用 Java 代码从字符串中移除数值。字符串在 Java 中是用双引号(" ")括起来的字符序列。
字符串可以包含数字、字母和特殊符号。因此,有时我们需要过滤字符串,只得到字母。假设我们有一些用户名包含字母数字值,那么为了获得一个有效的用户名,我们需要通过删除其他字符来过滤它们。
这里,我们使用replaceAll()
方法,该方法接受两个参数,一个是正则表达式来过滤字符串,第二个是替换字符串。
正则表达式可以是从字符串中移除字符的任何有效正则表达式。
举个例子
让我们创建一个从字符串中移除数值的示例。这里,我们使用 replaceAll()方法和正则表达式['^A-Za-z']来只保留字符串中的字母。
public class Main {
public static void main(String[] args){
String str = "House123sector4";
System.out.println(str);
// Replacing
str = str.replaceAll("[^A-Za-z]", "");
System.out.println("String only:");
System.out.println(str);
}
}
房屋 123 部门 4【仅 T1】字符串:
房屋部门
例 1
让我们再举一个从字符串中移除数值的例子。这里,我们使用“\d”作为正则表达式,从字符串中删除所有数字并获得结果。
public class Main {
public static void main(String[] args){
String str = "House123sector4";
System.out.println(str);
// Replacing
str = str.replaceAll("\\d", "");
System.out.println("String only:");
System.out.println(str);
}
}
房屋 123 部门 4【仅 T1】字符串:
房屋部门
例 2
在本例中,我们向 replaceAll()方法传递了一个正则表达式[0-9],该方法在移除所有数字或数值后返回一个字符串。请看下面的例子。
public class Main {
public static void main(String[] args){
String str = "House123sector4";
System.out.println(str);
// Replacing
str = str.replaceAll("[0-9]", "");
System.out.println("String only:");
System.out.println(str);
}
}
房屋 123 部门 4【仅 T1】字符串:
房屋部门
如何计算一个字符在 Java 字符串中的出现次数
原文:https://www.studytonight.com/java-examples/how-to-count-occurrence-of-a-char-in-java-string
在这篇文章中,我们将使用 Java 代码计算字符串中某个字符的出现次数。字符串是一个字符序列,也可以包含重复的字符。
因此,如果任何字符串包含一个字符不止一次,并且我们想要检查该字符的出现,那么我们可以使用 String 类的几种方法来帮助找到字符频率。
这里,我们使用replace()
、charAt()
和filter()
方法来查找字符串中存在的字符。
举例时间:
让我们创建一个示例来查找字符串中出现的字符。这里,我们使用的是replace()
方法,它只返回一个包含‘a’的字符串,然后两个字符串长度的差就是结果。replace()方法并不意味着查找字符出现,但是我们可以使用它来构建一些逻辑代码,从而产生所需的结果。
public class Main {
public static void main(String[] args){
String str = "abracadabra-banana";
System.out.println(str);
// count occurrence
int count = str.length() - str.replace("a", "").length();
System.out.println("occurrence of a: "+count);
}
}
阿布拉卡达布拉-香蕉
的发生率为:8
示例:Java 8
我们再举一个例子来寻找字符频率。这里,我们使用返回流的chars()
方法,然后使用filter()
方法获取字符串中存在的所有‘a’。count()
方法用于计算过滤后的流。这里我们使用的是 Java 8 版本的 流 API 概念,请看下面的例子。
public class Main {
public static void main(String[] args){
String str = "abracadabra-banana";
System.out.println(str);
// count occurrence
long count = str.chars().filter(ch -> ch == 'a').count();
System.out.println("occurrence of a: "+count);
}
}
阿布拉卡达布拉-香蕉
的发生率为:8
示例:自定义代码
这是在字符串中查找字符数的常规解决方案。这里,我们使用一个循环遍历字符串中的每个字符,并通过使用charAt()
方法比较字符,该方法返回指定索引处的字符,最后计算一个字符是否与所需的字符匹配。
public class Main {
public static void main(String[] args){
String str = "abracadabra-banana";
System.out.println(str);
// count occurrence
int count = 0;
for (int i=0; i < str.length(); i++)
{
if (str.charAt(i) == 'a')
{
count++;
}
}
System.out.println("occurrence of a: "+count);
}
}
阿布拉卡达布拉-香蕉
的发生率为:8
如何在 Java 中反转字符串
原文:https://www.studytonight.com/java-examples/how-to-reverse-string-in-java
在这篇文章中,我们将反转一个字符串。字符串是一个字符序列,也是 Java 中用来处理字符串数据的一个类。
要反转一个字符串,我们可以使用 StringBuilder 类的reverse()
方法,或者用一种方便的方法将字符以相反的顺序排列成一个新的字符串。我们将借助例子来使用这两种方法。
StringBuilder 类似于 String 类,只是它是可变的。所以,它的内容是可以改变的。
reverse()方法不带任何参数,用于反转字符序列。它返回字符串生成器而不是字符串。所以,如果你想要字符串返回,那么使用toString()
方法得到一个字符串对象。
举例时间:
让我们创建一个例子来得到字符串的反义词。这里,我们使用 StringBuilder,并将字符串参数传递给 StringBuilder 的构造器。之后通过使用 StringBuilder 类的 reverse()方法,我们得到一个反向字符串。
public class Main {
public static void main(String[] args){
String str = "Studytonight";
System.out.println(str);
StringBuilder strb = new StringBuilder(str);
strb.reverse();
System.out.println(strb);
}
}
学习夜
体操运动员
示例:
让我们举另一个例子来反转一个字符串。这里,我们使用 charAt()方法获取字符串的单个字符,并追加到一个新的字符串对象中,以获得一个新的字符串。
public class Main {
public static void main(String[] args){
String str = "Studytonight";
System.out.println(str);
String str2 = "";
for (int i = str.length()-1; i>=0; i--) {
str2 += str.charAt(i);
}
System.out.println(str2);
}
}
学习夜
体操运动员
如何在 Java 中把浮点数转换成字符串
原文:https://www.studytonight.com/java-examples/how-to-convert-float-to-string-in-java
在这篇文章中,我们将在 Java 中将Float
类型转换为字符串。 Float 是一个保存浮点值的数据类型,而 String 是一个字符序列和 Java 中的一个类。
要将浮点转换为字符串,有几种方法,如String
类的valueOf()
方法或Float
类的toString()
方法,或将表达式转换为字符串的简单字符串文字。
valueOf()
方法属于返回指定值字符串的 String,Float 类的 to String()方法返回浮点值字符串。
在这里,我们将借助几个示例来查看所有这些转换。
举例时间:
让我们举一个例子,将 float 转换为 string。这里,我们使用 String 类的valueOf()
方法从浮点值中获取一个字符串。
public class Main {
public static void main(String[] args){
Float val = 12.50f;
System.out.println(val);
// Float to String
String str = String.valueOf(val);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
12.5
12.5
Java 郎
示例:使用 toString()方法进行转换
让我们创建另一个示例来从 float 类型获取字符串。这里,我们使用的是 Float 类的toString()
方法,该方法返回一个指定值的字符串。
public class Main {
public static void main(String[] args){
Float val = 12.50f;
System.out.println(val);
// Float to String
String str = Float.toString(val);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
12.5
12.5
Java 郎
示例:使用字符串进行转换
还有一种方法可以将 float 转换为 string。这里,我们使用一个字符串文字,并使用加号将它附加到浮点。这是 Java 的隐式转换,如果我们将任何类型连接到字符串文字,它将返回一个字符串。
public class Main {
public static void main(String[] args){
Float val = 12.50f;
System.out.println(val);
// Float to String
String str = ""+val;
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
12.5
12.5
Java 郎
如何在 Java 中把整型转换成字符串
原文:https://www.studytonight.com/java-examples/how-to-convert-int-to-string-in-java
在这篇文章中,我们将在 Java 中将 int 类型转换为 string。整数是一种保存浮点值的数据类型,而字符串是一个字符序列和 Java 中的一个类。
要将 int 转换为 string,有几种方法,如 String 类的valueOf()
方法或 Integer 类的toString()
方法,或者将表达式转换为 String 的简单字符串文字。
valueOf()
方法属于返回指定值字符串的 String,Integer
类的 to String()方法返回浮点值字符串。
在这里,我们将借助几个示例来查看所有这些转换。
举例时间:
让我们创建一个将 int 类型转换为字符串的示例。这里,我们使用的是从指定值返回字符串的valueOf()
方法。
public class Main {
public static void main(String[] args){
int val = 10;
System.out.println(val);
// int to String
String str = String.valueOf(val);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
10
10
Java 岛
示例:使用 to String()方法将 int 转换为 String
让我们创建另一个将 int 类型转换为 string 的示例。这里,我们使用的是返回整型值字符串的 toString()方法。
public class Main {
public static void main(String[] args){
int val = 10;
System.out.println(val);
// int to String
String str = Integer.toString(val);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
10
10
Java 岛
示例:使用字符串进行转换
这是 int 到String
类型的隐式转换。如果我们将任何类型的值连接成一个字符串,那么 Java 会将该表达式转换成一个字符串,并返回一个字符串作为结果。
public class Main {
public static void main(String[] args){
int val = 10;
System.out.println(val);
// int to String
String str = ""+val;
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
10
10
Java 岛
如何在 Java 中比较字符串
原文:https://www.studytonight.com/java-examples/how-to-compare-string-in-java
在这篇文章中,我们将比较 Java 中的两个 String 对象。在 Java 中,字符串是一个字符序列和一个类。
要比较两个对象,字符串提供了equals()
和compareTo()
方法。equals()方法用于比较两个 String 对象的内容,而 compareTo()则按字典顺序比较两个字符串,并返回一个整数值。
equals()方法返回 true 或 false。如果字符串对象相等,则返回 true,否则返回 false。
还有一种比较两个字符串对象的方法是= = "****运算符,用于比较这些字符串对象的两个内存引用。
**## 举例时间:
让我们创建一个比较两个字符串对象的例子。这里,我们使用的是返回布尔值的equals()
方法。
public class Main {
public static void main(String[] args){
String str1 = "Studytonight";
String str2 = "studytonight";
boolean val = str1.equals(str2);
System.out.println(val);
String str3 = str2;
val = str2.equals(str3);
System.out.println(val);
}
}
假
真
示例:使用相等运算符比较字符串
在本例中,我们使用 == (等于)运算符来比较两个字符串对象引用。它比较这两个字符串对象是否引用内存中的同一个字符串。它返回一个布尔值,要么是真要么是假。
public class Main {
public static void main(String[] args){
String str1 = "Studytonight";
String str2 = "studytonight";
boolean val = str1 == str2;
System.out.println(val);
String str3 = str2;
val = str2 == str3;
System.out.println(val);
}
}
假
真
示例:使用 compareTo()方法比较字符串
让我们再举一个例子来比较字符串。这里,我们使用compareTo()
方法,该方法根据字符串中每个字符的 Unicode 值来比较字符串。它返回一个正整数或负整数。
public class Main {
public static void main(String[] args){
String str1 = "Studytonight";
String str2 = "studytonight";
int val = str1.compareTo(str2);
System.out.println(val);
String str3 = str2;
val = str2.compareTo(str3);
System.out.println(val);
}
}
-32
0
如何在 Java 中替换字符串中的子字符串
原文:https://www.studytonight.com/java-examples/how-to-replace-substring-from-a-string-in-java
在这篇文章中,我们将替换 Java 中String
中的一个子字符串。子字符串可以是字符串的单个字符或多个字符,而字符串是 Java 中表示字符序列的类。
为了替换子串,我们使用replace()
和replaceFirst()
方法。replace()方法用于替换字符串中的子字符串,并在修改后返回一个字符串。
replaceFirst()
方法用于从字符串中替换第一个出现的子字符串,并在修改后返回一个新的字符串。
举例时间:
让我们创建一个示例来替换整个字符串中的单个字符。这里,我们使用 replace()方法将整个字符串中的‘A’替换为‘A’。
public class Main {
public static void main(String[] args){
String str = "abracadabra";
System.out.println(str);
// Replace a char in String
str = str.replace('a', 'A');
System.out.println(str);
}
}
阿布拉卡达布拉
阿布拉卡达布拉
示例:使用replace()
方法替换
让我们创建另一个示例来替换字符串中的子字符串。在这里,我们用replace()
方法将整个字符串中“AB”的所有出现替换为“AB”。
public class Main {
public static void main(String[] args){
String str = "abracadabra";
System.out.println(str);
// Replace substring in String
str = str.replace("ab", "AB");
System.out.println(str);
}
}
阿布拉卡达布拉
阿布拉卡达布拉
示例:使用replaceFirst()
方法替换
在本例中,我们使用 replaceFirst()方法替换字符串中第一个出现的子字符串。它在第一次匹配后停止搜索子字符串,并在替换子字符串后返回一个新字符串。
public class Main {
public static void main(String[] args){
String str = "abracadabra";
System.out.println(str);
// Replace substring in String
str = str.replaceFirst("ab", "AB");
System.out.println(str);
}
}
阿布拉卡达布拉
阿布拉卡达布拉
如何在字符串中查找单词或子字符串
原文:https://www.studytonight.com/java-examples/how-to-find-a-word-or-substring-in-string
在这篇文章中,我们在字符串中找到一个单词或子字符串。字符串是一个字符序列和 Java 中的一个类。
为了在字符串中找到一个单词,我们使用了String
类的 indexOf()和 contains()方法。
indexOf()
方法用于查找当前字符串中指定子串的索引。如果找到的子串 else 返回-1,则返回一个正整数作为索引。
contains()
方法用于检查字符串是否包含指定的字符串。它返回真或假的布尔值。如果找到指定的字符串,则返回 true,否则返回 false。
举例时间:
让我们创建一个在字符串中查找单词的示例。这里,我们使用的是 indexOf()方法,该方法返回指定子字符串的索引。请看下面的例子。
public class Main {
public static void main(String[] args){
String str = "This sentance contains find me string";
System.out.println(str);
// find word in String
String find = "find me";
int i = str.indexOf(find);
if(i>0)
System.out.println(str.substring(i, i+find.length()));
else
System.out.println("string not found");
}
}
本标志包含“找到我”字符串
找到我
例 2
让我们创建另一个示例来查找字符串中的单词。这里,我们使用的是contains()
方法,如果找到指定的字符串,该方法返回 true。请看下面的例子。
public class Main {
public static void main(String[] args){
String str = "This sentance contains find me string";
System.out.println(str);
// find word in String
String find = "find me";
boolean val = str.contains(find);
if(val)
System.out.println("String found: "+find);
else
System.out.println("string not found");
}
}
本标志包含找到我字符串
找到的字符串:找到我
如何在 Java 中重复字符串N
次
原文:https://www.studytonight.com/java-examples/how-to-repeat-string-n-times-in-java
在这篇文章中,我们将使用 Java 代码重复一个字符串 N 次。在处理字符串时,可能需要重复一个字符串,为此,Java 在String
类中提供了repeat()
方法。
repeat()
方法是从 Java 11 版本添加到 String 类中的。
有几种方法可以对一个字符串进行重复,像使用Collections
类的 nCopies()方法或者 repeat()方法或者 replace()方法对字符串也可以用来获取重复字符串。
示例时间:Java 11
让我们创建一个重复字符串的示例。这里,我们使用String
类的 repeat()方法。重复字符串是最简单的方法。这个方法被添加到 Java 11 版本的 String 类中。
public class Main {
public static void main(String[] args){
String str = "Studytonight";
System.out.println(str);
// Repeat String
String newStr = str.repeat(3);
System.out.println(newStr);
}
}
今晚学习
今晚学习今晚学习
示例:使用字符串构造器和replace()
方法重复
让我们创建一个例子,用 Java 重复字符串。这里我们用的是replace()
方法,用来替换字符串,但是用一些逻辑代码,我们可以用它来重复字符串。这里,我们使用 char 数组创建一个字符串,并用提供的字符串替换数组的默认值。
public class Main {
public static void main(String[] args){
String str = "Studytonight";
System.out.println(str);
// Repeat String
String newStr = new String(new char[3]).replace("\0", str);
System.out.println(newStr);
}
}
今晚学习
今晚学习今晚学习
示例:使用 Java 8 重复字符串
如果您使用的是 Java 8 或更高版本,那么您可以使用Collections
类的nCopies()
方法,该方法使用String
类的join()
方法连接到字符串中。
import java.util.Collections;
public class Main {
public static void main(String[] args){
String str = "Studytonight";
System.out.println(str);
// Repeat String
String newStr = String.join("", Collections.nCopies(3, str));
System.out.println(newStr);
}
}
今晚学习
今晚学习今晚学习
如何从字符串中删除空格
原文:https://www.studytonight.com/java-examples/how-to-remove-white-spaces-from-string
在这篇文章中,我们将删除 Java 中字符串的前导和尾随空格。前导空格和尾随空格被附加到字符串的开头和结尾。例如,字符串“今晚学习”可以有前导空格,如“今晚学习”和尾随空格“今晚学习”。
为了删除空格,Java String 类提供了strip()
、stripLeading()
和stripTrailing()
方法,这些方法是在 Java 11 版本中添加的。
strip()方法用于移除字符串的所有前导和尾随空格。它不接受任何参数,而是向调用方返回一个字符串。
stripLeading()方法用于从字符串中删除前导空格。如果我们想从字符串中只删除前导空格,那么您可以使用这个方法,而要只删除尾随空格,您可以使用 stripTrailing()方法。
示例时间:Java 11
让我们创建一个从字符串中删除空格的例子。这里,我们使用strip()
方法去除字符串中所有的前导和尾随空格。
public class Main {
public static void main(String[] args){
String str = " Studytonight";
System.out.println(str);
System.out.println("hello"+str);
// remove whitespace from String
String newStr = str.strip();
System.out.println(newStr);
System.out.println("hello"+newStr);
}
}
今晚学习
你好今晚学习
今晚学习
晚上好
示例:使用stripLeading()
方法移除
让我们创建另一个示例来删除字符串中的空格。这里我们使用的是stripLeading()
方法,去掉所有前导空格后返回一个字符串。
public class Main {
public static void main(String[] args){
String str = " Studytonight";
System.out.println(str);
System.out.println("hello"+str);
// remove whitespace from String
String newStr = str.stripLeading();
System.out.println(newStr);
System.out.println("hello"+newStr);
}
}
今晚学习
你好今晚学习
今晚学习
晚上好
示例:使用stripTrailing()
方法移除
让我们再创建一个示例来删除字符串中的空白。在这里,我们使用stripTrailing()
方法在移除所有尾随空格后获得一个字符串。请看下面的例子。
public class Main {
public static void main(String[] args){
String str = " Studytonight ";
System.out.println(str);
System.out.println("hello"+str+".com");
// remove whitespace from String
String newStr = str.stripTrailing();
System.out.println(newStr);
System.out.println("hello"+newStr+".com");
}
}
今晚学习
你好今晚学习。今晚学习你好,Studytonight.com
如何在 Java 中将字符数组转换成字符串
原文:https://www.studytonight.com/java-examples/how-to-convert-char-array-to-string-in-java
在这篇文章中,我们将把字符数组转换成 Java 中的字符串。字符数组是字符和对象的集合,而String
是字符序列和 Java 中的一个类。
在 Java 中,字符串是最常用的数据类型。所以,如果我们有一个字符数组,需要把它转换成字符串,那么我们需要把字符数组转换成字符串。
为了将字符数组转换成字符串,我们使用了String
类的构造器valueOf()
和copyValueOf()
方法。
string 类为 char 数组参数提供了一个构造器来创建字符串。我们用它从字符数组中获取字符串。
String
类的valueOf()
方法接受字符数组参数,并返回一个字符串作为结果。类似地,copyValueOf()
方法可以用来从 char 数组中获取字符串。这两种方法是相同的,我们可以使用其中的任何一种。
举例时间:
让我们创建一个从字符数组中获取字符串的例子。这里,我们使用一个字符串的构造器,它从一个字符数组中返回一个字符串。
public class Main {
public static void main(String[] args){
char[] ch = {'a','e','i','o','u'};
System.out.println(ch);
// convert char to string
String str = new String(ch);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
aeiou
aeiou
Java . lang . string
示例:使用 valueOf()方法进行转换
让我们创建另一个示例,从 char 数组中获取字符串。这里,我们使用valueOf()
方法将字符数组转换为字符串对象。
public class Main {
public static void main(String[] args){
char[] ch = {'a','e','i','o','u'};
System.out.println(ch);
// convert char to string
String str = String.valueOf(ch);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
aeiou
aeiou
Java . lang . string
示例:使用 copyValueOf()方法进行转换
这里,我们使用copyValueOf()
方法从一个字符数组中获取一个字符串。它与 valueOf()方法没有显著差异。
public class Main {
public static void main(String[] args){
char[] ch = {'a','e','i','o','u'};
System.out.println(ch);
// convert char to string
String str = String.copyValueOf(ch);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
aeiou
aeiou
Java . lang . string
如何在 Java 中连接字符串
原文:https://www.studytonight.com/java-examples/how-to-join-string-in-java
在这篇文章中,我们将使用 Java 代码将两个或多个字符串连接成一个字符串。我们将字符串连接成由分隔符分隔的单个字符串。例如,我们有两个字符串“印度”和“新德里”,那么在连接时,我们使用“-”分隔符,因此结果字符串将是“印度-新德里”。
要连接多个字符串,我们使用的是字符串类的join()
方法。join()
方法有两个重载版本,其中一个以字符串为参数,第二个以 iterable (list,set)为参数,连接后返回单个字符串。
举个例子:
让我们创建一个示例,在连接多个字符串后获取一个字符串。在这里,我们使用join()
方法,该方法将分隔符作为第一个参数,其他参数是字符串参数。
public class Main {
public static void main(String[] args){
String str1 = "Mango";
String str2 = "Orange";
String str3 = "Apple";
// Join all strings
String str = String.join("-", str1, str2, str3);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
芒果橙苹果
Java 郎串
示例:
让我们创建另一个连接字符串的例子。这里,我们使用join(
方法将字符串列表连接成单个字符串。我们用连字符(-)来连接字符串。
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args){
List <String> list = Arrays.asList("Mango","Orange","Apple");
// Join all strings
String str = String.join("-", list);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
芒果橙苹果
Java 郎串
示例:Java 8
如果你使用的是 Java 8 或更高版本,那么我们可以使用列表的stream()
方法,然后使用 Collectors 的joining()
方法将所有字符串收集成一个。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args){
List <String> list = Arrays.asList("Mango","Orange","Apple");
// Join all strings
String str = list.stream().collect(Collectors.joining("-"));
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
芒果橙苹果
Java 郎串
如何在 Java 中把字符转换成字符串
原文:https://www.studytonight.com/java-examples/how-to-convert-char-to-string-in-java
在这篇文章中,我们将在 Java 中将 char 转换为字符串。char 是用于存储单个字符的 Java 数据类型之一,而 String 是一个字符序列。
要将Character
类型转换为字符串,我们可以使用String
类的valueOf()
方法或字符类的toString()
方法。字符是 Java 中的一个包装类,用于处理Character
类型对象。
String 类的 valueOf()方法用于从字符中获取字符串。它接受一个参数并返回一个指定类型的字符串。
Character
类的 toString()方法返回一个Character
类型值的字符串。
我们还使用了加号(+)运算符将字符转换为字符串,因为该运算符用于连接两个对象并返回一个字符串。
举例时间:
让我们举一个将 char 转换成字符串的例子。这里,我们使用的是返回字符串的 String 类的valueOf()
方法。
public class Main {
public static void main(String[] args){
char ch = 's';
System.out.println(ch);
// char to String
String str = String.valueOf(ch);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
s
s
Java.郎.弦
示例:
让我们再举一个例子,从一个Character
类型中获取一个字符串。这里,我们使用的是 Character 类的toString()
方法,它通过转换 char 返回一个字符串。
public class Main {
public static void main(String[] args){
char ch = 's';
System.out.println(ch);
// char to String
String str = Character.toString(ch);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
s
s
Java.郎.弦
示例:
在本例中,我们使用加号(+)运算符将字符值与字符串值连接起来。加号运算符在连接后返回一个字符串值。
public class Main {
public static void main(String[] args){
char ch = 's';
System.out.println(ch);
// char to String
String str = ""+ch;
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
s
s
Java.郎.弦
如何在 Java 中将double
转换为字符串
原文:https://www.studytonight.com/java-examples/how-to-convert-double-to-string-in-java
在这篇文章中,我们将在 Java 中将 double 转换为 String 。double 是 Java 数据类型之一,用于存储大量浮点值,而 String 是一个字符序列。
要将 double 类型转换为 string,我们可以使用 String 类的valueOf()
方法或 Double 类的toString()
方法。Double 是 Java 中用于处理Double
类型对象的包装类。
String 类的 valueOf()方法用于从 double 获取字符串。它接受一个参数并返回一个指定类型的字符串。
Double 类的 toString()方法返回一个Double
类型值的字符串。
我们还使用了加号(+)运算符将 double 转换为 string,因为该运算符用于连接两个对象并返回一个字符串。
举例时间:
让我们举一个例子把 double 转换成 string。这里,我们使用的是返回字符串的 String 类的valueOf()
方法。
public class Main {
public static void main(String[] args){
double val = 21.50;
System.out.println(val);
// double to String
String str = String.valueOf(val);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
21.5
21.5
Java 郎
示例:
让我们再举一个例子,从双精度类型中获取一个字符串。这里,我们使用的是 double 类的toString()
方法,它通过转换 Double 返回一个字符串。
public class Main {
public static void main(String[] args){
double val = 21.50;
System.out.println(val);
// double to String
String str = Double.toString(val);
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
21.5
21.5
Java 郎
示例:
在本例中,我们使用加号(+)运算符将双精度值与字符串值连接起来。加号运算符在连接后返回一个字符串值。
public class Main {
public static void main(String[] args){
double val = 21.50;
System.out.println(val);
// double to String
String str = ""+val;
System.out.println(str);
System.out.println(str.getClass().getName());
}
}
21.5
21.5
Java 郎
如何在 Java 中将枚举转换为字符串
原文:https://www.studytonight.com/java-examples/how-to-convert-enum-to-string-in-java
在本文中,我们将把 Java 中的枚举转换为字符串。enum
在 Java 中定义常量方面非常方便。枚举是一种特殊类型的数据类型,是一组预定义的常数。Java 提供了在一个地方收集常量的功能。
在 Java 中,有两种方法可以将枚举转换为字符串。
- 使用内置的 name()方法
- 使用内置的 toString()方法
使用内置名称()方法将枚举转换为字符串
在下面的代码中,枚举常量的所有值都存储在枚举的数组中,然后在遍历这个数组时,我们调用name()
方法,该方法将以字符串格式返回相应的常量。
enum Course
{
JAVA, ANDROID, HTML, CSS
}
public class StudyTonight {
public static void main(String[] args) {
// here values() method returns all the instances of Enum
Course[] courses = Course.values();
System.out.println("Name of All Courses");
for(Course course: courses)
{
System.out.println(course.name());
}
}
}
所有课程名称
JAVA
安卓
HTML
CSS
这是在 java 中将枚举转换为字符串的最简单的方法,但是根据 java 文档:
name()方法主要设计用于特定的情况,在这些情况下,正确性取决于获得确切的名称,这不会因版本而异。
使用内置的 to String()方法将枚举转换为字符串
在第二种方法中,我们将利用 Java 特性,它允许程序员覆盖继承的方法。通过简单的覆盖toString()
方法,我们可以增加获取 String 的功能。
public class StudyTonight {
enum Course {
JAVA("Java"), ANDROID("Android"), HTML("HTML"), CSS("CSS");
String course_name;
//Constructor to define name
Course(String course_name) {
this.course_name = course_name;
}
//override the inherited method
@Override
public String toString() {
return course_name;
}
}
public static void main(String args[]) {
Course[] courses = Course.values();
System.out.println("Name of All Courses");
for (Course course: courses) {
System.out.println(course.toString());
}
}
}
所有课程名称
JAVA
安卓
HTML
CSS
在这里,你要记住toString()
方法必须是公开的,否则会给出这样一个错误:
错误:课程中的 toString()无法覆盖枚举字符串中的 toString(),toString()试图分配较弱的访问权限;
以上两种方法是在 Java 中将枚举转换为字符串的正确方法,但是除了这两种方法之外,还有其他方法可以做同样的事情。
类中的静态最终字符串,而不是枚举
静态最终字符串变量可以在与枚举相同的类之外访问,并且值不会改变,因此这也是直接使用字符串常量而不是枚举的另一种方式。
class ClassName{
public static final String CONSTANT= "CONSTANT";
}
例子
它是枚举的替代,我们可以在类中声明公共静态最终字符串变量,并且它可以作为常数在类外直接访问。请看下面的例子。
class Course
{
//declaration of all constant terms same as constants in enum
public static final String JAVA= "Java";
public static final String ANDROID= "Android";
public static final String HTML= "HTML";
public static final String CSS= "CSS";
}
public class StudyTonight
{
public static void main(String args[])
{
//this print statements will print all the constants
System.out.println(Course.JAVA);
System.out.println(Course.ANDROID);
System.out.println(Course.HTML);
System.out.println(Course.CSS);
}
}
Java
Android
html
CSS
接口来声明常数
我们可以使用接口来声明常数。通过使用接口,我们不需要转换任何东西,因为所有的字符串都将像枚举中的常量一样公开可见。
public interface InterfaceName{
String CONSTANT = "CONSTANT";
}
例子
这里,我们声明了一个接口,接口字符串内部声明为一个常量。我们可以使用接口名和常量名直接访问它们。
interface Course
{
String JAVA= "Java";
String ANDROID= "Android";
String HTML= "HTML";
String CSS= "CSS";
}
public class StudyTonight
{
public static void main(String args[])
{
System.out.println(Course.JAVA);
System.out.println(Course.ANDROID);
System.out.println(Course.HTML);
System.out.println(Course.CSS);
}
}
Java
Android
html
CSS
结论:
主要有两种方法toString()
和name()
,通过这两种方法我们可以将枚举转换为字符串,但我们并不仅限于这两种方法,还有其他替代方法,如也存在的接口。
如何在 Java 中将字符串日期转换为时间戳
原文:https://www.studytonight.com/java-examples/how-to-convert-string-date-to-timestamp-in-java
在本教程中,我们将学习如何在 Java 中将字符串日期转换为时间戳。当我们想要处理时间戳时,这种转换非常重要。例如,一个人可能想知道哪个日期比另一个日期小,或者我们可能想计算自特定日期以来的天数,而字符串日期是不可能的。在本教程中,我们将使用 Java 的SimpleDateFormat
、Timestamp
和Date
类。
将字符串日期转换为时间戳的示例
下面给出的代码非常适合将字符串日期转换为时间戳。首先,我们将使用SimpleDateFormat.parse()
方法将一个简单的字符串转换为日期,然后确保时间戳以正确的格式给出。
import java.text.SimpleDateFormat;
import java.sql.Timestamp;
import java.util.Date;
public class StudyTonight
{
public static void main(String[] args) throws Exception
{
//date in string format
String stringDate = "2021-01-07 02:02:16.172";
try
{
//creating date format
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
//parsing string to date using parse() method
Date parsedDate = dateFormat.parse(stringDate);
//finally creating a timestamp
Timestamp timestamp = new java.sql.Timestamp(parsedDate.getTime());
System.out.println(timestamp.getClass());
}
catch(Exception e)
{
System.out.println(e);
}
}
}
2021-01-07 02:02:16.172
如果字符串的格式不正确,您将得到一个异常错误:java.text.ParseException: Unparseable date:
使用 valueOf()方法将字符串日期转换为时间戳
这是使用java.sql.Timestamp
类的valueOf()
方法将日期字符串转换为时间戳的另一种方式。这是一个简单的方法,不需要做额外的编码。
例 2
在这个程序中,我们不需要考虑日期的格式,因为valueOf()
方法会直接将字符串转换为时间戳本身。与最后一个代码不同,如果字符串格式不正确,它将抛出异常java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff].
import java.text.SimpleDateFormat;
import java.sql.Timestamp;
import java.util.Date;
public class StudyTonight
{
public static void main(String[] args) throws Exception
{
//date in string format
String stringDate = "2021-01-07 02:02:16.172";
try
{
//converting string date to timestamp using valueOf() method
java.sql.Timestamp timestamp = java.sql.Timestamp.valueOf( stringDate );
System.out.println(timestamp);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
2021-01-07 02:02:16.172
结论:
要将字符串日期转换为时间戳,我们有两种方法,即使用时间戳作为构造器,另一种是使用时间戳类的 valueOf()方法。这在对实际时间戳而不是不同格式的日期执行操作时非常有用。
如何在 Java 中将文件读入字符串
原文:https://www.studytonight.com/java-examples/how-to-read-a-file-to-string-in-java
在本教程中,我们将学习如何在 Java 中读取文件到字符串。将数据存储到文件中对于永久存储很有用。一般我们使用扩展名为*.txt
的文件,这些文件也被称为纯文本文件。虽然文件可以是任何 PDF、DOC 或 SQL 等。在 Java 中,读取文件主要有四类。这些类属于java.io
包,用于 Java 中的文件处理。
-
FileReader
类 -
Scanner
类 -
FileInputStream
类 -
BufferedReader
类
在本教程中,我们将使用这个sampledata.txt
文件来执行读取操作,并且该数据将被转换为字符串。文件数据如下所示。
This is the sample data stored in a file
Rahul:10025
Sohan:10026
Madan:10027
Jack:10028
代码示例中显示的文件的所有路径都因机器而异。请验证系统中示例文件的路径,并将该路径正确添加到程序中。
使用FileReader
类从文件中检索字符串的示例
在下面的例子中,我们使用FileReader
类从文件中读取数据。FileReader
类的一个对象指向一个文件的开头,当它返回-1 时,我们将打印所有内容,因为它指示文件的结尾,数据被附加到一个字符串变量中。
import java.io.*;
public class StudyTonight
{
public static void main(String[] args) throws Exception
{
FileReader fr = new FileReader("E:\\Studytonight\\sampledata.txt");
String fileData = "";
int c;
while((c=fr.read()) != -1)
fileData += (char)c;
System.out.println(fileData);
}
}
这是存储在文件中的样本数据 Rahul:10025 Sohan:10026 马丹:10027 Jack:10028
使用扫描器类从文件中检索字符串的示例
Scanner 类从特定的源获取输入。大多数时候,我们提供System.in
作为从键盘输入的输入源。在我们的程序中,我们将从文本文件中读取数据,因此我们将提供该文件作为输入源。
不要忘记添加useDelimiter("\\Z")
方法来分隔文件中的读数。
import java.io.*;
import java.util.Scanner;
public class StudyTonight
{
public static void main(String[] args) throws Exception
{
File file = new File("E:\\Studytonight\\sampledata.txt");
//Scanner will read all the data from source file
Scanner sc = new Scanner(file);
//Delimiter reads upto the end of input
sc.useDelimiter("\\Z");
System.out.println(sc.next());
}
}
这是存储在文件中的样本数据 Rahul:10025 Sohan:10026 马丹:10027 Jack:10028
使用FileInputStream
类从文件中检索字符串的示例
在这个例子中,我们将使用FileInputStream
类从文件中读取数据,然后我们将创建一个 10 字节大小的缓冲区来存储从文件中读取后的临时字节。这些缓冲区将被添加到StringBuilder
中,稍后我们将使用toString()
方法将该数据转换为字符串。
import java.io.*;
public class StudyTonight
{
public static void main(String[] args) throws Exception
{
File file = new File("E:\\Studytonight\\sampledata.txt");
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buffer = new byte[10];
StringBuilder sb = new StringBuilder();
while (fileInputStream.read(buffer) != -1)
{
sb.append(new String(buffer));
buffer = new byte[10];
}
fileInputStream.close();
String fileData = sb.toString();
System.out.println(fileData);
}
}
这是存储在文件中的样本数据 Rahul:10025 Sohan:10026 马丹:10027 Jack:10028
使用BufferedReader
类类从文件中检索字符串的示例
BufferedReader
是最喜欢用简单的方式读取数据的类。它会同时读取所有数据,然后我们用readLine()
方法逐行打印。在文件的末尾readLine()
将返回一个空值,在那里我们将停止读取数据。
import java.io.*;
public class StudyTonight
{
public static void main(String[] args) throws Exception
{
File file = new File("E:\\Studytonight\\sampledata.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null)
System.out.println(line);
}
}
这是存储在文件中的样本数据 Rahul:10025 Sohan:10026 马丹:10027 Jack:10028
结论
在本文中,我们看到了许多从文件到字符串读取数据的方法,例如从文件中检索数据的四种方法,我们在其中使用FileReader, Scanner, FileInputStream, Using
BufferedReader.`` 在某些情况下,我们需要注意分隔符,否则它将读取无限次。
如何在 Java 中删除字符串中的标点符号
原文:https://www.studytonight.com/java-examples/how-to-remove-punctuation-from-string-in-java
在本教程中,我们将学习如何在 Java 中删除字符串中的标点符号。我们括在方括号中的所有字符都被归类为标点符号[ `! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~` ]。这些基本上是任何语言语法的一部分。Java 提供了几种从字符串中删除这些内容的方法。
考虑到str
是字符串,使用正则表达式去除标点符号非常简单,下面是单行代码,方便快速直觉。
str.replaceAll("\\p{Punct}", "");
现在,让我们正式看一下从字符串中删除标点符号的完整程序。
使用 replaceAll()从字符串中删除标点符号的示例
在下面的代码中,我们使用正则表达式调用replaceAll()
方法,该方法将找到字符串中存在的所有标点符号字符,并将其替换为空字符串(""
),看起来标点符号被删除了。
更多信息,可以参考本官方文档:模式(Java SE 14&JDK 14)(oracle.com)。
public class StudyTonight
{
public static void main(String[] args)
{
String str = "?This String $% Contains$$ punctuation !!";
str = str.replaceAll("\\p{Punct}","");
System.out.println(str);
}
}
该字符串包含标点符号
正则表达式不是一个非常直观的东西,所以我们将看一些非常基本的东西。
使用 isLetterOrDigit()方法从字符串中删除标点符号的示例
在下面的代码中,我们首先使用toCharArray()
将一个字符串转换成一个字符数组,然后使用isLetterOrDigit()
确定当前字符是数字还是字母,如果是,我们将把它附加到结果字符串中,它将形成一个新的字符串。
public class StudyTonight
{
public static void main(String[] args)
{
String str = "?This String $% Contains$$ punctuation !!";
String res = "";
for (Character c : str.toCharArray())
{
if(Character.isLetterOrDigit(c))
res += c;
}
System.out.println(res);
}
}
道德字串包含溢漏情况
结论:
在本文中,我们学习了从给定的字符串中删除标点符号。这是一个简单的任务,结合了像replaceAll()
和isLetterOrDigit().
这样的正则表达式和 Java 方法
如何在 Java 中排序字符串
原文:https://www.studytonight.com/java-examples/how-to-sort-string-in-java
在本教程中,我们将学习如何对字符串进行排序。在 Java 中,String
类中没有一个用于排序的方法。另一个困难是字符串在 Java 中是不可变的,这意味着我们不能修改原始字符串。另一方面,我们可以对字符数组执行非常灵活的操作,我们将使用字符数组的这个属性来对我们的字符串进行排序。
有两种方法可以对字符串进行排序
- 使用
Arrays.sort()
- 在
Arrays.sort()
中使用Comparator
- 使用普通算法如
Selection Sort
、Bubble Sort
等进行正常排序。
使用数组对字符串进行排序的示例。sort()方法
在下面的代码中,使用 toCharArray()
方法将片段原始字符串转换为字符数组,稍后使用Arrays.sort()
方法对其进行排序,然后返回到前面声明的 sortedString 变量。
“敏捷的棕色狐狸跳过懒惰的狗”是包含字母表中每个字母至少一次的字符串。
import java.util.Arrays;
public class StudyTonight
{
public static void main(String[] args)
{
String originalString = "The quick brown fox jumps over the lazy dog";
String sortedString = "";
//converting string to character array
char tempString[] = originalString.toCharArray();
//perform sort using Arrays.sort() method
Arrays.sort(tempString);
//storing sorted character array back to string
sortedString = new String(tempString);
System.out.println("Original String : " + originalString);
System.out.println("Sorted String : " + sortedString);
}
}
原弦:快棕狐狸跳过懒狗
排序弦:tabcdeefghhijklmnoopqrstuuvwxyz
在上面的程序中,您可能已经注意到一个大写字符首先显示,这意味着所有大写字母的优先级都高于小写字母。如果我们想排序而不考虑区分大小写呢?在这种情况下,我们需要一个定制的Comparator
函数。
使用数组、排序()和Comparator
函数对字符串进行排序的示例
在这里,需要记住的要点是:我们不能添加具有原始数据类型的Comparator
,这就是为什么我们创建了一个字符类的数组,然后应用Comparator
函数,并使用Character.toLowerCase()
方法将所有输入字符的大小写更改为小写。最后,我们使用StringBuilder
类来构建一个排序的字符串。
import java.util.Arrays;
import java.util.Comparator;
public class StudyTonight
{
public static void main(String[] args)
{
String originalString = "The quick brown fox jumps over the lazy dog";
String sortedString = "";
//length of string
int n=originalString.length();
//Building array of Character Array
Character tempString[] = new Character[n];
for (int i = 0; i < originalString.length(); i++)
{
tempString[i] = originalString.charAt(i);
}
//perform sort using Arrays.sort() with comparator function
Arrays.sort(tempString, new Comparator<Character>(){
@Override
public int compare(Character c1, Character c2)
{
//here we are converting character to lowercase
return Character.compare(Character.toLowerCase(c1),Character.toLowerCase(c2));
}
});
//StringBuilder to create string from Characters
StringBuilder sb = new StringBuilder(tempString.length);
for (Character c : tempString)
sb.append(c.charValue());
//Storing sorted string in sortedString variable
sortedString = sb.toString();
System.out.println("Original String : " + originalString);
System.out.println("Sorted String : " + sortedString);
}
}
原弦:快棕狐狸跳过懒狗
排序弦:abcdeeefghhijklmnoooopqrrsTtuuvwxyz
现在我们已经排序了字符串,没有区分大小写的影响。
使用传统方式比较和交换的字符串排序示例
在使用内置方法实现排序后,您能从零开始考虑解决方案吗?因此,这里有一个字符数组排序的例子,我们实现了嵌套循环,对于每个字符,它将比较它右边的字符,如果发现较小的字符,我们将其与当前字符交换。像往常一样完成后,我们将把这个排序后的字符数组存储在一个字符串中。
import java.util.Arrays;
public class StudyTonight
{
public static void main(String[] args)
{
String originalString = "The quick brown fox jumps over the lazy dog";
String sortedString = "";
//converting string to character array
char tempString[] = originalString.toCharArray();
int n= tempString.length;
for(int i = 0; i < n; i++ )
{
for(int j = i+1; j < n; j++)
{
if(tempString[i]>tempString[j]) {
char temp = tempString[i];
tempString[i] = tempString[j];
tempString[j] = temp;
}
}
}
//storing sorted character array back to string
sortedString = new String(tempString);
System.out.println("Original String : " + originalString);
System.out.println("Sorted String : " + sortedString);
}
}
原弦:快棕狐狸跳过懒狗
排序弦:tabcdeefghhijklmnoopqrstuuvwxyz
这不是旅程的终点。你可以试试那些流行的算法,比如Selection Sort
、Bubble Sort
等。
结论:
要对给定的字符串进行排序,String
类没有可用的方法,但是另一方面,我们可以对字符数组执行许多操作。对字符串进行排序最简单的方法是使用Arrays.sort()
,但它区分大小写。为了避免字符串排序时区分大小写,我们可以使用比较函数。
如何在 Java 中重复字符串
原文:https://www.studytonight.com/java-examples/how-to-multiply-string-in-java
在本教程中,我们将学习如何在 Java 中乘法字符串。我们将使用 Java 的String.repeat()
和StringBuffer.append()
方法来相乘 String。让我们看一些例子。
为了充分利用本教程,建议尝试所有代码片段并按顺序理解主题。
将字符串相乘以重复字符序列。
String str = "StudyTonight";
String repeated = str.repeat(3);
以上代码将只支持 Java 11 及以上。下面我们需要用到StringBuffer().
为什么?
字符串是不可变的。它不能被继承,一旦创建,我们就不能改变对象。
例子
我们正在使用String
类的repeat()
方法来相乘字符串并获得一个新的字符串对象。
public class StudyTonight
{
public static void main(String[] args)
{
String str = "Studytonight";
System.out.println( str.repeat(3) );
}
}
今晚学习今晚学习
使用 StringBuffer.append()乘法字符串的示例
我们用StringBuffer()
在String
上做操作,以后可以用StringBuffer.toString()
法换成String
。
public class StudyTonight {
public static void main(String[] args) {
//original string
String str = "studytonight ";
//number of times repetition
int n=5;
//empty stringbuffer
StringBuffer str_bfr = new StringBuffer();
for(int i=0;i<n;i++)
{
//append string to stringbuffer n times
str_bfr.append(str);
}
//converting stringbuffer back to string using toString() method
str = str_bfr.toString();
System.out.print(str);
}
}
今晚学习今晚学习今晚学习今晚学习今晚学习今晚学习
使用字符串乘字符串的示例。替换()
它是相同代码的最短变体,但需要 Java 1.5 及以上版本。这段代码的神奇之处在于不需要导入或库。其中***n***
是你想要重复该字符串的次数, str
是要重复的字符串。
public class StudyTonight {
public static void main(String[] args) {
String str = "studytonight ";
int n=5;
String repeated = new String(new char[n]).replace("\0", str);
System.out.print(repeated);
}
}
今晚学习今晚学习今晚学习今晚学习今晚学习今晚学习
结论
我们可以在 java 中使用StringBuffer.append()
在循环中附加一个特定的字符串来乘字符串,它将确保该字符串重复 n 次。另一种方法是使用 String.replace()
方法,我们传递空字符(" \0 "),它也称为字符串的结尾,第二个参数作为原始字符串对该字符的替换。String.repeat()
也是能够演出同样名声的弦乐。
如何在 Java 中将字符串转换为日期
原文:https://www.studytonight.com/java-examples/how-to-convert-string-to-date-in-java
在本文中,我们将向您介绍在 Java 中将字符串转换为日期的非常简单易懂的方法。以纯文本格式存储日期并在以后用于业务逻辑是软件行业中非常常见的做法。通过以纯文本存储日期,我们可以节省大量存储空间。
这是一个非常经典的将字符串转换为日期的例子。自己试试这个例子,它会帮助你获得将字符串转换为日期的过程背后的直觉。
示例:将字符串转换为日期
import java.text.SimpleDateFormat;
import java.util.Date;
public class StudyTonight
{
public static void main(String args[]) throws Exception
{
String string_format="4/1/2021";
Date date_format=new SimpleDateFormat("dd/MM/yyyy").parse(string_format);
System.out.println(" Date in String Format: "+string_format+" \n Converted Date: "+date_format);
}
}
字符串格式日期:2021 年 4 月 1 日转换日期:2021 年 1 月 4 日星期一 00:00:00 IST
执行上述示例时,不要忘记在主方法中使用 throws 关键字,否则会出现编译时错误。
在代码中,您可能已经注意到simpledate format(“DD/MM/yyyy”)方法来设置日期的格式。这意味着所提到的日期采用 【日/月/年】 的格式。Java 支持许多格式来定制日期,具有很大的灵活性。你可以在下面看到同样的表格。
### Java 中所有可用的日期和时间格式 |标志
|
符号代表
|
| --- | --- |
| G | 时代 |
| u | 年 |
| y | 时代之年 |
| D | 一年中的一天 |
| 男/女 | 年度月份 |
| d | 每月的某一天 |
| Q/q | 季度 |
| Y | 基于周的年 |
| w | 以周为单位的年度 |
| W | 每月的一周 |
| E | 星期几 |
| 英/法 | 本地化的星期几 |
| F | 每月的一周 |
| a | 每天上午-下午 |
| h | 上午 11 点至下午 1 点(1-12 点) |
| K | 上午 11 点(0-11 点) |
| k | 凌晨 1 点至 24 点 |
| H | 一天中的小时数(0-23) |
| m | 小时分钟 |
| s | 分钟秒 |
| S | 几分之一秒 |
| A | 百万日 |
| n | 纳米秒 |
| 普通 | 纳米技术 |
| V | 时区标识 |
| z | 时区名称 |
| O | 局部区域偏移 |
| X | 零的区域偏移 |
| x | 区域偏移 |
| Z | 区域偏移 |
将字符串转换为日期的示例
在本例中,我们使用SimpleDateFormat
类将字符串格式的给定日期转换为Date
格式。将字符串转换为日期时,请确保其格式正确,否则将引发异常,即ParseException
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class StudyTonight {
public static void main(String[] args) {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy");
String date_String = "4-Jan-2021";
try {
Date date = formatter.parse(date_String);
System.out.println(date);
System.out.println(formatter.format(date));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
我的 Jan 04 00:00:00 是 2021 年 1 月 04 日-2021
现在让我们打破上面的代码,逐行理解
SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy");
SimpleDateFormat 是来自java.text
包的一个类,用于设置日期的格式。在上面的例子中【DD-MMM-yyy】可以进一步简化成这样:
- 每月的第几天
- 一年中的月份
- yyyy -纪元年
所以,这是格式化的格式,可以应用到以后的任何日期。如需进一步说明,您可以参考上面给出的表格。
String date_String = "4-Jan-2021";
这是以字符串格式给出的简单日期。
Date date = formatter.parse(date_String);
这里,使用formatter.parse()
方法将String
类型的日期转换为日期。
这里我们提供了一些将字符串转换为日期的示例
例 1
在这种情况下,我们得到了一个格式为“dd/MM/yyyy”的日期,我们希望使用SimpleDateFormat()
将该日期转换为日期类型的“dd/MM/yyyy”格式。我们创建了一个日期格式,然后通过调用Format.parse()
方法将字符串转换为所需的日期格式。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class StudyTonight
{
public static void main(String[] args)
{
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
String date_String = "01/04/2021";
try
{
Date date = formatter.parse(date_String);
System.out.println(date);
System.out.println(formatter.format(date));
}
catch (ParseException e)
{
e.printStackTrace();
}
}
}
因此 04 月 01 日 00:00:00 是 2021 年 4 月 1 日 2021
例 2
在这种情况下,我们得到了日期“2021 年 1 月 4 日星期一”,我们希望将该日期转换为日期类型的“E,MMM dd yyyy”格式。使用SimpleDateFormat()
我们创建了一个日期格式,然后通过调用Format.parse()
方法将字符串转换为所需的日期格式。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class StudyTonight
{
public static void main(String[] args)
{
SimpleDateFormat formatter = new SimpleDateFormat("E, MMM dd yyyy");
String date_String = "Mon, Jan 4 2021";
try
{
Date date = formatter.parse(date_String);
System.out.println(date);
System.out.println(formatter.format(date));
}
catch (ParseException e)
{
e.printStackTrace();
}
}
}
我的 Jan 04 00:00:00 是 2021 Mon,Jan 04 2021
例 3
在这种情况下,我们得到的日期是“2021 年 1 月 4 日星期一下午 12:15:30”,我们希望将该日期转换为“EEEE,MMM dd,yyyy HH:mm:ss a”格式的日期类型。使用SimpleDateFormat()
我们创建了一个日期格式,然后通过调用Format.parse()
方法将字符串转换为所需的日期格式。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class StudyTonight
{
public static void main(String[] args)
{
SimpleDateFormat formatter = new SimpleDateFormat("EEEE, MMM dd, yyyy HH:mm:ss a");
String date_String = "Monday, Jan 4, 2021 12:15:30 PM";
try
{
Date date = formatter.parse(date_String);
System.out.println(date);
System.out.println(formatter.format(date));
}
catch (ParseException e)
{
e.printStackTrace();
}
}
}
我的 Jan 04 12:15:30 是 2021 星期一,Jan 04,2021 是下午 12:15:30
结论:
我们有不同的类来将字符串格式的日期更改为实际日期,这为我们提供了在以后的日期上进行不同操作的能力。字符串格式的所有有效日期都可以通过指定所需的格式,使用SimpleDateFormat
类转换为Date
格式。如果日期是日期格式,那么我们可以计算两天之间的持续时间,我们可以比较两个日期,如果日期以字符串格式表示,这是不可能的。
如何将字符串转换为 JSON,反之亦然
原文:https://www.studytonight.com/java-examples/how-to-convert-string-to-json-and-vice-versa
在本教程中,我们将学习如何将字符串转换为 JSON,反之亦然。首先,什么是 JSON?
JSON 是 JavaScript 对象符号的缩写。它是不同网络服务之间的轻量级数据传输格式。它主要用于构建 API。
JSON 示例
这是 JSON 的一个例子,它以键值格式存储数据,值可以是另一个原始数据类型或另一个 JSON 的数组。
myJSON = {
"course":"Java",
"price":8000,
"duration":"3 Months"
};
在 Java 中,有三种方法可以将 JSON 转换为字符串,反之亦然
-
使用 JSON 库
-
使用 Gson 库
-
使用 Jaskson 图书馆
在运行包含这些库的程序时,我们需要下载这些 jar 文件,并根据 ide 将它们添加到项目中,否则这些库中的函数将不支持并导致错误。您可以参考以下链接来下载这些库
让我们借助例子一个一个看。
示例 JSON 库
在下面给出的代码中,我们有一个以字符串形式存储的JSON
数据。转换一个字符串JSON
执行多个动作非常方便。JSONObject
是一个将字符串转换为JSON
对象的org.json
包类。
import org.json.JSONException;
import org.json.JSONObject;
public class StudyTonight
{
public static void main(String[] args)
{
String myJSON ="{\"name\":\"studytonight\",\"address\":\"Noida\"}";
try
{
JSONObject jsonObject = new JSONObject(myJSON);
System.out.println("JSON Object: "+jsonObject);
}
catch (JSONException e)
{
System.out.println("Error "+e.toString());
}
}
}
JSON 对象:{“地址”:“Noida”,“姓名”:“今晚学习”}
JSON 库示例:JSON 到字符串
在上面的代码中,我们学习了如何将字符串转换为 JSON 对象,现在我们可以将 JSON 对象转换为字符串,我们还将学习从头开始创建对象。首先,我们将创建一个 JSON 对象并添加值。这个类有一个 JSONObject.put()方法,它接受两个参数键和值。
import org.json.JSONObject;
public class StudyTonight
{
public static void main(String[] args)
{
//Creating a JSON Object
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", "studytonight");
jsonObject.put("address", "Noida");
//Converting JSON Object using toString() method
String myJSONString = jsonObject.toString();
System.out.println("JSON String: "+myJSONString);
}
}
JSON 字符串:{“地址”:“Noida”,“姓名”:“今晚学习”}
GSON 库示例
无论我们在上面的代码块中做了哪两件事,我们都将使用 Gson 库做同样的事情。这个库是谷歌开发的,在业内广泛使用。JsonParser
是负责解析字符串的类,parse()
是接受字符串的方法。最后,我们使用getAsJsonObject()
以 JsonObject 格式获取上述所有转换。
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class StudyTonight
{
public static void main(String[] args)
{
//JSON String
String myJSON ="{\"name\":\"studytonight\",\"address\":\"Noida\"}";
//JSON Parser from Gson Library
JsonParser parser = new JsonParser();
//Creating JSONObject from String using parser
JsonObject JSONObject = parser.parse(myJSON).getAsJsonObject();
System.out.println("Object: "+JSONObject);
}
}
对象:{“姓名”:“今晚学习”、“地址”:“Noida”}
示例 GSON 库:JSON 到字符串
为了在com.google.gson
内部创建 JSON 对象,我们使用 JSON 对象类和方法addPropety()
。addProperty()将接受两个参数,即将要添加到 JSON 对象中的键和值。
import com.google.gson.JsonObject;
public class StudyTonight
{
public static void main(String[] args)
{
//Creating Json Object
JsonObject JSONObject = new JsonObject();
JSONObject.addProperty("name", "studytonight");
JSONObject.addProperty("address", "Noida");
//Converting Json Object to String
String myJSON = JSONObject.toString();
System.out.println("String: "+myJSON);
}
}
字符串:{“姓名”:“今晚学习”、“地址”:“Noida”}
Jaskson 图书馆示例
Jackson 是一个库,在使用 JSON 时提供了很大的灵活性。我们需要从 ObjectMapper 类创建一个映射器,然后我们从一个映射器创建一个 JsonFactory 类对象,并调用该映射器来创建一个解析器,最后这个解析器将使用readTree()
方法为我们实际创建 JSON 对象。readTree()
将接受解析器对象,并跟踪 JSON 的层次结构。
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.ObjectMapper;
public class StudyTonight
{
public static void main(String[] args)
{
//JSON String
String myJSON ="{\"name\":\"studytonight\",\"address\":\"Noida\"}";
ObjectMapper mapper = new ObjectMapper();
JsonFactory factory = mapper.getJsonFactory();
try
{
JsonParser parser = factory.createJsonParser(myJSON);
JsonNode actualObj = mapper.readTree(parser);
System.out.println("Object: "+actualObj);
}
catch(Exception e)
{
System.out.println("Error: "+e.toString());
}
}
}
对象:{“姓名”:“今晚学习”、“地址”:“Noida”}
示例 Jaskson 库:JSON 到字符串
为了从 Json 对象创建 String,Jaskson 库在ObjectMapper
类中提供了writeValueAsString()
方法。该值接受 JSON 对象并返回字符串。
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ObjectNode;
public class StudyTonight
{
public static void main(String[] args)
{
ObjectMapper mapper = new ObjectMapper();
// create a JSON object
ObjectNode JSONObject = mapper.createObjectNode();
JSONObject.put("name", "studytonight");
JSONObject.put("address", "Noida");
try
{
//Json object to String
String JSONString = mapper.writeValueAsString(JSONObject);
System.out.println("String: "+JSONString);
}
catch(Exception e)
{
System.out.println("Error "+e);
}
}
}
字符串:{“姓名”:“今晚学习”、“地址”:“Noida”}
结论:
JSON 是 JavaScript 对象符号,它非常适合构建像 RESTful APIs 这样的网络服务。我们使用json
、gson
和Jackson
库将 JSON 转换为 String,并将 String 转换为 JSON。
日期和时间
Java 8 日期和时间 API
原文:https://www.studytonight.com/java-examples/java-8-date-and-time-api
Java 8 推出了全新的日期时间 API 。这个新的 API 的灵感来自流行的 JodaTime 库。添加它是为了克服现有日期 API 的缺点。
在本教程中,我们将讨论新的日期和时间 API 的重要类。
现有 API 的缺点(Java 7)
现有的日期和时间 API 有几个主要缺点。让我们讨论其中的一些缺点。
- 线程安全 -现有的日期和日历类不是线程安全的,需要额外的努力来处理并发性。新的 LocalDate、LocalTime 和 LocalDateTime 类解决了这个问题。这些类是不可变的和线程安全的。
- 时区 -旧的 API 不提供任何时区支持。新的 ZonedDateTime 类也支持时区。
- 其他改进 -新的 API 符合 ISO 标准,更容易理解。它提供了许多操作日期和时间的方法。与新的 API 相比,现有的 API 有点难以使用和理解。
LocalDate Class(本地日期类)
LocalDate 类用于表示标准 ISO 格式 (yyyy-mm-dd)的日期。它不包括时间,也不支持时区。
创建本地日期实例
我们可以使用 now() 方法创建 LocalDate 类的一个实例。它将根据系统时钟捕捉当前日期。
import java.time.LocalDate;
public class Demo
{
public static void main(String[] args)
{
LocalDate currDate = LocalDate.now();
System.out.print("Current Date is: " + currDate);
}
}
当前日期为:2021-08-13
要使用其他日期创建实例,我们可以使用()方法的。此方法采用三个整数参数,即年、月和日。
import java.time.LocalDate;
public class Demo
{
public static void main(String[] args)
{
LocalDate date = LocalDate.of(2021, 8, 13);
System.out.print("Date: " + date);
}
}
日期:2021-08-13
如果您有包含日期的字符串,请使用 parse() 方法。确保日期采用正确的国际标准化组织格式。
import java.time.LocalDate;
public class Demo
{
public static void main(String[] args)
{
LocalDate date = LocalDate.parse("2021-08-13");
System.out.print("Date: " + date);
}
}
日期:2021-08-13
加减方法
我们可以从日期中添加或减去天数、月数或年数。让我们使用 plusDays() 或 minusDays() 方法来获取昨天的日期和明天的日期。我们也有类似的方法来改变月份和年份。
import java.time.LocalDate;
public class Demo
{
public static void main(String[] args)
{
LocalDate currDate = LocalDate.now();
LocalDate yesterday = currDate.minusDays(1);
LocalDate tomorrow = currDate.plusDays(1);
System.out.println("Current Date: " + currDate);
System.out.println("tomorrow's Date: " + tomorrow);
System.out.println("Yesterday's Date: " + yesterday);
}
}
当前日期:2021-08-13
明天日期:2021-08-14
昨天日期:2021-08-12
我们也可以使用更简单的加()或减()方法来操纵日期。这些方法将使用计时单位枚举。请记住,LocalDate 是不可变的,我们不会更改现有的日期。所有这些方法都返回一个经过修改的新实例。
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
public class Demo
{
public static void main(String[] args)
{
LocalDate currDate = LocalDate.now();
LocalDate date1 = currDate.plus(5, ChronoUnit.MONTHS);
LocalDate date2 = currDate.minus(5, ChronoUnit.DAYS);
System.out.println("Current Date: " + currDate);
System.out.println("Current Date plus five months: " + date1);
System.out.println("Current Date minus five days: " + date2);
}
}
当前日期:2021-08-13
当前日期加五个月:2022-01-13
当前日期减五天:2021-08-08
吸气方法
LocalDate 类包含几个 getter 方法来从 LocalDate 获取不同的信息,例如获取星期几或月几等。下面的代码演示了这一点。
import java.time.DayOfWeek;
import java.time.LocalDate;
public class Demo
{
public static void main(String[] args)
{
LocalDate currDate = LocalDate.now();
DayOfWeek dayOfWeek = currDate.getDayOfWeek();//getDayOfWeek() returns a DayOfWeek instance and not a String
int dayOfMonth = currDate.getDayOfMonth();
int dayOfYear = currDate.getDayOfYear();
System.out.println("Date: " + currDate);
System.out.println("Day of Week: " + dayOfWeek);
System.out.println("Day of Month: " + dayOfMonth);
System.out.println("Day of Year: " + dayOfYear);
}
}
日期:2021-08-13
星期几:星期五
月日:13
年日:225
比较日期
我们可以通过使用 isBefore() 和 isAfter() 方法来比较日期,以检查哪个更大。请看下面的例子。
import java.time.LocalDate;
public class Demo
{
public static void main(String[] args)
{
LocalDate currDate = LocalDate.now();
LocalDate tomorrow = currDate.plusDays(1);
LocalDate yesterday = currDate.minusDays(1);
System.out.println("Current date is after yesterday's date: " + currDate.isAfter(yesterday));
System.out.println("Current date is before tomorrow's date: " + currDate.isBefore(tomorrow));
}
}
当前日期在昨天日期之后:真
当前日期在明天日期之前:真
其他实用方法
这个类还提供了其他实用方法。例如,我们有islapyear()方法,该方法返回一个布尔值,指示该年是否是闰年。
import java.time.LocalDate;
public class Demo
{
public static void main(String[] args)
{
LocalDate currDate = LocalDate.now();
System.out.println(currDate + " is a leap year? " + currDate.isLeapYear());
}
}
2021-08-13 是闰年?错误的
我们还有 lengthOfMonth() 和 lengthOfYear() 方法返回月和年的长度。
import java.time.LocalDate;
public class Demo
{
public static void main(String[] args)
{
LocalDate currDate = LocalDate.now();
System.out.println("Current Date " + currDate);
System.out.println("Length of Month: " + currDate.lengthOfMonth());
System.out.println("Length of Year: " + currDate.lengthOfYear());
}
}
当前日期 2021-08-14
月长:31
年长:365
还有很多其他方法可用。查看官方 Javadoc 页面查看它们。
LocalTime(本地时间)
LocalTime 类用于表示时间。
创建本地时间实例
要创建一个 LocalTime 实例,我们可以使用 now() 、 of() 或者 parse() 方法。now()方法将使用系统时钟获取当前时间。()和 parse()方法可以根据传递的参数创建一个 LocalTime。
import java.time.LocalTime;
public class Demo
{
public static void main(String[] args)
{
LocalTime currTime = LocalTime.now();
LocalTime t1 = LocalTime.of(5, 32, 44);
LocalTime t2 = LocalTime.parse("05:32:44");
System.out.println(currTime);
System.out.println(t1);
System.out.println(t2);
}
}
16:26:36.285807700
05:32:44
05:32:44
加减方法
LocalTime 类也有几个加减方法。
import java.time.LocalTime;
public class Demo
{
public static void main(String[] args)
{
LocalTime t1 = LocalTime.of(5, 32, 44);
LocalTime t2 = t1.plusHours(2);
LocalTime t3 = t1.minusMinutes(10);
System.out.println(t1);
System.out.println(t2);
System.out.println(t3);
}
}
05:32:44
07:32:44
05:22:44
我们也可以使用更简单的加()和减()方法,并带有一个计时单位参数。
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
public class Demo
{
public static void main(String[] args)
{
LocalTime t1 = LocalTime.of(5, 32, 44);
LocalTime t2 = t1.plus(2, ChronoUnit.HOURS);
LocalTime t3 = t1.plus(10, ChronoUnit.MINUTES);
System.out.println(t1);
System.out.println(t2);
System.out.println(t3);
}
}
05:32:44
07:32:44
05:42:44
吸气方法
这个类还包含几个 getter 方法来获取不同的信息,如小时、分钟或秒。下面的代码演示了这一点。
import java.time.LocalTime;
public class Demo
{
public static void main(String[] args)
{
LocalTime t = LocalTime.of(5, 32, 44);
int hours = t.getHour();
int minutes = t.getMinute();
int seconds = t.getSecond();
System.out.println("Time: " + t);
System.out.println("Hours: " + hours);
System.out.println("Minutes: " + minutes);
System.out.println("Seconds: " + seconds);
}
}
时间:05:32:44
小时:5
分钟:32
秒:44
比较本地时间实例
像 LocalDate 类一样,我们可以通过使用 isBefore() 和 isAfter() 方法来比较 LocalTime 的实例。
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
public class Demo
{
public static void main(String[] args)
{
LocalTime t1 = LocalTime.of(5, 32, 44);
LocalTime t2 = t1.plus(1, ChronoUnit.HOURS);
boolean b = t1.isAfter(t2); //False
}
}
LocalDateTime 类
本地日期时间类是本地日期和本地时间类的组合。本地日期时间实例包含日期组件和时间组件。
类似于前面的类,我们有 now() 、 of() 和 parse() 方法来构造 LocalDateTime 类的对象。
import java.time.LocalDateTime;
public class Demo
{
public static void main(String[] args)
{
LocalDateTime currDateTime = LocalDateTime.now();
LocalDateTime dt1 = LocalDateTime.of(2020, 8, 13, 5, 32);
LocalDateTime dt2 = LocalDateTime.parse("2020-08-13T05:32");
System.out.println(currDateTime);
System.out.println(dt1);
System.out.println(dt2);
}
}
2021-08-13t 16:44:11.684424
2020-08-13t 05:32
2020-08-13t 05:32
对于 LocalDateTime 类,我们也有类似的加减方法。
import java.time.LocalDateTime;
public class Demo
{
public static void main(String[] args)
{
LocalDateTime currDateTime = LocalDateTime.now();
LocalDateTime dt1 = currDateTime.plusDays(10);
LocalDateTime dt2 = currDateTime.minusHours(5);
System.out.println(currDateTime);
System.out.println(dt1);
System.out.println(dt2);
}
}
2021-08-13T 16:46:12.603985700
2021-08-23T 16:46:12.603985700
2021-08-13T 11:46:12.603985700
要获取 LocalDateTime 实例的不同组件,我们可以使用 getters。下面的代码演示了一些 getter 方法的使用。
import java.time.LocalDateTime;
import java.time.Month;
public class Demo
{
public static void main(String[] args)
{
LocalDateTime currDateTime = LocalDateTime.now();
int hour = currDateTime.getHour();
int dayOfMonth = currDateTime.getDayOfMonth();
Month month = currDateTime.getMonth();
System.out.println(currDateTime);
System.out.println("Hour: " + hour);
System.out.println("Day of Month: " + dayOfMonth);
System.out.println("Month: " + month);
}
}
2021-08-13t 16:49:07.087638100
小时:16
月日:13
月:8 月
ZonedDateTime Class
上面讨论的类不支持时区。ZonedDateTime 类提供了这种功能。它与 ZoneId 类一起使用,有助于识别不同的时区。
使用 now() 方法创建这个类的一个实例。相关时区信息将被添加到当前日期和时间。
import java.time.ZonedDateTime;
public class Demo
{
public static void main(String[] args)
{
ZonedDateTime zdt = ZonedDateTime.now();
System.out.print(zdt);
}
}
2021-08-13 t17:31:18.046976800+05:30[亚洲/加尔各答]
我们还可以为 now()方法提供一个区域标识。区域 id 用于识别不同的时区。使用 ZoneId 类的()方法的来实现。请确保您提供了有效的时区。
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Demo
{
public static void main(String[] args)
{
ZoneId zone = ZoneId.of("Asia/Tokyo");
ZonedDateTime zdt = ZonedDateTime.now(zone);
System.out.print(zdt);
}
}
2021-08-13t 21:02:03.657050700+09:00【亚洲/东京】
我们可以使用 ZoneId 类的 getAvailableZoneIds() 方法查看所有可用的时区。
import java.time.ZoneId;
import java.util.Set;
public class Demo
{
public static void main(String[] args)
{
Set<String> zones = ZoneId.getAvailableZoneIds();
for(String zone : zones)
System.out.println(zone);
}
}
由上述代码打印的几个时区如下所示。
亚洲/科伦坡
澳大利亚/西部
印度/塔那那利佛
澳大利亚/布里斯班
印度/马约特
美国/印第安纳-斯塔克
我们也可以通过使用这个类的 parse()方法来构造一个 ZonedDateTime 实例。
import java.time.ZonedDateTime;
public class Demo
{
public static void main(String[] args)
{
ZonedDateTime zdt = ZonedDateTime.parse("2021-08-13T17:35:08.044680100+09:00[Asia/Tokyo]");
System.out.print(zdt);
}
}
2021-08-13t 17:35:08.044680100+09:00【亚洲/东京】
ZoneOffset Class(区域偏移类)
使用时区的另一种方法是使用区域偏移量。下面的代码演示了这一点。
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
public class Demo
{
public static void main(String[] args)
{
LocalDateTime dateTime = LocalDateTime.now();
ZoneOffset offset = ZoneOffset.of("+09:00");
OffsetDateTime offsetDateTime = OffsetDateTime.of(dateTime, offset);
System.out.print(offsetDateTime);
}
}
2021-08-13t 17:38:41.485118900+09:00
期间和持续时间
“期间”和“持续时间”类用于查找两个日期或时间之间的差异。期间用于本地日期,持续时间用于本地时间。
让我们使用 Period 类来获取两个日期之间的差异。我们将使用 getDays() 、 getMonths() 和 getYears() 方法来获取两个日期的每个组成部分之间的差异。
import java.time.LocalDate;
import java.time.Period;
public class Demo
{
public static void main(String[] args)
{
LocalDate d1 = LocalDate.now();
LocalDate d2 = d1.plusDays(10).plusMonths(5).plusYears(1);
int days = Period.between(d1, d2).getDays();
int months = Period.between(d1, d2).getMonths();
int years = Period.between(d1, d2).getYears();
System.out.println("Initial Date: " + d1 + " Final Date " + d2);
System.out.println("Difference in Days: " + days);
System.out.println("Difference in Months: " + months);
System.out.println("Difference in Years: " + years);
}
}
起始日期:2021-08-13 结束日期 2023-01-23
日差:10
月差:5
年差:1
让我们使用 Duration 类来获取两个 LocalTimes 之间的差异。我们可以使用这个类的 getSeconds() 方法,以秒为单位获取两次的差值。
import java.time.Duration;
import java.time.LocalTime;
public class Demo
{
public static void main(String[] args)
{
LocalTime t1 = LocalTime.now();
LocalTime t2 = t1.plusHours(10).plusMinutes(5).plusSeconds(15);
long secs = Duration.between(t1, t2).getSeconds();
System.out.println("Initial Time: " + t1 + " Final Time " + t2);
System.out.println("Difference in Seconds: " + secs);
}
}
初始时间:17:55:56.774818600 最终时间 04:01:11.774818600
秒差:-50085
为此,我们还可以使用计时单位类的介于()之间的方法。下面的代码演示了它的用法。
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
public class Demo
{
public static void main(String[] args)
{
LocalTime t1 = LocalTime.now();
LocalTime t2 = t1.plusHours(10).plusMinutes(5).plusSeconds(15);
long hours = ChronoUnit.HOURS.between(t2, t1);
long mins = ChronoUnit.MINUTES.between(t2, t1);
long secs = ChronoUnit.SECONDS.between(t2, t1);
System.out.println("Initial Time: " + t1 + " Final Time " + t2);
System.out.println("Difference in Hours: " + hours);
System.out.println("Difference in Minutes: " + mins);
System.out.println("Difference in Seconds: " + secs);
}
}
初始时间:17:57:29.308126300 最终时间 04:02:44.308126300
小时差:13
分钟差:834
秒差:50085
新旧班级之间的转换
Java 8 还支持将旧的 API 类转换成新的。我们将在日期和日历类实例上使用 LocalDateTime 类的 ofInstant() 方法和 toInstant() 方法来执行转换。下面的代码演示了这一点。
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
public class Demo
{
public static void main(String[] args)
{
Date d = new Date();
Calendar c = Calendar.getInstance();
LocalDateTime dateTime1 = LocalDateTime.ofInstant(d.toInstant(), ZoneId.systemDefault());
LocalDateTime dateTime2 = LocalDateTime.ofInstant(c.toInstant(), ZoneId.systemDefault());
System.out.println(dateTime1);
System.out.println(dateTime2);
}
}
2021-08-13t 18:06:18.030
2021-08-13t 18:06:18.055
格式化日期
Java 8 提供了一个 format() 函数,使用特定的模式将日期格式化为字符串。新的日期时间格式化器类允许我们使用预定义的模式。在下面的代码中,我们使用了一些预定义的日期格式。
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Demo
{
public static void main(String[] args)
{
LocalDateTime dateTime = LocalDateTime.now();
String dateStr1 = dateTime.format(DateTimeFormatter.ISO_WEEK_DATE);
String dateStr2 = dateTime.format(DateTimeFormatter.BASIC_ISO_DATE);
String dateStr3 = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(dateStr1);
System.out.println(dateStr2);
System.out.print(dateStr3);
}
}
2021-W32-6
20210814
2021-08-14T 09:02:32.534666660606
DateTimeFormatter 类还允许我们定义自定义日期格式。让我们用两个星号来分隔日期的每个部分。
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Demo
{
public static void main(String[] args)
{
LocalDateTime dateTime = LocalDateTime.now();
String dateStr1= dateTime.format(DateTimeFormatter.ofPattern("dd ** MM ** YYYY"));
System.out.print(dateStr1);
}
}
2021 年 14 ** 08 **月
摘要
新的日期和时间 API 旨在解决现有 API 的问题。新的日期和时间类是不可变的和线程安全的。本地日期、本地时间和本地日期时间类是新 API 最常用的类。这些新类出现在 java.time 包中。它还提供了一个 ZonedDateTime 类来处理时区。现有的 API 也缺乏这一功能。
Java 数组
Java 中数组和列表之间的转换
原文:https://www.studytonight.com/java-examples/converting-between-an-array-and-list-in-java
数组是用于存储数据集合的线性数据结构。数组被分配了连续的内存块,这允许我们使用数组的索引随机访问数组的任何元素。列表是 java.util 包的接口,帮助我们维护有序的数据集合。列表接口由ArrayList
、LinkedList
和其他几个类实现。在本教程中,我们将学习如何将数组转换为列表,并将列表转换回数组。
数组到列表的转换
使用 Arrays.asList()方法
数组类的 asList() 方法提供了一种将数组转换为列表的简单方法。我们需要将数组作为参数传递给这个方法,它将返回数组元素的列表。
下面的代码演示了 asList()方法的工作原理。
public static void main(String args[])
{
//Converting a string array
String[] strArr = {"this", "is", "a", "string", "array"};
List<String> strList = Arrays.asList(strArr);
System.out.println(strList);
//Converting an integer array
Integer[] intArr = {2, 3, 5, 7, 11, 13, 17};
List<Integer> intList = Arrays.asList(intArr);
System.out.println(intList);
}
【这,是,a,字符串,数组】
【2,3,5,7,11,13,17】
使用 Collections.addAll()方法
java.util 包的 Collections 类有一个 addAll()方法,它会将数组的所有元素添加到一个列表中。我们首先需要创建一个空的列表,然后将现有的数组和新创建的列表作为参数传递给这个方法。方法签名如下所示。
Collections.addAll(target, source);
下面的代码演示了 addAll()方法的工作原理。
public static void main(String args[])
{
//Converting a string array
String[] strArr = {"this", "is", "a", "string", "array"};
List<String> strList = new ArrayList<String>();
Collections.addAll(strList, strArr);
System.out.println(strList);
//Converting an integer array
Integer[] intArr = {2, 3, 5, 7, 11, 13, 17};
List<Integer> intList = new ArrayList<Integer>();
Collections.addAll(intList, intArr);
System.out.println(intList);
}
【这,是,a,字符串,数组】
【2,3,5,7,11,13,17】
使用番石榴图书馆
番石榴是谷歌开发的一套开源库。它有一个 Lists.newArrayList() 方法,可用于将数组转换为ArrayList
。下面的代码演示了它的工作原理。
public static void main(String args[])
{
//Converting a string array
String[] strArr = {"this", "is", "a", "string", "array"};
List<String> strList = Lists.newArrayList(strArr);
System.out.println(strList);
//Converting an integer array
Integer[] intArr = {2, 3, 5, 7, 11, 13, 17};
List<Integer> intList = Lists.newArrayList(intArr);
System.out.println(intList);
}
【这,是,a,字符串,数组】
【2,3,5,7,11,13,17】
写我们自己的方法
我们可以编写我们的方法,并从数组中创建一个列表。List 接口为我们提供了 add()方法,我们可以使用该方法将数组中的元素添加到列表中。下面的代码将字符串数组转换为列表。如果我们希望转换其他数据类型的数组,我们可以创建一个不同的方法,或者我们可以只使用泛型方法。
public static List<String> arrayToList(String[] strArr)
{
List<String> strList = new ArrayList<String>();
for(int i = 0; i <= strArr.length - 1; i++)
strList.add(strArr[i]);
return strList;
}
public static void main(String args[])
{
//Converting a string array
String[] strArr = {"this", "is", "a", "string", "array"};
List<String> strList = arrayToList(strArr);
System.out.print(strList);
}
【这,是,一,串,阵】
列表到数组的转换
使用 toArray()方法
toArray()方法提供了一种将列表转换为数组的简单方法。下面的代码演示了它的工作原理。
public static void main(String args[])
{
//Creating an ArrayList
List<String> strList = new ArrayList<String>();
strList.add("this");
strList.add("is");
strList.add("a");
strList.add("string");
strList.add("array");
//converting to array
String[] strArr = strList.toArray(new String[0]);
for(int i = 0; i <= strArr.length - 1; i++)
System.out.print(strArr[i] + " ");
}
这是一个字符串数组
使用番石榴图书馆
在前一节中,我们看到了如何使用番石榴库将数组转换为列表。它还提供了 toArray() 方法,可用于将列表转换回数组。
public static void main(String args[])
{
//Creating an ArrayList
List<String> strList = new ArrayList<String>();
strList.add("this");
strList.add("is");
strList.add("a");
strList.add("string");
strList.add("array");
//converting to array
String[] strArr = Iterables.toArray(strList, String.class);
for(int i = 0; i <= strArr.length - 1; i++)
System.out.print(strArr[i] + " ");
}
这是一个字符串数组
写我们自己的方法
我们还可以定义自己的方法,将列表转换为数组。我们将循环遍历列表,使用 get() 方法获取每个元素,并使用数组索引将其添加到数组中。我们可以为不同的数据类型定义不同的方法,或者我们可以简单地使用泛型方法。
public static String[] listToArray(List<String> strList)
{
String[] strArr = new String[strList.size()];
for(int i = 0; i <= strList.size() - 1; i++)
strArr[i] = strList.get(i);
return strArr;
}
public static void main(String args[])
{
//Creating an ArrayList
List<String> strList = new ArrayList<String>();
strList.add("this");
strList.add("is");
strList.add("a");
strList.add("string");
strList.add("array");
//converting to array
String[] strArr = listToArray(strList);
for(int i = 0; i <= strArr.length - 1; i++)
System.out.print(strArr[i] + " ");
}
这是一个字符串数组
摘要
数组是一种简单而有用的数据结构,用于存储类似类型的数据。列表是一个接口,像ArrayList
和LinkedList
这样的类实现了这个接口。ArrayList 是一个动态数组,克服了数组大小有限的问题。一个人必须知道如何将一个数组转换成一个列表,反之亦然,才能充分利用两者的潜力。asList()和 toArray()方法是最常用的方法。我们还实现了自己的方法,使用列表的 add()方法将数组转换为列表,使用列表的 get()方法将列表转换为数组。我们还可以定义通用方法来处理其他数据类型。
在 Java 中初始化数组
原文:https://www.studytonight.com/java-examples/initializing-arrays-in-java
数组是一种线性数据结构,用于以有序的方式存储相似的元素。数组是一种非常简单但功能强大的数据结构,可用于各种任务。存储在数组中的每个元素都可以通过使用其索引值来访问。数组遵循从零开始的索引,这意味着第一个索引将为零。在本教程中,我们将学习用 Java 初始化数组的不同方法。
在 Java 中声明数组
在初始化之前,我们必须知道如何声明数组。声明意味着定义变量名称和将存储在数组中的元素的数据类型。下面的代码显示了声明数组的一般语法。
datatype[] variableName;
在 Java 中初始化数组
让我们学习一下给数组赋值的不同方法。
将所有数组元素初始化为零
我们可以简单地声明一个数组,并在一行代码中将数组的每个元素初始化为零。零是 Java 在我们声明数组大小时分配的默认值。下面的代码演示了这个场景。
public class InitializeDemo
{
public static void main(String[] args)
{
//Declaring array
int[] intArray;
//Initializing to Zero
intArray = new int[5];
//Printing the values
for(int i = 0; i < intArray.length; i++)
System.out.println(intArray[i]);
}
}
0
0
0
0
0
对于字符串数组,默认值为 null。
public class InitializeDemo
{
public static void main(String[] args)
{
//Declaring array
String[] strArray;
//Initializing to Zero
strArray = new String[5];
//Printing the values
for(int i = 0; i < strArray.length; i++)
System.out.println(strArray[i]);
}
}
零
零
零
零
零
一次初始化一个数组元素
我们并不总是想在数组中存储零。我们可以在单个 for 循环的帮助下逐个初始化每个元素。我们将使用元素的索引来初始化数组。
例如,让我们初始化一个数组来存储前 5 个自然数的平方。
public class InitializeDemo
{
public static void main(String[] args)
{
//Declaring array
int[] intArray;
//Defining the array length
intArray = new int[5];
//Initializing
for(int i = 0; i < intArray.length; i++)
intArray[i] = (i+1) * (i+1);
//Printing the values
for(int i = 0; i < intArray.length; i++)
System.out.println(intArray[i]);
}
}
1
4
9
16
25
如果我们使用多维数组,那么我们需要使用嵌套循环。下面的代码显示了如何初始化 2D 数组。
public class InitializeDemo
{
public static void main(String[] args)
{
//Declaring array
int[][] intArray;
//Defining the array length
intArray = new int[3][4];
//Initializing
for(int i = 0; i < intArray.length; i++)
for(int j = 0; j < intArray[0].length; j++)
intArray[i][j] = (i+1) * (j+1);
//Printing the values
for(int i = 0; i < intArray.length; i++)
{
for(int j = 0; j < intArray[0].length; j++)
System.out.print(intArray[i][j] + " ");
System.out.println();
}
}
}
1 2 3 4
2 4 6 8
3 6 9 12
我们也可以通过扫描仪类获取用户输入来初始化数组。
import java.util.Scanner;
public class InitializeDemo
{
public static void main(String[] args)
{
//Declaring array
int[] intArray;
//Defining the array length
intArray = new int[5];
Scanner s = new Scanner(System.in);
System.out.println("Enter the values: ");
//Initializing
for(int i = 0; i < intArray.length; i++)
intArray[i] = s.nextInt();
s.close();
System.out.println("The array contains: ");
//Printing the values
for(int i = 0; i < intArray.length; i++)
System.out.println(intArray[i]);
}
}
输入数值:
5
10
15
20
25
数组包含:
5
10
15
20
25
在声明时初始化数组
我们可以声明一个数组,同时用一行代码初始化它。当使用这种技术初始化时,我们不需要指定数组的大小。
public class InitializeDemo
{
public static void main(String[] args)
{
//Declaring array
int[] intArray = {3,6,9,12,15};
//Printing the values
for(int i = 0; i < intArray.length; i++)
System.out.println(intArray[i]);
}
}
3
6
9
12
15
使用数组.填充()方法
Arrays 类为我们提供了 fill()方法,该方法可以用一些元素填充整个数组或数组的一部分。此方法无法初始化数组,它用于修改已经初始化的数组。
如果我们使用下面的签名,那么数组的所有元素都将被设置为 value 参数。
public static void fill(int[] intArray, int value)
相反,如果我们使用以下语法,那么 fromIndex 和 toIndex 之间的所有元素(不包括)都将被设置为 value 参数。
public static void fill(int[] intArray, int fromIndex, int toIndex, int value)
下面的代码演示了 fill()方法的工作原理。我们也可以使用其他数据类型的数组。
import java.util.Arrays;
public class InitializeDemo
{
public static void main(String[] args)
{
int[] intArray = new int[10]; //Array initialized with zeroes.
System.out.println("Initial Array: " + Arrays.toString(intArray));
Arrays.fill(intArray, -5);//Changing all the elements to -5
System.out.println("Changing all elements of the array: " + Arrays.toString(intArray));
int fromIdx = 1, toIdx = 5;
Arrays.fill(intArray, fromIdx, toIdx, 0);//Changing some elements back to 0
System.out.println("Changing a few elements of the array: " + Arrays.toString(intArray));
}
}
初始数组:【0,0,0,0,0,0,0,0,0,0,0】
更改数组的所有元素:[-5,-5,-5,-5,-5,-5,-5,-5,-5,-5]
更改数组的一些元素:[-5,0,0,0,0,-5,-5,-5,-5]
使用 Arrays.setAll()方法
Arrays
类的 setAll()方法可以在生成器函数的帮助下初始化数组。这个生成器函数通过使用索引来计算数组值。
例如,让我们尝试用前 10 个自然数的平方初始化一个数组。
import java.util.Arrays;
public class InitializeDemo
{
public static void main(String[] args)
{
//Declaring array
int[] intArray;
intArray = new int[10];
//Initializing using setAll()
Arrays.setAll(intArray, (index) -> (index+1) * (index+1) );
//Printing the values
for(int i = 0; i < intArray.length; i++)
System.out.println(intArray[i]);
}
}
1
4
9
16
25
36
49
64
81
100
现在,让我们尝试初始化一个字符串数组。如果一个元素的指数小于 5,那么它应该有值 < 5 ,否则它应该有值 > =5 。
import java.util.Arrays;
public class InitializeDemo
{
public static void main(String[] args)
{
//Declaring array
String[] strArray;
strArray = new String[10];
//Initializing using setAll()
Arrays.setAll(strArray, (index) -> ((index < 5) ? "<5" : ">=5" ));
//Printing the values
for(int i = 0; i < strArray.length; i++)
System.out.println("Index: " + i + " Value: " + strArray[i]);
}
}
指数:0 值:< 5
指数:1 值:< 5
指数:2 值:< 5
指数:3 值:< 5
指数:4 值:< 5
指数:5 值:> =5
指数:6 值:> =5
指数:7 值:> =5
指数:8 值:> =5
使用 ArrayUtils.clone()方法
我们可以使用 clone()方法通过复制或克隆另一个数组来初始化一个数组。这仅用于创建现有数组的副本。它是 Apache Commons Lang 3 包的一部分。
import org.apache.commons.lang3.ArrayUtils;
public class InitializeDemo
{
public static void main(String[] args)
{
int[] intArray = {1, 3, 5, 7, 9};
int[] copy = ArrayUtils.clone(intArray);
for(int i = 0; i < copy.length; i++)
System.out.println(copy[i]);
}
}
1
3
5
7
9
使用 Arrays.copyOf()方法
我们还可以使用 Arrays 类的 copyOf()方法来创建另一个数组的副本。
此方法采用一个额外的整数参数来表示要复制的元素数量。
- 如果此参数小于原始数组的长度,则只复制前几个元素。
- 如果它大于原始数组的长度,那么额外的元素将被初始化为零。
- 如果它完全等于原始数组的长度,则创建一个精确的副本。
import java.util.Arrays;
public class InitializeDemo
{
public static void main(String[] args)
{
int[] intArray = {1, 3, 5, 7, 9};
int[] copy1 = Arrays.copyOf(intArray, 3);
int[] copy2 = Arrays.copyOf(intArray, 7);
int[] copy3 = Arrays.copyOf(intArray, 5);
System.out.println("Original Array: " + Arrays.toString(intArray));
System.out.println("Copied array with smaller length: " + Arrays.toString(copy1));
System.out.println("Copied array with greater length: " + Arrays.toString(copy2));
System.out.println("Copied array with same length: " + Arrays.toString(copy3));
}
}
原始数组:[1,3,5,7,9]
长度较小的复制数组:[1,3,5]
长度较大的复制数组:[1,3,5,7,9,0,0]
长度相同的复制数组:[1,3,5,7,9]
常见问题
问:初始化和声明数组有什么区别?
声明意味着设置将存储在数组中的元素的名称和数据类型。初始化意味着给数组元素设置一个初始值。
问:什么是动态数组?
动态数组是可以动态调整大小的数组。普通数组的大小是固定的,如果它们已经满了,我们就不能在其中插入额外的元素,但是动态数组没有这个问题。
问:如何将整数数组的所有元素初始化为 0?
如上所述,如果我们将空间分配给一个数组,那么默认情况下,所有数组元素都设置为 0。我们还可以使用其他方法,如 fill()和 setAll()来实现这一点。
摘要
数组是最常用的线性数据结构之一。Java 中有很多初始化数组的方法。大多数情况下,我们将使用 for 循环来初始化数组的元素,但是必须知道也可以用于初始化的不同方法。我们还学习了如何使用 clone()和 copyOf()方法将现有数组的内容复制到新数组中。
如何用 java 将流转换成数组
原文:https://www.studytonight.com/java-examples/how-to-convert-stream-to-an-array-in-java
在这篇文章中,我们将学习流到数组的转换。流是一个元素序列,它允许我们以函数方式执行操作,而数组是一个存储类似类型元素的对象。
在这里,我们有一些例子,我们将流转换为一个原始值数组。
举例时间:
让我们创建一个将流转换成数组的例子。这里,我们使用IntStream
的rangeClosed()
方法创建一个整数序列,然后使用toArray()
方法转换成一个数组。
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args){
IntStream integerStream = IntStream.rangeClosed(1, 5);
// Convert stream into Array
int[] arr = integerStream.toArray();
for(int e:arr) {
System.out.println(e);
}
}
}
1
2
3
4
5
另一个例子的时间:
让我们再举一个例子,从流中获取数组。这里,我们从一个列表中创建了一个流,并通过指定数组的类型使用toArray()
方法进行了转换。另一方面,我们也将数组转换为流,这样如果需要的话,我们就可以得到以前类型的元素。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args){
Stream<String> stream = List.of("UK", "US", "BR").stream();
// Convert string stream into string array
String[] strArray = stream.toArray(String[]::new);
for(String str : strArray) {
System.out.println(str);
}
System.out.println("\nAfter conversion to array:");
// Array to stream conversion
Stream<String> stringStream = Arrays.stream(strArray);
stringStream.forEach(System.out::println);
}
}
英国
美国
BR
T4【转换成阵后:
英国
美国
BR
如何在 Java 中连接数组
原文:https://www.studytonight.com/java-examples/how-to-join-arrays-in-java
在这篇文章中,我们将学习使用 Java 代码将多个数组连接成一个数组。可能会有这样一种情况,我们需要将两个或多个数组的数据组合成一个数组,例如将两个源组合成一个,以单个源的形式传输数据。
在这里,我们使用 Java 8 流 API 来连接数组,并以数组或流的形式获得结果。请看这里给出的例子。
举例时间:
让我们举一个例子,将两个字符串数组连接成一个字符串数组。这里,我们使用Stream
的of()
方法,该方法返回一个流序列,该流序列通过使用toArray()
方法进一步转换为数组。
import java.util.stream.Stream;
public class Main {
public static void main(String[] args){
String[] asia = new String[]{"India", "Russia", "Japan"};
String[] europe = new String[]{"Poland", "Germany", "France"};
//join arrays
String[] countries = Stream.of(asia,europe).flatMap(Stream::of).toArray(String[]::new);
for (String country : countries) {
System.out.println(country);
}
}
}
印度
俄国
日本
波兰
德国
法国
另一个例子的时间:
我们可以通过使用 concat()方法组合两个流,该方法返回指定类型的流。该示例解释了如何将两个或多个流连接成一个流,就像我们在上面的示例中合并两个数组一样。
import java.util.stream.Stream;
public class Main {
public static void main(String[] args){
Stream<Integer> stream1 = Stream.of(1, 2, 3);
Stream<Integer> stream2 = Stream.of(4, 5, 6);
//concat arrays
Stream<Integer> result = Stream.concat(stream1, stream2);
result.forEach(System.out::println);
}
}
1
3
5
2
4
6
Java 中的数组到ArrayList
原文:https://www.studytonight.com/java-examples/array-to-arraylist-in-java
在这篇文章中,我们将把一个数组转换成ArrayList
。ArrayList
是 Java 中List
接口的实现类,用于存储基于索引的元素,而数组用于存储类似类型的元素。
可能会有这样一种情况,您正在处理数据集合,您的数据存储在一个数组中,并且您想要将它转换成ArrayList
。
这里,我们使用的是Arrays
类的asList()
方法,它返回一个列表,然后我们可以从这个列表中获得ArrayList
。
addAll()方法属于Collections
类,可用于向ArrayList
中添加数组元素。
举例时间:
让我们创建一个从数组元素获取ArrayList
的例子。这里,我们在构造器内部使用asList()
方法,因为 ArrayList 有一个构造器来获取列表作为参数。
import java.util.ArrayList;
import java.util.Arrays;
public class Main {
public static void main(String[] args){
String[] fruits = {"Apple", "Orange", "Banana"};
for (int i = 0; i < fruits.length; i++) {
System.out.println(fruits[i]);
}
ArrayList<String> arrayList = new ArrayList<>(Arrays.asList(fruits));
System.out.println(arrayList);
}
}
苹果
橘子
香蕉
【苹果、橘子、香蕉】
另一个例子的时间:
让我们再举一个例子来理解数组到ArrayList
的转换。这里,我们使用 addAll()方法将所有数组元素添加到一个 ArrayList 中。请看下面的例子。
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args){
String[] fruits = {"Apple", "Orange", "Banana"};
for (int i = 0; i < fruits.length; i++) {
System.out.println(fruits[i]);
}
ArrayList<String> arrayList = new ArrayList<>();
Collections.addAll(arrayList, fruits);
System.out.println(arrayList);
}
}
苹果
橘子
香蕉
【苹果、橘子、香蕉】
如何在 Java 中返回数组
原文:https://www.studytonight.com/java-examples/how-to-return-an-array-in-java
在本文中,我们将学习如何在 Java 中返回一个数组。在本教程的最后,您将学习如何在 Java 方法中传递数组,如何在方法内部对它们执行操作,以及最后如何从 Java 方法返回数组。
Java 程序:Java 中返回数组
在下面给出的程序中,我们创建了一个方法public static int[] getArray()
,该方法将返回一个分配给arr
的数组arr
,该数组在方法调用语句int[] arr = getArray();
中声明,最后将打印该数组。若要返回数组,函数的返回类型必须是Arrays
类型。
public class StudyTonight
{
public static void main(String args[])
{
int[] arr=getArray();
for (int i = 0; i < arr.length; i++)
System.out.print( arr[i]+ " ");
}
public static int[] getArray()
{
int[] arr={17,18,19,20,21};
return arr;
}
}
17 18 19 20 21
由于上面的代码工作正常,让我们再添加一个如何将数组传递给元素的功能。现在,我们将实现一个程序,其中一个方法将接受一个数组并返回一个数组的反例。
示例:在 Java 中返回数组并将数组作为参数传递
在下面的程序中,我们在方法 reverseArray()中传递了一个数组,然后我们反转了一个数组,并使用 return 关键字返回它,之后,它被分配给原始数组。
public class StudyTonight
{
public static void main(String args[])
{
int[] arr={17,18,19,20,21};
//calling reverse method to reverse an array
arr=reverseArray(arr);
//printing an array
for (int i = 0; i < arr.length; i++)
System.out.print( arr[i]+ " ");
}
public static int[] reverseArray(int arr[])
{
int end = arr.length - 1;
int start = 0;
//logic for reverse of an Array
while (start < end)
{
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
//returning an reversed array
return arr;
}
}
21 20 19 18 17
示例:从函数返回对象数组
在下面给出的程序中,我们将从一个函数返回一个对象数组。我们可以看到我们有一个类Student
,其中stud_name
和roll_no
是数据成员。当我们调用getStudents()
方法时,它会创建一个Student
类的数组并将其返回到Student[] arr
中,之后,我们会打印每个对象的数据。
class Student
{
String stud_name;
int roll_no;
//constructor for initializing data members
Student(String stud_name, int roll_no)
{
this.stud_name = stud_name;
this.roll_no = roll_no;
}
}
public class StudyTonight
{
public static void main(String args[])
{
Student[] arr = getStudents();
//print data of each object
for(Student obj:arr)
{
System.out.println("Name: "+obj.stud_name+" Roll No: "+obj.roll_no);
}
}
public static Student[] getStudents()
{
Student[] arr= new Student[2];
arr[0] = new Student("ABC",123);
arr[1] =new Student("DEF",456);
//return an array of objects of Student class
return arr;
}
}
名称:ABC 辊号:123
名称:DEF 辊号:456
结论
要返回一个数组,我们在函数内部使用一个 return 语句,函数的返回类型必须是Arrays
类型。当我们想用 Java 方法返回一组数据时,这非常方便。
如何在 Java 中将数组转换成列表
原文:https://www.studytonight.com/java-examples/how-convert-an-array-to-a-list-in-java
在本教程中,我们将学习如何在 Java 中将数组转换为列表。要将数组转换为列表,我们有三种方法
- 通过将数组的每个元素显式添加到列表中。
- 通过使用
Arrays.asList()
方法。 - 通过使用
Collections.addAll()
方法
示例:通过将数组中的每个元素添加到列表中,从数组创建列表。
在这个程序中,我们将迭代一个数组,并将每个元素添加到一个数组中。这是一种非常传统的方式,我们需要遍历整个数组来将元素添加到列表中。
import java.util.*;
public class StudyTonight
{
public static void main(String[] args)
{
List<String> courses= new ArrayList<String>();
String array[] = {"Bangalore","Mumbai","Delhi","Noida"};
for(int i =0;i<array.length;i++)
{
courses.add(array[i]);
}
for(String course: courses)
{
System.out.println(course);
}
}
}
班加罗尔
【孟买】
【德里】
示例:使用Arrays.asList()
方法从数组创建列表。
在给定的程序中,我们使用来自Arrays
类的asList()
方法,该类接收一个数组并将其转换为列表。这个方法比上面的例子更有效,而且不需要遍历整个数组。
import java.util.*;
public class StudyTonight
{
public static void main(String[] args)
{
String courses[]={"Bangalore","Mumbai","Delhi","Noida"};
List<String> courseList= new ArrayList<String>(Arrays.asList(courses));
for (String course: courseList)
{
System.out.println(course);
}
}
}
班加罗尔
【孟买】
【德里】
示例:使用Collections.addAll()
方法从数组创建列表。
在这个程序中,我们使用来自一个Collections
类的addAll()
方法,该方法接受两个参数,即列表和数组,并将该数组转换为列表。
import java.util.*;
public class StudyTonight
{
public static void main(String[] args)
{
String array[]={"Bangalore","Mumbai","Delhi","Noida"};
List<String> courses= new ArrayList<String>();
Collections.addAll(courses, array);
for (String course: courses)
{
System.out.println(course);
}
}
}
班加罗尔
【孟买】
【德里】
结论:我们可以通过三种方法将 array 转换为 List,分别是将 Array 的每个元素显式添加到 List、使用Arrays.asList()
方法和使用Collections.addAll()
方法。这里,第一种方法非常直观和简单,但为此,我们需要遍历整个数组。
Java 集合
在 Java 中向数组和ArrayList
添加元素
原文:https://www.studytonight.com/java-examples/add-elements-to-array-and-arraylist-in-java
数组是 Java 中相似对象的固定大小集合。ArrayList
与数组非常相似,但是没有大小限制。
在本教程中,我们将学习如何在数组和ArrayList
中插入元素。
数组和ArrayList
的区别
在学习如何插入元素之前,让我们先快速了解一下数组和ArrayList
之间的一些区别。
履行
数组是一种简单的线性数据结构,由 Java 提供。ArrayList 是 Java 中实现列表接口的类,是集合框架的一部分。ArrayList
在内部使用数组进行操作。
访问和修改元素
数组的元素通过使用索引来访问和修改。ArrayList 类提供了 getter 和 setter 方法来访问和修改它的内容。
元素类型
数组能够存储基元类型和非基元类型。ArrayList
只能存储非基元类型。然而,我们可以使用包装类来存储原始类型。
大小
如上所述,数组具有固定大小,而ArrayList
具有动态大小。对于一个数组,我们需要在实例化过程中定义它的大小。我们不能超过这个尺寸限制。对于ArrayList
,当我们需要向其中添加更多元素时,其大小会动态增加。创建了一个更大的新底层数组来容纳额外的项目。
附加元素
让我们学习如何向数组和ArrayList
追加元素。追加意味着添加到结尾。
附加到数组
我们将首先创建一个更大尺寸的新数组。接下来,我们将把元素转移到这个新数组中。最后,我们可以在这个新数组的末尾添加新项。下面的代码演示了这一点。
import java.util.Arrays;
public class Demo
{
public static int[] appendToArray(int[] arr, int elementToAdd)
{
int[] newArr = new int[arr.length + 1];//new array of larger size
//copying elements from old to new array
for(int i = 0; i < arr.length; i++)
newArr[i] = arr[i];
newArr[newArr.length - 1] = elementToAdd;//Adding the element
return newArr;
}
public static void main(String[] args)
{
int[] arr = {1, 2, 3, 4, 5, 6};
System.out.println("Initial Array: " + Arrays.toString(arr));
arr = appendToArray(arr, 7);
arr = appendToArray(arr, 8);
arr = appendToArray(arr, 9);
System.out.println("After adding the element: " + Arrays.toString(arr));
}
}
初始数组:[1,2,3,4,5,6]
添加元素后:[1,2,3,4,5,6,7,8,9]
Arrays
类提供了一个简单的 copyOf() 方法,将元素从旧数组复制到新数组。该方法以旧数组和新数组的大小为参数。让我们通过使用 copyOf()方法而不是 for 循环来重写上面的代码。
import java.util.Arrays;
public class Demo
{
public static int[] appendToArray(int[] oldArr, int elementToAdd)
{
//creating a new array and copying the elements
int[] newArr = Arrays.copyOf(oldArr, oldArr.length + 1);
newArr[newArr.length - 1] = elementToAdd;
return newArr;
}
public static void main(String[] args)
{
int[] arr = {1, 2, 3, 4, 5, 6};
System.out.println("Initial Array: " + Arrays.toString(arr));
arr = appendToArray(arr, 7);
arr = appendToArray(arr, 8);
arr = appendToArray(arr, 9);
System.out.println("After adding the element: " + Arrays.toString(arr));
}
}
初始数组:[1,2,3,4,5,6]
添加元素后:[1,2,3,4,5,6,7,8,9]
附加到ArrayList
附加到ArrayList
非常简单。这个类有一个 add() 方法,在列表的末尾添加一个元素。下面的代码演示了这一点。
import java.util.ArrayList;
public class Demo
{
public static void main(String[] args)
{
ArrayList<Integer> arrList = new ArrayList<>();
arrList.add(1);
arrList.add(2);
arrList.add(3);
System.out.println("ArrayList: " + arrList);
}
}
数组列表:[1、2、3]
插入元素
现在让我们尝试在任何索引处插入元素。确保索引在边界内,以避免 IndexOutOfBoundsException。我们将
插入数组
首先,我们将创建一个新的数组来容纳额外的元素。要在给定的索引处插入,我们需要将该索引处的元素以及该索引之后的所有元素向右移动一个位置。
例如,考虑初始数组[10,20,30,40],我们需要在索引 1 处插入 50。元素 20、30 和 40 将向右移动一个位置。得到的数组将是[10,50,20,30,40]。
import java.util.Arrays;
public class Demo
{
public static int[] insertAtIndex(int[] arr, int elementToAdd, int index)
{
int[] newArr = new int[arr.length + 1];//new array of larger size
//Copying and adding the new element
int currIdx = 0;
for(int i = 0; i < newArr.length; i++)
{
if(i == index)
newArr[i] = elementToAdd;
else {
newArr[i] = arr[currIdx];
currIdx += 1;
}
}
return newArr;
}
public static void main(String[] args)
{
int[] arr = {10, 20, 30, 40};
System.out.println("Initial Array: " + Arrays.toString(arr));
arr = insertAtIndex(arr, 50, 1);
System.out.println("After adding 50 at index 1: " + Arrays.toString(arr));
}
}
初始数组:[10,20,30,40]
在索引 1 处添加 50 后:[10,50,20,30,40]
在ArrayList
中插入
add()方法有一个重载版本,它也接受我们想要添加元素的索引。项目从一个地方移到右边,为新项目腾出空间。
import java.util.ArrayList;
public class Demo
{
public static void main(String[] args)
{
ArrayList<Integer> arrList = new ArrayList<>();
arrList.add(10);
arrList.add(20);
arrList.add(30);
arrList.add(40);
System.out.println("Initial ArrayList: " + arrList);
arrList.add(1, 50);
System.out.print("After adding 50 at index 1: " + arrList);
}
}
初始ArrayList
:[10,20,30,40]
在索引 1 处添加 50 后:[10,50,20,30,40]
摘要
在数组中插入元素非常复杂。我们需要创建一个新数组,并传输旧数组的内容。然而,ArrayList
提供了一个方便的 add()方法来追加或插入元素。请确保索引有效,以避免索引越界错误。注意,add()方法的最坏情况时间复杂度为 O(N) 。这是因为创建了一个新的底层数组。
单行列表初始化
原文:https://www.studytonight.com/java-examples/list-initialization-in-a-single-line
列表是 Java 中的一个接口,由ArrayList
和LinkedList
这样的类来实现。列表接口实现了集合接口。
在本教程中,我们将学习一些在 Java 中初始化列表的单行代码。
Arrays.asList()方法
我们可以使用 asList()方法从数组创建一个列表。这个方法可以取 varargs ,所以我们甚至不需要数组来初始化列表。我们可以直接将元素传递给这个方法。
import java.util.Arrays;
import java.util.List;
public class Demo
{
public static void main(String[] args)
{
List<String> listOfStrings = Arrays.asList("Justin", "Jessica", "Simon", "Harry");
System.out.print(listOfStrings);
}
}
【贾斯汀、杰西卡、西蒙、哈利】
此方法返回的实例是由输入数组支持的列表。这使得初始化后的列表大小固定,我们无法在其中添加更多的元素。如果我们试图添加一个元素,那么我们将得到一个不支持操作异常。下面的代码演示了这个场景。
import java.util.Arrays;
import java.util.List;
public class Demo
{
public static void main(String[] args)
{
List<String> listOfStrings = Arrays.asList("Justin", "Jessica", "Simon", "Harry");
listOfStrings.add("Victor");//Error
}
}
线程“main”Java . lang . unsupportedoperationexception
在 Java . base/Java . util . abstract list . add(abstract list . Java:153)
在 Java . base/Java . util . abstract list . add(abstract list . Java:111)
在 Demo.main(Demo.java:9)
另外需要注意的是,数组和列表将有对对象的共享引用。不会创建新对象并将其添加到列表中。我们可以通过打印对象并查看唯一的 hashcode 来验证这一点。在下面的代码输出中,数组和列表中对象的 hashcode 是相同的,这意味着它是同一个对象。
import java.util.Arrays;
import java.util.List;
public class Demo
{
public static void main(String[] args)
{
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
Object[] objectArr = {o1, o2, o3};
List<Object> listOfObjects = Arrays.asList(objectArr);//Creating a List of Objects
System.out.println("Object o2 from Array: " + objectArr[1]);
System.out.println("Object o2 from List: " + listOfObjects.get(1));
}
}
数组中的对象 O2:Java . lang . Object @ 36 BAF 30 c
列表中的对象 O2:Java . lang . Object @ 36 BAF 30 c
在 Java 中 8 流
流也可以在 Java 中初始化列表。我们可以使用 Stream.of() 方法来创建一个 Stream。接下来,我们将使用 collect() 方法收集列表中的流元素。
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Demo
{
public static void main(String[] args)
{
List<String> listOfStrings = Stream.of("Justin", "Jessica", "Simon")
.collect(Collectors.toList());
System.out.print(listOfStrings);
}
}
【贾斯汀、杰西卡、西蒙】
使用列表()方法
List.of()方法是在 Java 9 中引入的,可以在一行代码中初始化一个列表。我们需要将元素传递给这个方法,它将返回一个 List 实例。Java 9 包含该方法的几个重载版本,以提供更好的性能。它还包含一个 varargs 重载方法来处理更多的元素。
import java.util.List;
public class Demo
{
public static void main(String[] args)
{
List<String> listOfStrings = List.of("Justin", "Jessica", "Simon");
System.out.print(listOfStrings);
}
}
【贾斯汀、杰西卡、西蒙】
请注意,返回的列表是不可变的,不能更改。如果我们尝试修改列表,我们将获得不支持操作例外。
import java.util.List;
public class Demo
{
public static void main(String[] args)
{
List<String> listOfStrings = List.of("Justin", "Jessica", "Simon");
listOfStrings.add("Victor");//Error
}
}
线程“main”Java . lang . unsupportedoperationexception
在 Java . base/Java . util . immogratecollections . uoe(immogratecollections . Java:73)
在 Java . base/Java . util . immogratecollections $ abstractimgratecollection . add(immogratecollections . Java:77)
在 Demo.main(Demo.java:8)
双括号语法
我们可以使用双括号语法在 Java 中初始化一个列表。外部大括号用于声明扩展对象类型的匿名内部类。
内部的一对大括号称为实例初始化块,我们将使用它向列表中添加元素。
不建议使用这种方法,因为它每次都会创建一个新类。它还保存对封闭实例的隐藏引用,这可能会导致内存泄漏。
import java.util.List;
import java.util.ArrayList;
public class Demo
{
public static void main(String[] args)
{
List<String> listOfStrings = new ArrayList<String>() {
{
add("Justin");
add("Jessica");
add("Simon");
}
};
System.out.print(listOfStrings);
}
}
【贾斯汀、杰西卡、西蒙】
外部库
我们可以使用番石榴或阿帕奇公共库来初始化 Java 中的列表。
使用 Apache 公共集合
我们可以使用 ListUtils 类的 unmodifiableList()方法来创建一个不可修改的列表。我们可以将现有列表传递给这个方法。或者我们可以在未修改的列表()中使用 Arrays.asList()方法。
import java.util.List;
import org.apache.commons.collections4.ListUtils;
import java.util.Arrays;
public class Demo
{
public static void main(String[] args)
{
List<String> listOfStrings = ListUtils.unmodifiableList(
Arrays.asList("Justin", "Jessica", "Simon", "Harry")
);
System.out.print(listOfStrings);
}
}
【贾斯汀、杰西卡、西蒙、哈利】
这个方法并不经常使用,因为我们只需要借助 Arrays.asList()方法就可以获得同样的结果。
使用番石榴图书馆
番石榴库可以初始化一个可变和不可变的列表。List 类的 newArrayList()方法将元素作为参数,并返回一个用这些元素初始化的可变ArrayList
。
import java.util.List;
import com.google.common.collect.Lists;
public class Demo
{
public static void main(String[] args)
{
List<String> listOfStrings = Lists.newArrayList("Justin", "Jessica", "Simon");
System.out.print(listOfStrings);
}
}
【贾斯汀、杰西卡、西蒙】
为了创建一个不可变的列表,我们将使用 ImmutableList.of()方法。番石榴提供了这个方法的几个重载版本,以获得更好的性能。它还有一个 varargs 重载方法来处理更多的元素。
import java.util.List;
import com.google.common.collect.ImmutableList;
public class Demo
{
public static void main(String[] args)
{
List<String> listOfStrings = ImmutableList.of("Justin", "Jessica", "Harry");
System.out.print(listOfStrings);
}
}
【贾斯汀、杰西卡、哈利】
摘要
在本教程中,我们学习了仅使用一行代码在 Java 中初始化列表的不同方法。我们讨论了几种创建可变和不可变列表的方法。上述任何一种方法都可以使用,因为它们都具有相当的性能。但是,不建议使用双括号方法,因为这会导致大量开销。
Java 泛型
通用的意思是不特定或不固定的东西。在 Java 中,泛型类和方法被创建来处理不同的数据类型和对象。
我们只是为类或方法可以接受的类型创建一个参数。泛型提供了一个额外的抽象层,帮助我们避免运行时错误。他们还提供型安全。让我们进一步了解 Java 中的泛型。
Java 泛型类
假设,我们需要一个可以处理任何对象类型的类。我们可以使用菱形运算符(< > ) 在 Java 中创建一个泛型类。
考虑下面显示的例子。菱形运算符之间的字母 T 称为类型参数。可以使用String
类型、Integer
类型甚至双精度来创建类对象。
//Generic class with parameter type T
class GenericClass<T>
{
T field1;//Object of type T
GenericClass(T f1)
{
this.field1 = f1;
}
}
public class GenericsDemo
{
public static void main(String[] args)
{
GenericClass<String> g1 = new GenericClass("100");
GenericClass<Integer> g2 = new GenericClass(100);
GenericClass<Double> g3 = new GenericClass(100.0);
}
}
在上面的例子中,我们只有一个类型参数。我们还可以使用多个类型参数来创建泛型类。下面是一个例子。
//Generic Class with multiple type parameters
class GenericClass<E, T>
{
E field1;//Object of type E
T field2;//Object of type T
GenericClass(E f1, T f2)
{
this.field1 = f1;
this.field2 = f2;
}
}
public class GenericsDemo
{
public static void main(String[] args)
{
GenericClass<String, Integer> g1 = new GenericClass("100", 100);
GenericClass<Integer, String> g2 = new GenericClass(100, "100");
GenericClass<Double, String> g3 = new GenericClass(100.0, "100");
}
}
Java 泛型方法
就像类一样,Java 中的方法也可以采用类型参数。这将使我们能够对不同的对象类型使用相同的方法。
考虑下面的代码,它使用 Generic print()方法来打印对象。Parameter
类型为 T 的 Generic 方法,我们可以在方法实现的任何地方使用这个类型 T。即使方法返回 void,也必须使用 diamond 运算符。
public class GenericsDemo
{
public static <T> void print(T object)
{
System.out.println(object);
}
public static void main(String[] args)
{
String s = "100";
Integer i = 100;
Double d = 100.0;
print(s);
print(i);
print(d);
}
}
100
100
100.0
就像泛型类一样,g 泛型方法也可以取多个类型参数。例如,让我们创建一个方法,将任意类型的两个列表作为参数,它应该打印这两个列表。我们可以在菱形运算符中定义两种Parameter
类型(T 和 E)。
import java.util.ArrayList;
import java.util.LinkedList;
public class GenericsDemo
{
public static <T, E> void printLists(ArrayList<T> l1, LinkedList<E> l2)
{
System.out.println(l1);
System.out.println(l2);
}
public static void main(String[] args)
{
ArrayList<Integer> al = new ArrayList<>();
al.add(5);
al.add(10);
al.add(15);
LinkedList<String> ll = new LinkedList<>();
ll.add("five");
ll.add("ten");
ll.add("fifteen");
printLists(al, ll);
}
}
【5,10,15】
【五,十,十五】
有界泛型方法
泛型类和方法为用户提供了很大的自由,但这有时会对我们不利。我们可以使用扩展关键字来限制泛型接受的类型范围。
<T extends ClassName>
这将只允许泛型类或方法中的父类及其所有子类。
例如,让我们创建三个类(ClassA、ClassB 和 ClassC),并从 ClassA 扩展 ClassB。然后,下面显示的 boundedPrint()方法将对类 a 和类 b 的对象起作用。
class ClassA
{
public void printClassA()
{
System.out.println("Class A");
}
}
class ClassB extends ClassA
{
public void printClassB()
{
System.out.println("Class B");
}
}
class ClassC
{
public void printClassC()
{
System.out.println("Class C");
}
}
public class GenericsDemo
{
//Bounded Generic Method
public static <T extends ClassA> void boundedPrint(T object)
{
System.out.println("Object of ClassA or a subclass of ClassA");
}
public static void main(String[] args)
{
ClassA a = new ClassA();
ClassB b = new ClassB();
boundedPrint(a);
boundedPrint(b);
}
}
类甲的对象或类甲的子类
类甲的对象或类甲的子类
然而,如果我们对 ClassC 的对象使用这个方法,我们会得到一个编译错误。
public static void main(String[] args)
{
ClassC c = new ClassC();
boundedPrint(c);//Compilation error
}
线程“main”Java . lang . error:未解决的编译问题:
genericsdode 类型中的方法 boundprint(T)不适用于 genericsdode . main(genericsdode . Java:35)处的参数(ClassC)
我们也可以将有界泛型用于实现接口的类。我们将使用带有 extends 关键字的接口名称来代替类名。
<T extends Interface>
我们还可以一起使用类和接口来施加更严格的限制。
<T extends Class & Interface>
泛型中的类型安全
使用泛型的一个主要优势是它提供了类型安全。如果我们已经为泛型定义了一个类型,那么编译器知道期望什么对象,并在编译时返回一个错误,而不是给出一个运行时错误。
例如,如果我们创建一个ArrayList
来存储整数,并且没有为其元素指定类型,那么下面的代码将成功编译。但是我们会在运行时得到一个错误。
import java.util.ArrayList;
public class GenericsDemo
{
public static void main(String[] args)
{
ArrayList l = new ArrayList();
l.add(100);//Integer
l.add(101);//Integer
l.add("102");//String
Integer i1 = (Integer)l.get(0);
Integer i2 = (Integer)l.get(1);
Integer i3 = (Integer)l.get(2);
}
}
线程“main”Java . lang . class castexception 中的异常:类 java.lang.String 无法强制转换为类 java.lang.Integer(Java . lang . string 和 Java . lang . integer 位于 generic demo . main(generic demo . Java:48)处加载程序“bootstrap”的模块 java.base 中)
相反,如果我们使用菱形运算符并将类型定义为整数,我们将在编译时得到一个错误。这减少了运行时的开销。此外,我们不需要显式转换,因为编译器知道将返回哪种类型,并应用隐式转换。
import java.util.ArrayList;
public class GenericsDemo
{
public static void main(String[] args)
{
ArrayList<Integer> l = new ArrayList<Integer>();
l.add(100);//Integer
l.add(101);//Integer
l.add("102");//String
Integer i1 = l.get(0);
Integer i2 = l.get(1);
Integer i3 = l.get(2);
}
}
线程“main”Java . lang . error:未解决的编译问题:
类型 ArrayList 中的 add(Integer)
【T3)
泛型中的类型擦除
泛型在编译时使用一种称为类型擦除的技术。类型擦除将泛型的Parameter
类型 T 替换为对象类(或者在泛型有界的情况下为父类),并在编译时强制类型约束。这确保了在运行时不需要做额外的工作,并减少了运行时开销。它确保不会为参数化类型创建新类。
例如,考虑以下通用方法。
public static <T> void print(T obj)
{
//Implementation
}
编译时,类型参数 T 将被对象类型替换,代码如下所示。
public static void print(Object obj)
{
//Implementation
}
如果类型参数是有界的,则在编译时用父类替换它。
public static <T extends ClassA> void boundedPrint(T obj)
{
//Implementation
}
public static void boundedPrint(ClassA obj)
{
//Implementation
}
由于类型擦除,泛型不能与基元类型一起工作。这是因为原始类型没有扩展对象类,或者任何其他类,因此在类型擦除过程中,编译器不能替换它们。但是我们总是可以使用包装类(比如整型和双精度型)来代替原始类型。
摘要
在本教程中,我们学习了 Java 中泛型的基础知识。它为程序员解决了很多问题,并使我们的代码可重用。一个通用方法可以用于多种类型的对象。泛型还提供类型安全,不需要显式转换。泛型帮助我们为不同类型的对象编写通用算法。
Java 中的hashCode()
方法
原文:https://www.studytonight.com/java-examples/hashcode-method-in-java
哈希是为给定密钥生成唯一值的技术。哈希用于实现HashMap
,这些数据结构提供了一种更快、更有效的数据查找方式。哈希被许多不同的集合使用,比如HashMap
和HashSet
。hashCode()方法为给定的键返回一个整数 值(也称为哈希或哈希值)。
Java 等于()方法
在继续之前,我们必须了解 equals()方法。equals()方法是一个简单的方法,如果被比较的两个对象相等,返回 true,否则返回 false 。
- equals()方法主要由数据结构用来检查数据结构中是否存在值。这是通过将密钥与数据结构中的所有元素进行比较来完成的。
- HashCode()方法通常是对具有 equals()方法的类的添加。增加 hashCode()方法是为了减少 equals()方法所做的比较次数。
- 如果 equals()方法改变了,那么相应的 hashCode()方法也应该改变。
- 例如,考虑一个有学生名字和 GPA 的学生班级。如果我们说如果两个学生的名字相同,那么他们就是平等的,那么 HashCode()方法也应该只关注学生的名字。
- 基本上 hashCode()不应该考虑 equals()方法没有用于相等检查的任何字段。
equals()方法的示例如下所示。
public class HashDemo
{
public static void main(String args[])
{
String str1 = "String 1";
String str2 = "String 2";
String str3 = "String 1";
System.out.println("String 1 is equal to String 2: " + str1.equals(str2));
System.out.println("String 1 is equal to String 1: " + str1.equals(str3));
}
}
字符串 1 等于字符串 2:假
字符串 1 等于字符串 1:真
hashCode()方法
如上所述,hashCode()方法为给定的输入返回一个整数值。不同的 ide 都有自己的 hashCode()方法的实现,我们可以直接使用或者覆盖它们。任何 hashCode()方法都应该满足以下三个条件。这些条件合在一起也被称为哈希码契约。
- hashCode()方法必须在每次时为特定对象返回相同的值,假设我们没有更改 hashCode()方法或 equals()方法的实现,并且该对象没有以任何方式被修改。
- 如果 equals()方法为两个对象返回 true,那么 hashCode()方法必须为两个对象返回相同的哈希值。
- hashCode()可以根据 equals()方法为两个不相等的对象返回相同的哈希值。
即使 hashCode()方法对于不同的输入返回相同的哈希值是完全有效的,但是这种方法在HashMap
的实现中使用时会导致大量的冲突。在这种情况下,HashMap
的查找时间将不是常数(0(1))。有一些方法可以处理这些碰撞,比如探测和链接,但是避免它们是一个更好的选择。避免冲突的最好方法是编写一个强大的 hashCode()方法。
内置 hashCode()方法的示例
下面的代码演示了 Eclipse IDE 的内置 hashCode()方法的工作原理。
public class HashDemo
{
public static void main(String args[])
{
String str1 = "String 1";
String str2 = "String 1";
String str3 = "String 3";
System.out.println("Hash of Str1: " + str1.hashCode());
System.out.println("Hash of Str2: " + str2.hashCode());
System.out.println("String 1 is equal to String 1: " + str1.equals(str2));
System.out.println("Hash of Str3: " + str3.hashCode());
System.out.println("String 1 is equal to String 3: " + str1.equals(str3));
}
}
str 1 的哈希:1859651586
str 2 的哈希:1859651586
字符串 1 等于字符串 1:真
str 3 的哈希:1859651588
字符串 1 等于字符串 3:假
HashMap
的工作
HashMap
是一种基于数据哈希值将数据存储在不同桶中的数据结构。这样当我们需要搜索一个元素时,我们可以直接去那个特定的桶,而不需要搜索每个桶。HashMap
的基本工作总结如下。
- 当添加一个元素时,它的哈希值是通过使用 hashCode()函数生成的。
- 这个哈希值决定了元素应该添加到的桶。如果 hashCode()方法不是很强大,并且为不同的元素生成重复的值,那么在一个桶中会出现多个元素。
- 搜索元素时,首先为元素生成 hashCode(),我们直接在应该出现的桶中搜索。如果桶中存在多个对象,那么我们可以使用 equals()方法在桶中搜索正确的元素。
示例:实现 hashCode()方法
让我们尝试创建一个学生类,并实现我们自己的 hashCode()和 equals()方法。首先,我们将实现一个基本的 hashCode()方法,它只根据学生名字的第一个字母返回一个整数。
class Student
{
String name;
int regNo;
double gpa;
Student(String name, int regNo, double gpa)
{
this.name = name;
this.regNo = regNo;
this.gpa = gpa;
}
@Override
public int hashCode()
{
return (int)this.name.charAt(0) - 64;
}
@Override
public boolean equals(Object obj)
{
if(obj == null)
return false;
if(this == obj)
return true;
if(obj.getClass() != this.getClass())
return false;
Student s = (Student)obj;
return this.name == s.name &&
this.regNo == s.regNo &&
this.gpa == s.gpa;
}
}
public class HashDemo
{
public static void main(String args[])
{
Student s1 = new Student("Justin", 59, 7.6);
Student s2 = new Student("Jessica", 21, 8.0);
Student s3 = new Student("Paul", 20, 5.5);
Student s4 = new Student("Justin", 59, 7.6);
System.out.println("Hash of s1: " + s1.hashCode());
System.out.println("Hash of s2: " + s2.hashCode());
System.out.println("Hash of s3: " + s3.hashCode());
System.out.println("s1 is the same as s2: " + s1.equals(s2));
System.out.println("s1 is the same as s4: " + s1.equals(s4));
}
}
S1:10 的哈希
s2:10 的哈希
S3:16 的哈希
s1 与 S2 相同:假
s1 与 s4 相同:真
上面的 hashCode()方法是完全有效的,因为它满足合同的所有条件,但是它不是很强,因为名字第一个字母相同的不同学生将被分配相同的哈希值。让我们使用类的其他字段来编写一个更强的 hashCode()方法。
class Student
{
String name;
int regNo;
double gpa;
Student(String name, int regNo, double gpa)
{
this.name = name;
this.regNo = regNo;
this.gpa = gpa;
}
@Override
public int hashCode()
{
return ((int)this.name.charAt(0) - 64) * this.regNo * (int)this.gpa;
}
@Override
public boolean equals(Object obj)
{
if(obj == null)
return false;
if(this == obj)
return true;
if(obj.getClass() != this.getClass())
return false;
Student s = (Student)obj;
return this.name == s.name &&
this.regNo == s.regNo &&
this.gpa == s.gpa;
}
}
public class HashDemo
{
public static void main(String args[])
{
Student s1 = new Student("Justin", 59, 7.6);
Student s2 = new Student("Jessica", 21, 8.0);
Student s3 = new Student("Paul", 20, 5.5);
Student s4 = new Student("Justin", 59, 7.6);
System.out.println("Hash of s1: " + s1.hashCode());
System.out.println("Hash of s2: " + s2.hashCode());
System.out.println("Hash of s3: " + s3.hashCode());
System.out.println("Hash of s4: " + s4.hashCode());
System.out.println("s1 is the same as s2: " + s1.equals(s2));
System.out.println("s1 is the same as s4: " + s1.equals(s4));
}
}
S1:4130 的哈希
s2:1680 的哈希
S3:1600 的哈希
s4:4130 的哈希
s1 与 S2 相同:假
s1 与 S4 相同:真
示例:在实现中使用内置的 hashCode()方法
上面的 hashCode()方法比上一个好。现在让我们在 hashCode()方法的实现中使用内置的 hashCode()方法。
@Override
public int hashCode()
{
return this.name.hashCode() * this.regNo * (int)this.gpa;
}
常见问题
问:为什么在一些 hashCode()方法中使用数字 31?
31 是奇数。如果使用偶数,那么它将导致溢出,因为乘以 2 等于移位。现代虚拟机正在通过移位和减法取代 31 的使用。
问:如果我们知道原始密钥的哈希值,我们能拿回它吗?
不,任何哈希函数都不应该是可逆的。执行哈希运算是为了将大数据转换成一组固定的整数。多个密钥可以获得相同的哈希值,因此不可能获得原始密钥。
问:如果我们覆盖或更改 equals()方法,而不是 hashCode()方法,会发生什么?
如果我们覆盖 equals()方法,但是 hashCode()方法没有改变,那么 equals()方法用来检查两个对象是否相等的参数可能不会被 hashCode()方法使用。这会导致两个相等的对象具有不同的哈希值,这违反了 hashCode 契约的条件。
摘要
哈希是一种重要的技术,在许多不同的集合中使用它来提高查找时间。hashCode()方法用于生成这些数据结构所需的哈希值。hashCode()方法必须满足契约的三个条件。但是,强 hashCode()方法不应该为不同的对象返回相同的值,因为这会导致冲突。
如何在 Java 中把数组转换成集合
原文:https://www.studytonight.com/java-examples/how-to-convert-array-to-set-in-java
在这篇文章中,我们将使用 Java co de 将一个数组转换为 set。数组是基于索引的数据结构,用于存储相似类型的数据,而集合是唯一元素的集合。
这里,我们有几个将数组转换为集合的例子,请始终记住,集合只包含唯一的元素,因此在转换过程中,数组的重复元素不会添加到集合中。
这里,我们使用addAll()
、asList()
和toSet()
方法从数组元素中获取集合。addAll()
方法是一个Collections
类方法,它将数组元素添加到指定的集合(列表、集合等)中
举个例子
让我们举一个将数组转换为集合的例子。这里,我们使用 addAll()方法向集合中添加元素。这很容易从数组中设置。
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args){
String[] fruits = {"Apple", "Orange", "Banana","Orange"};
for (int i = 0; i < fruits.length; i++) {
System.out.println(fruits[i]);
}
Set<String> fruitsSet = new HashSet<>();
Collections.addAll(fruitsSet, fruits);
System.out.println(fruitsSet);
}
}
苹果
橙子
香蕉
橙子
【苹果、橙子、香蕉】
示例:
我们可以使用asList()
方法获取转换数组进行设置。asList()方法返回数组的列表,该列表被构造器进一步转换为集合。见下面的例子。
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args){
String[] fruits = {"Apple", "Orange", "Banana","Orange"};
for (int i = 0; i < fruits.length; i++) {
System.out.println(fruits[i]);
}
Set<String> fruitsSet = new HashSet<>(Arrays.asList(fruits));
System.out.println(fruitsSet);
}
}
苹果
橙子
香蕉
橙子
【苹果、橙子、香蕉】
示例:Java 8
让我们创建另一个例子来从数组元素中获取集合。这里,我们使用 Collectors 类的toSet()
方法,从流元素中返回集合。如果您想使用流来获取集合元素,这个示例非常有用。
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args){
String[] fruits = {"Apple", "Orange", "Banana","Orange"};
for (int i = 0; i < fruits.length; i++) {
System.out.println(fruits[i]);
}
Set<String> fruitsSet = new HashSet<>();
fruitsSet = Arrays.stream(fruits).collect(Collectors.toSet());
System.out.println(fruitsSet);
}
}
苹果
橙子
香蕉
橙子
【苹果、橙子、香蕉】
如何在 Java 中把列表转换成数组
原文:https://www.studytonight.com/java-examples/how-to-convert-list-to-array-in-java
在这篇文章中,我们将使用 Java 代码将 List 转换为 Array。列表是用于存储数据的线性数据结构,而数组是存储相似类型数据的基于索引的数据结构。
为了将列表转换成数组,我们使用了返回对象数组的列表界面的toArray()
方法。
我们使用了几个例子来将列表转换成一个数组,这个数组有老的和新的方法,比如流和方法引用。
举例时间:
在这个例子中,我们正在创建一个水果列表并打印它的元素。之后,我们使用 toArray()方法将列表转换为数组。toArray()方法返回一个对象元素数组。所以,如果你想得到另一种类型的数组,那么传递一个该类型的对象作为参数。
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args){
List<String> fruits = new ArrayList<>();
fruits.add("Mango");
fruits.add("Apple");
fruits.add("Orange");
System.out.println(fruits);
// Conversion List to array
String[] newArray = fruits.toArray(new String[0] );
System.out.println(newArray);
for (int i = 0; i < newArray.length; i++) {
System.out.println(newArray[i]);
}
}
}
【芒果,苹果,橙】
【ljava . lang . string;@3764951d
芒果
苹果
橙
示例:Java 8
如果您使用的是 Java 8 或更高版本,那么您可以使用 stream()方法获取元素流,然后使用方法引用语法从列表中获取String
类型元素的数组。
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args){
List<String> fruits = new ArrayList<>();
fruits.add("Mango");
fruits.add("Apple");
fruits.add("Orange");
System.out.println(fruits);
// Conversion List to array
String[] newArray = fruits.stream().toArray(String[]::new);
System.out.println(newArray);
for (int i = 0; i < newArray.length; i++) {
System.out.println(newArray[i]);
}
}
}
【芒果,苹果,橙】
【ljava . lang . string;@3764951d
芒果
苹果
橙
示例:
如果您使用的是最新的 Java 版本,那么您可以从列表中获取一个数组,而无需使用 stream()方法,并直接使用 toArray()方法。
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args){
List<String> fruits = new ArrayList<>();
fruits.add("Mango");
fruits.add("Apple");
fruits.add("Orange");
System.out.println(fruits);
// Conversion List to array
String[] newArray = fruits.toArray(String[]::new);
System.out.println(newArray);
for (int i = 0; i < newArray.length; i++) {
System.out.println(newArray[i]);
}
}
}
【芒果,苹果,橙】
【ljava . lang . string;@3764951d
芒果
苹果
橙
如何在 Java 中将字符串转换为ArrayList
原文:https://www.studytonight.com/java-examples/how-to-convert-string-to-arraylist-in-java
在这篇文章中,我们将使用 Java 代码将一个字符串转换为ArrayList
。字符串是一个字符序列,在 Java 中是一个类,而ArrayList
是列表接口的实现类。
假设,我们有一个由服务器资源路径组成的 URL 字符串,并由一些单独的符号分隔,我们希望将其获取为ArrayList
。所以,我们需要执行这个转换。
要将字符串转换为ArrayList,
,我们使用asList()
、split()
和add()
方法。asList()
方法属于Arrays
类,从数组中返回一个列表。
split()
方法属于String
类,根据指定的拆分分隔符返回一个数组。
这里,我们有几个例子来说明字符串到ArrayList
的转换过程。请看下面的例子。
举例时间:
让我们举一个从字符串中获取ArrayList
的例子。这里,我们使用 split()方法获取一个字符串数组,然后使用 asList()方法将该数组转换为一个列表。
import java.util.ArrayList;
import java.util.Arrays;
public class Main {
public static void main(String[] args){
String msg = "StudyTonight.com/tutorial/java/string";
System.out.println(msg);
// string to ArrayList
ArrayList<String> list = new ArrayList<>(Arrays.asList(msg.split("/")));
list.forEach(System.out::println);
}
}
StudyTonight.com/tutorial/java/string
StudyTonight.com
教程
Java
弦
例 1
如果我们有一个字符串数组,那么我们不需要split()
方法。我们可以直接将这个数组传入asList()
法得到ArrayList
。请看下面的例子。
import java.util.ArrayList;
import java.util.Arrays;
public class Main {
public static void main(String[] args){
String[] msg = {"StudyTonight.com","tutorial","java","string"};
System.out.println(msg.length);
// string[] to ArrayList
ArrayList<String> list = new ArrayList<>(Arrays.asList(msg));
list.forEach(System.out::println);
}
}
4
StudyTonight.com
教程
Java
弦
例 2
我们再举一个例子来获取 ArrayList,这里我们使用add()
方法通过遍历将字符串数组元素添加到ArrayList
中。这对于初学者来说是最简单的。
import java.util.ArrayList;
public class Main {
public static void main(String[] args){
String[] msg = {"StudyTonight.com","tutorial","java","string"};
System.out.println(msg.length);
// string[] to ArrayList
ArrayList<String> list = new ArrayList<>();
for (String string : msg) {
list.add(string);
}
System.out.println(list);
}
}
4
【study south . com,教程,java,string】
如何在 Java 中将ArrayList
转换为LinkedList
原文:https://www.studytonight.com/java-examples/how-to-convert-arraylist-to-linkedlist-in-java
在这篇文章中,我们将把 Java 中的ArrayList
转换为LinkedList
。ArrayList
和LinkedList
都是类,分别用于实现基于数组的列表和基于LinkedList
的列表。
当ArrayList
将数据存储在类似数组的列表中时,LinkedList
使用LinkedList
数据结构来存储数据。两个类都实现了 Java 集合框架层次中的List
接口。
要转换ArrayList
,有几种方法,这里我们使用的一些方法,比如将 ArraList 作为参数传递给LinkedList
构造器,或者使用add()
方法逐个添加 ArrayList 元素,或者使用 stream API 将 stream 元素获取到 LinkedList。
举例时间:
举个例子把ArrayList
转换成LinkedList
。在这里,我们将ArrayList
元素传递给LinkedList
构造器,并获得一个新的数据结构。
import java.util.ArrayList;
import java.util.LinkedList;
public class Main {
public static void main(String[] args){
ArrayList<String> arrList = new ArrayList<>();
arrList.add("Mango");
arrList.add("Apple");
arrList.add("Orange");
System.out.println(arrList);
// ArrayList to LinkedList
LinkedList<String> linkList = new LinkedList<>(arrList);
System.out.println("Linked List:");
System.out.println(linkList);
}
}
【芒果、苹果、橙子】
LinkedList
:
【芒果、苹果、橙子】
另一个例子:
让我们创建另一个示例来将ArrayList
转换为LinkedList
。这里,我们使用add()
方法向 LinkedList 添加元素。
import java.util.ArrayList;
import java.util.LinkedList;
public class Main {
public static void main(String[] args){
ArrayList<String> arrList = new ArrayList<>();
arrList.add("Mango");
arrList.add("Apple");
arrList.add("Orange");
System.out.println(arrList);
// ArrayList to LinkedList
LinkedList<String> linkList = new LinkedList<>();
for (String arr : arrList) {
linkList.add(arr);
}
System.out.println("Linked List:");
System.out.println(linkList);
}
}
【芒果、苹果、橙子】
LinkedList
:
【芒果、苹果、橙子】
示例:Java 8
如果您使用的是 Java 8 或更高版本,那么您可以利用Java 流 API
将ArrayList
转换为LinkedList
。这里,我们使用 stream 将ArrayList
元素收集到 LinkedList 中。
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args){
ArrayList<String> arrList = new ArrayList<>();
arrList.add("Mango");
arrList.add("Apple");
arrList.add("Orange");
System.out.println(arrList);
// ArrayList to LinkedList
LinkedList<String> linkList = arrList.stream().collect(Collectors.toCollection(LinkedList::new));
System.out.println("Linked List:");
System.out.println(linkList);
}
}
【芒果、苹果、橙子】
LinkedList
:
【芒果、苹果、橙子】
Java ArrayList
到LinkedHashSet
的转换
原文:https://www.studytonight.com/java-examples/java-arraylist-to-linkedhashset-conversion
在这篇文章中,我们将把ArrayList
转换为链接HashSet
。LinkedHashSet 是一个使用 linkedlist 数据结构在 Java 中实现 Set 的类。
当我们想要将类似数组的列表转换为唯一的数据集合时,这是很有帮助的。LinkedHashSet 用于收集唯一数据。
为了将ArrayList
转换为 LinkedHashSet,我们使用了各种方法,如流 API 或 add()方法或 LinkedHashSet 构造器。见下面的例子。
举例时间:
在本例中,我们使用流 API 将ArrayList
元素收集到 LinkedHashSet 中,以获得唯一的元素。请看下面的例子。
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args){
ArrayList<String> arrList = new ArrayList<>();
arrList.add("Mango");
arrList.add("Apple");
arrList.add("Orange");
arrList.add("Apple");
System.out.println(arrList);
// ArrayList to LinkedHashSet
LinkedHashSet<String> linkList = arrList.stream().collect(Collectors.toCollection(LinkedHashSet::new));
System.out.println("Linked HashSet:");
System.out.println(linkList);
}
}
【芒果、苹果、橙子、苹果】
链接 HashSet:
【芒果、苹果、橙子】
示例:
如果要将元素一个一个地添加到 LinkedHashSet 中,那么可以使用 add()方法,得到一个唯一元素的集合。请看下面的例子。
import java.util.ArrayList;
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args){
ArrayList<String> arrList = new ArrayList<>();
arrList.add("Mango");
arrList.add("Apple");
arrList.add("Orange");
arrList.add("Apple");
System.out.println(arrList);
// ArrayList to LinkedHashSet
LinkedHashSet<String> linkSet = new LinkedHashSet<String>();
for (String arr : arrList) {
linkSet.add(arr);
}
System.out.println("Linked HashSet:");
System.out.println(linkSet);
}
}
【芒果、苹果、橙子、苹果】
链接 HashSet:
【芒果、苹果、橙子】
示例:
这是另一种从ArrayList
中获取 LinkedHashSet 的方法。这里,我们将ArrayList
作为参数传递给 LinkedHashSet 的构造器。
import java.util.ArrayList;
import java.util.LinkedHashSet;
public class Main {
public static void main(String[] args){
ArrayList<String> arrList = new ArrayList<>();
arrList.add("Mango");
arrList.add("Apple");
arrList.add("Orange");
arrList.add("Apple");
System.out.println(arrList);
// ArrayList to LinkedHashSet
LinkedHashSet<String> linkSet = new LinkedHashSet<String>(arrList);
System.out.println("Linked HashSet:");
System.out.println(linkSet);
}
}
【芒果、苹果、橙子、苹果】
链接 HashSet:
【芒果、苹果、橙子】
Java ArrayList
到HashSet
的转换
原文:https://www.studytonight.com/java-examples/java-arraylist-to-hashset-conversion
在这篇文章中,我们将把 Java 中的ArrayList
转换为 HashSet 。ArrayList
是List
接口的实现类,而HashSet
是Set
接口的实现类。
如果我们想得到一个独特元素的集合,那么我们可以使用 HashSet。ArrayList
到HashSet
的转换将删除ArrayList
中所有重复的元素。
虽然有几种方法可以将 ArrayList 转换成 HashSet,但是这里我们使用了一些常见的方法,比如使用 add()方法或者 HashSet 构造器或者最新 java 版本的 流 API 。
举例时间:
让我们举个例子从ArrayList
中获取 HashSet。在这里,我们将ArrayList
传递给 HashSet 构造器,以获取唯一元素的集合。请看下面的例子。
import java.util.ArrayList;
import java.util.HashSet;
public class Main {
public static void main(String[] args){
ArrayList<String> arrList = new ArrayList<>();
arrList.add("Mango");
arrList.add("Apple");
arrList.add("Orange");
arrList.add("Apple");
System.out.println(arrList);
// ArrayList to HashSet
HashSet<String> hashSet = new HashSet<String>(arrList);
System.out.println("HashSet:");
System.out.println(hashSet);
}
}
【芒果,苹果,橘子,苹果】
HashSet
:
【苹果,芒果,橘子】
示例:
让我们创建另一个示例来将ArrayList
转换为 HashSet。这里,我们使用 add()方法将每个元素逐个添加到 HashSet 中,并获得一个唯一的元素集合。
public class Main {
public static void main(String[] args){
ArrayList<String> arrList = new ArrayList<>();
arrList.add("Mango");
arrList.add("Apple");
arrList.add("Orange");
arrList.add("Apple");
System.out.println(arrList);
// ArrayList to HashSet
HashSet<String> hashSet = new HashSet<String>();
for (String arr : arrList) {
hashSet.add(arr);
}
System.out.println("HashSet:");
System.out.println(hashSet);
}
}
【芒果,苹果,橘子,苹果】
HashSet
:
【苹果,芒果,橘子】
示例:Java 8
如果您使用的是 Java 8 或更高版本,那么您可以利用 流 API 的优势,使我们的转换代码更加简洁和紧凑。这里,我们使用 stream 将ArrayList
元素收集为 HashSet。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args){
ArrayList<String> arrList = new ArrayList<>();
arrList.add("Mango");
arrList.add("Apple");
arrList.add("Orange");
arrList.add("Apple");
System.out.println(arrList);
// ArrayList to HashSet
HashSet<String> hashSet = arrList.stream().collect(Collectors.toCollection(HashSet::new));
System.out.println("HashSet:");
System.out.println(hashSet);
}
}
【芒果,苹果,橘子,苹果】
HashSet
:
【苹果,芒果,橘子】
如何在 Java 中排序ArrayList
原文:https://www.studytonight.com/java-examples/how-to-sort-arraylist-in-java
在这篇文章中,我们将对 Java 中的一个ArrayList
进行排序。ArrayList
是 List 接口的一个实现,用于存储数据的类。
排序是我们在日常编程中使用的数据基本操作之一。
对ArrayList
进行排序有多种方式,如使用List
的sort()
方法或Collections
类的sort()
方法或流 API 的sorted()
方法。
我们可以根据需要使用这些排序技术中的任何一种,比如如果我们使用的是 stream,那么 sorted()方法将有助于获得排序的 ArrayList。
举例时间:
让我们创建一个对ArrayList
进行排序的示例。这里我们使用的是sort()
方法,它需要Comparator
参数并对指定的列表进行排序。
import java.util.ArrayList;
import java.util.Comparator;
public class Main {
public static void main(String[] args){
ArrayList<Integer> arrList = new ArrayList<>();
arrList.add(1030);
arrList.add(1020);
arrList.add(1010);
arrList.add(1040);
System.out.println(arrList);
// Sorting ArrayList
arrList.sort(Comparator.comparing( Integer::new ));
System.out.println("After Sorting:");
System.out.println(arrList);
}
}
【1030、1020、1010、1040】
排序后:
【1010、1020、1030、1040】
示例:
让我们创建另一个例子来排序ArrayList
。这里,我们使用 Collections 类的 sort()方法,该方法接受一个参数并对列表进行排序。
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args){
ArrayList<Integer> arrList = new ArrayList<>();
arrList.add(1030);
arrList.add(1020);
arrList.add(1010);
arrList.add(1040);
System.out.println(arrList);
// Sorting ArrayList
Collections.sort(arrList);
System.out.println("After Sorting:");
System.out.println(arrList);
}
}
【1030、1020、1010、1040】
排序后:
【1010、1020、1030、1040】
示例:Java 8
如果您正在使用 Java 8 或更高版本,那么您可以利用流 API 对ArrayList
进行排序。这里,我们使用流的 sorted()方法来帮助对流元素进行排序。
import java.util.ArrayList;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args){
ArrayList<Integer> arrList = new ArrayList<>();
arrList.add(1030);
arrList.add(1020);
arrList.add(1010);
arrList.add(1040);
System.out.println(arrList);
// Sorting ArrayList
arrList = (ArrayList<Integer>)arrList.stream().sorted().collect(Collectors.toList());
System.out.println("After Sorting:");
System.out.println(arrList);
}
}
【1030、1020、1010、1040】
排序后:
【1010、1020、1030、1040】
如何在 Java 中连接两个ArrayList
原文:https://www.studytonight.com/java-examples/how-to-join-two-arraylist-in-java
在这篇文章中,我们将在 Java 中加入两个ArrayList
。ArrayList 是集合框架中 List 接口的实现类,用于存储数据。
连接两个ArrayList
实际上是将两个ArrayList
元素组合成一个ArrayList
的过程。当我们有多个数据流并希望将它们收集到一个流中时,这很有帮助。
为了加入ArrayList
,我们使用了列表的 addAll()方法和流 API 的 flatMap()方法。
addAll()方法 add 用于将一个ArrayList
的元素添加到另一个ArrayList
中,并接受一个参数。让我们看看例子。
举例时间:
让我们创建一个连接两个ArrayList
的例子。这里我们使用addAll()
方法,并将 arrList2 作为一个参数传递给,看到我们将所有元素放入一个 ArrayList 中。
import java.util.ArrayList;
import java.util.Arrays;
public class Main {
public static void main(String[] args){
ArrayList<Integer> arrList1 = new ArrayList<>();
arrList1.add(1030);
arrList1.add(1020);
arrList1.add(1010);
arrList1.add(1040);
System.out.println(arrList1);
// Join two ArrayList
ArrayList<Integer> arrList2 = new ArrayList<>(Arrays.asList(1050,1060,1070));
System.out.println(arrList2);
arrList1.addAll(arrList2);
System.out.println("After Joining:");
System.out.println(arrList1);
}
}
【1030、1020、1010、1040】
【1050、1060、1070】
加入后:
【1030、1020、1010、1040、1050、1060、1070】
示例:
您也可以使用 Java 流来组合两个ArrayList
元素。这里,我们使用流的 flatMap()方法,将所有元素收集到一个流中并返回一个列表。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args){
ArrayList<Integer> arrList1 = new ArrayList<>();
arrList1.add(1030);
arrList1.add(1020);
arrList1.add(1010);
arrList1.add(1040);
System.out.println(arrList1);
// Join two ArrayList
ArrayList<Integer> arrList2 = new ArrayList<>(Arrays.asList(1050,1060,1070));
System.out.println(arrList2);
List<Integer> arrList3 = Stream.of(arrList1, arrList2)
.flatMap(x -> x.stream())
.collect(Collectors.toList());
System.out.println("After Joining:");
System.out.println(arrList3);
}
}
【1030、1020、1010、1040】
【1050、1060、1070】
加入后:
【1030、1020、1010、1040、1050、1060、1070】
示例:连接唯一元素
如果您只想从两个不同的ArrayList
中收集唯一的元素,那么您可以将 distinct()方法与 flatMap()一起使用,该方法返回唯一元素的列表。请看下面的例子。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args){
ArrayList<Integer> arrList1 = new ArrayList<>();
arrList1.add(1030);
arrList1.add(1020);
arrList1.add(1010);
arrList1.add(1040);
System.out.println(arrList1);
// Join two ArrayList
ArrayList<Integer> arrList2 = new ArrayList<>(Arrays.asList(1050,1030,1070));
System.out.println(arrList2);
List<Integer> arrList3 = Stream.of(arrList1, arrList2)
.flatMap(Collection::stream)
.distinct()
.collect(Collectors.toList());
System.out.println("After Joining:");
System.out.println(arrList3);
}
}
【1030、1020、1010、1040】
【1050、1030、1070】
加入后:
【1030、1020、1010、1040、1050、1070】
如何对 Java 中的 HashSet 元素进行排序
原文:https://www.studytonight.com/java-examples/how-to-sort-hashset-elements-in-java
在这篇文章中,我们将对 Java 中的 HashSet 元素进行排序。HashSet 是 Java 中 Set 接口的一个实现类,用于存储数据,但不维护任何顺序。
要排序HashSet
,有几种方法,如将HashSet
转换为TreeSet
合或集合类的sort()
方法,或使用流的sorted()
方法。
由于 HashSet 不保证插入顺序,也不按照排序顺序存储元素,所以 Java 提供了 TreeSet 来存储排序后的数据。
举例时间:
让我们创建一个例子来排序 HashSet 元素。在这里,我们将 HashSet 元素转换为以排序顺序存储元素的 TreeSet。
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
public class Main {
public static void main(String[] args){
Set<Integer> set = new HashSet<>();
set.add(14);
set.add(20);
set.add(50);
set.add(10);
System.out.println(set);
// Sorting
set = new TreeSet<>(set);
System.out.println(set);
}
}
【50,20,10,14】
【10,14,20,50】
例 1
让我们创建另一个对 HashSet 元素进行排序的示例。这里,我们使用 Collections 类的 sort()方法,该方法返回一个已排序元素的列表。当您想要获得排序的元素时,无论是集合还是列表,这个例子都很有用。
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Main {
public static void main(String[] args){
Set<Integer> set = new HashSet<>();
set.add(14);
set.add(20);
set.add(50);
set.add(10);
System.out.println(set);
// Sorting
List<Integer> list = new ArrayList<>(set);
Collections.sort(list);
System.out.println(list);
}
}
【50,20,10,14】
【10,14,20,50】
例 2
如果您使用的是 Java 8 或更高版本的 Java,那么您可以使用 流 API 及其 sorted()方法对流元素进行排序,toList()方法返回这些元素的列表。请看下面的例子。
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args){
Set<Integer> set = new HashSet<>();
set.add(14);
set.add(20);
set.add(50);
set.add(10);
System.out.println(set);
// Sorting
List<Integer> list = set.stream()
.sorted()
.collect(Collectors.toList());
System.out.println(list);
}
}
【50,20,10,14】
【10,14,20,50】
如何按值对 Java 映射进行排序
原文:https://www.studytonight.com/java-examples/how-to-sort-a-java-map-by-value
在本文中,我们将学习对 Java 映射的元素进行排序。Java 中的 Map 默认情况下是未排序的,以键值格式存储数据。非常需要根据价值对它们进行排序,以便根据价值做出决策。
示例:对映射排序
这里,我们有一个学生映射的例子,他们的名字和身高以厘米为单位。假设我们想根据学生的名字对他们进行排序(基于键进行编程),为此我们将使用Collections.sort()
方法,同样的方法也可以用于根据他们的身高对学生进行排序(基于值进行编程),但唯一需要的更改是Comparator
函数。
Collections.sort()
总是以一个List<T>
作为参数。因此,我们将从Map.entrySet()
这个方法创建一个列表,它将返回映射的所有键值对。当根据多个参数对特定集合进行排序时,Comparator
功能开始发挥作用。在Comparator
功能内部,return student1.getKey().compareTo(student2.getKey());
决定排序方式。在这种情况下,它将根据关键字进行排序。
import java.util.*;
public class StudyTonight
{
public static void main(String args[])
{
Map<String,Integer> students = new HashMap<>();
students.put("Student 1", 159);
students.put("Student 2", 147);
students.put("Student 3", 183);
students.put("Student 4", 167);
students.put("Student 5", 173);
List<Map.Entry<String, Integer>> student_list = new ArrayList<>(students.entrySet());
System.out.println("\nBefore Sorting\n");
for(Map.Entry<String, Integer> student: student_list)
{
System.out.println(student.getKey()+" "+student.getValue());
}
Collections.sort(student_list, new Comparator<Map.Entry<String, Integer>>()
{
@Override
public int compare(Map.Entry<String, Integer> student1, Map.Entry<String, Integer> student2){
return student1.getKey().compareTo(student2.getKey());
}
});
System.out.println("\nAfter Sorting\n");
for(Map.Entry<String, Integer> student: student_list)
{
System.out.println(student.getKey()+" "+student.getValue());
}
}
}
排序前
学生 2 147
学生 1 159
学生 4 167
学生 3 183
学生 5 173
排序后
学生 1 159
学生 2 147
学生 3 183
学生 4 167
学生 5 173
基于值对映射进行排序的示例
要根据值对映射进行排序,我们只需更改Comparator
功能student1.getValue().compareTo(student2.getValue());
,其余代码将保持不变。
这里Comparator
函数处理的是 Map 的值,因此我们将根据值得到结果。
import java.util.*;
public class StudyTonight
{
public static void main(String args[])
{
Map<String,Integer> students = new HashMap<>();
students.put("Student 1", 159);
students.put("Student 2", 147);
students.put("Student 3", 183);
students.put("Student 4", 167);
students.put("Student 5", 173);
List<Map.Entry<String, Integer>> student_list = new ArrayList<>(students.entrySet());
System.out.println("\nBefore Sorting\n");
for(Map.Entry<String, Integer> student: student_list)
{
System.out.println(student.getKey()+" "+student.getValue());
}
Collections.sort(student_list, new Comparator<Map.Entry<String, Integer>>()
{
@Override
public int compare(Map.Entry<String, Integer> student1, Map.Entry<String, Integer> student2){
return student1.getValue().compareTo(student2.getValue());
}
});
System.out.println("\nAfter Sorting\n");
for(Map.Entry<String, Integer> student: student_list)
{
System.out.println(student.getKey()+" "+student.getValue());
}
}
}
排序前
学生 2 147
学生 1 159
学生 4 167
学生 3 183
学生 5 173
排序后
学生 2 147
学生 1 159
学生 4 167
学生 5 173
学生 3 183
使用λ和基于值对映射进行排序的示例
这个方法也与我们在第一个例子中所做的非常相似。但是,唯一不同的是Comparator
函数,它被称为匿名实现(student1, student2)->student1.getKey().compareTo(student2.getKey()));
import java.util.*;
public class StudyTonight
{
public static void main(String args[])
{
Map<String,Integer> students = new HashMap<>();
students.put("Student 1", 159);
students.put("Student 2", 147);
students.put("Student 3", 183);
students.put("Student 4", 167);
students.put("Student 5", 173);
List<Map.Entry<String, Integer>> student_list = new ArrayList<>(students.entrySet());
System.out.println("\nBefore Sorting\n");
for(Map.Entry<String, Integer> student: student_list)
{
System.out.println(student.getKey()+" "+student.getValue());
}
Collections.sort(student_list, (student1, student2)->student1.getKey().compareTo(student2.getKey()));
System.out.println("\nAfter Sorting\n");
for(Map.Entry<String, Integer> student: student_list)
{
System.out.println(student.getKey()+" "+student.getValue());
}
}
}
排序前
学生 2 147
学生 1 159
学生 4 167
学生 3 183
学生 5 173
排序后
学生 1 159
学生 2 147
学生 3 183
学生 4 167
学生 5 173
结论:
我们可以借助Comparator
函数,使用Collection.sort()
方法对 Java 中的 Map 进行排序。Comparator
功能可以匿名方式实现,效率更高。
如何在 Java 映射中找到最大值
原文:https://www.studytonight.com/java-examples/how-to-find-maximum-value-in-java-map
在本文中,我们将学习对 Java 映射的元素进行排序。映射以键值对的格式存储数据,除此之外,它还存储在随机的位置,这就是为什么在 Java 的映射中很难找到最大值的原因。
在 Java 映射中寻找最大价值的挑战
- Java 中的 Map 将值存储在随机位置。
- 因为它以键值格式存储数据,所以有必要决定应该考虑哪个因素进行比较。
让我们通过一个 Java 中使用Map
的程序来理解。在下面给出的程序中,我们创建了一个Map
,它将以键值格式存储每个相应课程的价格。
import java.util.*;
public class StudyTonight
{
public static void main(String args[])
{
Map<String,Integer> coursePrice = new HashMap<>();
coursePrice.put("Java",5000);
coursePrice.put("Python",3000);
coursePrice.put("CPP",4000);
coursePrice.put("Android",8000);
System.out.println(coursePrice);
}
}
不要忘记导入java.util.*;
包,否则编译器会给出错误。
{Java=5000,CPP=4000,Python=3000,Android=8000}
现在,很明显会想哪道菜最便宜?哪门课贵?
在编程世界中,我们通过简单地找到最大值和最小值来解决这些情况。在讨论实际解决方案之前,让我们讨论迭代解决方案。
求映射最大值的迭代解法
在这个程序中,我们创建了一个映射类型的空条目,然后迭代映射的所有值。每当我们得到一个更大的值或空值时,我们就把它赋给 Entry,并在最后简单地打印 Entry 的值。
import java.util.*;
public class StudyTonight
{
public static void main(String args[])
{
Map<String,Integer> coursePrices = new HashMap<>();
Map.Entry<String,Integer> maxPrice = null;
coursePrices.put("Java", 5000);
coursePrices.put("Python", 3000);
coursePrices.put("CPP", 4000);
coursePrices.put("Android", 8000);
for(Map.Entry<String,Integer> price:coursePrices.entrySet())
{
if (maxPrice == null || price.getValue().compareTo(maxPrice.getValue()) > 0)
{
maxPrice = price;
}
}
System.out.println("Maximum price is: "+maxPrice.getValue());
}
}
最高限价为:8000
在映射中查找最大值的示例
在这里,我们简单地使用Map.values()
传递了 Map 的所有值,其他的工作由 Java 中的Collections
类自动完成。
本示例将打印映射上显示的最高价格。
import java.util.*;
public class StudyTonight
{
public static void main(String args[])
{
Map<String,Integer> coursePrice = new HashMap<>();
coursePrice.put("Java",5000);
coursePrice.put("Python",3000);
coursePrice.put("CPP",4000);
coursePrice.put("Android",8000);
System.out.println("maximum price is : "+ Collections.max(coursePrice.values()));
}
}
最高限价为:8000
如果我们想找到最大映射键而不是值呢?
在这种情况下,我们只需要传递方法 Map.keySet()而不是 Map.values(),下面给出了实现这种情况的代码,其中所有课程价格都是键,课程名称都是值。所以,我们在 Collection.max()方法中传递了 Map.keySet()。
import java.util.*;
public class StudyTonight
{
public static void main(String args[])
{
Map<Integer,String> coursePrice = new HashMap<>();
coursePrice.put(5000,"Java");
coursePrice.put(3000,"Python");
coursePrice.put(4000,"CPP");
coursePrice.put(8000,"Android");
System.out.println("maximum price is : "+ Collections.max(coursePrice.keySet()));
}
}
最高限价为:8000
结论:
在本文中,我们学习了使用Collections
类或传统的迭代比较方法在 Java Map 中查找最大值。Map 为访问时间提供 O(1),但为从中找到最大元素提供 O(n)。
在 Java 中从数组创建ArrayList
原文:https://www.studytonight.com/java-examples/create-an-arraylist-from-an-array-in-java
在本教程中,我们将学习如何从 Java 中的数组创建ArrayList
。ArrayList 属于java.util
包。ArrayList
的大小是可变的,这一特性使它成为比数组更好的选择。主要有三种方法:
- 通过将数组的每个元素显式添加到
ArrayList
中。 - 通过使用
Arrays.asList()
方法。 - 通过使用
Collections.addAll()
方法
例 1:
通过将每个元素添加到数组的ArrayList
中,从数组创建ArrayList
。
import java.util.*;
public class StudyTonight
{
public static void main(String[] args)
{
ArrayList<String> courses= new ArrayList<String>();
String array[] = {"Java","Python","C","C++"};
for(int i =0;i<array.length;i++)
{
courses.add(array[i]);
}
for(String course: courses)
{
System.out.println(course);
}
}
}
Java
Python
C
C++
示例:使用Arrays.asList()
方法从数组创建ArrayList
。
在本例中,Arrays
类的asList()
方法会将给定的数组转换为ArrayList
。
import java.util.*;
public class StudyTonight
{
public static void main(String[] args)
{
String courses[]={"Java", "Python", "Android", "Web"};
ArrayList<String> courseList= new ArrayList<String>(Arrays.asList(courses));
for (String course: courseList)
{
System.out.println(course);
}
}
}
Java
python
Android
web
示例:使用Collections.addAll()
方法从数组创建ArrayList
。
在本例中,Collections
类的addAll()
方法将数组转换为ArrayList
。我们将两个参数传递给 addAll 方法,即 ArrayList 和 array。
import java.util.*;
public class StudyTonight
{
public static void main(String[] args)
{
String array[]={"C", "C++", "Java", "Python"};
ArrayList<String> courses= new ArrayList<String>();
Collections.addAll(courses, array);
for (String course: courses)
{
System.out.println(course);
}
}
}
C
C++
Java
Python
结论:
ArrayList
的大小是可变的,这就是为什么将数组转换为ArrayList
很有用。我们可以通过三种方式来实现:通过将数组的每个元素显式添加到 ArrayList 中,通过使用Arrays.asList()
方法,以及通过使用Collections.addAll()
方法
Java 中整数列表到整型数组的转换
原文:https://www.studytonight.com/java-examples/convert-integer-list-to-int-array-in-java
在本文中,我们将学习如何在 Java 中将整数列表转换为 int 数组。在 Java 中,有两种方法可以将整数列表转换为数组
- 使用
stream.mapToInt()
方法 - 使用
ArrayUtils.toPrimitive()
方法
示例:使用 stream.mapToInt()方法将整数列表转换为数组
在这个例子中,我们创建了一个整数列表。为了将这个ArrayList
改为 Array,我们在列表中调用了stream().mapToInt().toAttay()
方法,其结果将被分配给 array arr。
import java.util.*;
public class StudyTonight
{
public static void main(String[] args)
{
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
int[] arr = list.stream().mapToInt(i->i).toArray();
for (int val : arr) {
System.out.println(val);
}
}
}
1
2
3
4
5
示例:使用ArrayUtils.toPrimitive()
方法将整数列表转换为整型数组
对于这个例子,我们需要一个外部包org.apache.commons.lang3.ArrayUtils.
在一些 IDE 中,你已经可以找到或者需要通过下载 JARs 文件导入。
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.ArrayUtils;
public class StudyTonight
{
public static void main(String[] args)
{
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
int[] arr = ArrayUtils.toPrimitive(list.toArray(new Integer[list.size()]));
for (int val : arr) {
System.out.println("int primitive: "+val);
}
}
}
1
2
3
4
5
结论:
我们学习了如何在 java 中将整数列表转换成 int 数组。Java 中 stram API 的ArrayUtils.toPrimitive()
和stream().mapToInt()
有两种方法可以做到。
Java 杂项
在 Java 中将输入流转换为字符串
原文:https://www.studytonight.com/java-examples/convert-inputstream-to-string-in-java
InputStream
类是 java.io 包的一部分,代表一个有序的数据序列。InputStreams
用于有序地从文件中读取数据。在本教程中,我们将学习将输入流转换为字符串的不同方法。
使用InputStreamReader
InputStreamReader
类提供了一种方便的read()
方法,将输入流中的数据读入字符数组。然后,我们可以将这个字符数组转换成字符串。
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Demo
{
public static String inputStreamToString(InputStream i) throws IOException
{
InputStreamReader isr = new InputStreamReader(i);
char[] charArr = new char[256];
isr.read(charArr);
return new String(charArr);
}
public static void main(String[] args)
{
try
{
InputStream i = new ByteArrayInputStream("hello world".getBytes());//Creating the input stream
String strFromInputStream = inputStreamToString(i);
System.out.print("String from the Input Stream is: " + strFromInputStream);
}
catch(Exception e)
{
System.out.print(e);
}
}
}
来自输入流的字符串是:hello world
在字符串生成器中使用InputStreamReader
和BufferedReader
类
我们可以用BufferedReader
来包裹InputStreamReader
。它提高了我们项目的整体效率。我们将使用BufferedReader
的readLine()
方法,并将这些行存储在一个 StringBuilder
对象中。最后,我们可以使用StringBuilder
上的toString()
方法来获取字符串。
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Demo
{
public static String inputStreamToString(InputStream i) throws IOException
{
StringBuilder builder = new StringBuilder();
InputStreamReader isr = new InputStreamReader(i);
BufferedReader br = new BufferedReader(isr);//Wrapping InputStreamReader with BufferedReader
String s;
while((s = br.readLine()) != null)
builder.append(s);
return builder.toString();
}
public static void main(String[] args)
{
try
{
InputStream i = new ByteArrayInputStream("hello world".getBytes());//Creating the input stream
String strFromInputStream = inputStreamToString(i);
System.out.print("String from the Input Stream is: " + strFromInputStream);
}
catch(Exception e)
{
System.out.print(e);
}
}
}
来自输入流的字符串是:hello world
在没有字符串生成器的情况下使用InputStreamReader
和BufferedReader
类
我们可以使用BufferedReader
的lines()
方法简化上一节写的代码。我们不需要使用任何循环或将字符串存储在 StringBuilder 中。
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
public class Demo
{
public static String inputStreamToString(InputStream i)
{
InputStreamReader isr = new InputStreamReader(i);
BufferedReader br = new BufferedReader(isr);
String s = br.lines().collect(Collectors.joining("\n"));
return s;
}
public static void main(String[] args)
{
InputStream i = new ByteArrayInputStream("hello world".getBytes());//Creating the input stream
String strFromInputStream = inputStreamToString(i);
System.out.print("String from the Input Stream is: " + strFromInputStream);
}
}
来自输入流的字符串是:hello world
使用输入流的 readAllBytes()方法
InputStream
班在Java 9
介绍了readAllBytes()
法。我们可以使用这个方法在一行代码中将输入流转换成字符串。但是,不建议使用这种方法来读取具有大量数据的流。
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
public class Demo
{
public static String inputStreamToString(InputStream i) throws IOException
{
return new String(i.readAllBytes());
}
public static void main(String[] args)
{
try
{
InputStream i = new ByteArrayInputStream("hello world".getBytes());//Creating the input stream
String strFromInputStream = inputStreamToString(i);
System.out.print("String from the Input Stream is: " + strFromInputStream);
}
catch(Exception e)
{
System.out.print(e);
}
}
}
来自输入流的字符串是:hello world
使用扫描仪类
Scanner
是一个众所周知的用于读取和解析数据的类。我们可以使用这个类将输入流转换成字符串。我们将使用hasNext()
方法检查数据是否存在,使用nextLine()
方法将数据流中的数据读入StringBuilder
。
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
public class Demo
{
public static String inputStreamToString(InputStream i) throws IOException
{
Scanner scanner = new Scanner(i);
StringBuilder builder = new StringBuilder();
while(scanner.hasNext())
builder.append(scanner.nextLine());
return builder.toString();
}
public static void main(String[] args)
{
try
{
InputStream i = new ByteArrayInputStream("hello world".getBytes());//Creating the input stream
String strFromInputStream = inputStreamToString(i);
System.out.print("String from the Input Stream is: " + strFromInputStream);
}
catch(Exception e)
{
System.out.print(e);
}
}
}
来自输入流的字符串是:hello world
使用字节数组输出流
我们将使用read()
方法从InputStream
读取数据,并将其写入字节数组。此 read()方法返回字节数组中写入的字节数(如果没有写入数据,则返回-1)。然后,我们将使用这个字节数组将数据写入ByteArrayOutputStream
。最后,我们将使用 toString()方法来获取字符串表示形式。
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class Demo
{
public static String inputStreamToString(InputStream i) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[128];
int length;
while((length = i.read(buffer)) != -1)
baos.write(buffer, 0, length);
return baos.toString();
}
public static void main(String[] args)
{
try
{
InputStream i = new ByteArrayInputStream("hello world".getBytes());//Creating the input stream
String strFromInputStream = inputStreamToString(i);
System.out.print("String from the Input Stream is: " + strFromInputStream);
}
catch(Exception e)
{
System.out.print(e);
}
}
}
来自输入流的字符串是:hello world
使用 java.nio Package
我们可以使用java.nio
创建一个新的临时文件,并将输入流中的数据复制到这个文件中。然后,我们可以将这个临时文件的内容读入一个字符串。请注意,当程序结束时,临时文件将被自动删除。
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.*;
public class Demo
{
public static String inputStreamToString(InputStream i) throws IOException
{
Path file = Files.createTempFile(null, null);
Files.copy(i, file, StandardCopyOption.REPLACE_EXISTING);
return new String(Files.readAllBytes(file));
}
public static void main(String[] args)
{
try
{
InputStream i = new ByteArrayInputStream("hello world".getBytes());//Creating the input stream
String strFromInputStream = inputStreamToString(i);
System.out.print("String from the Input Stream is: " + strFromInputStream);
}
catch(Exception e)
{
System.out.print(e);
}
}
}
来自输入流的字符串是:hello world
使用谷歌番石榴图书馆
我们可以使用番石榴库的CharStreams
类将输入流转换成字符串。我们将使用这个类的 toString()方法来实现这一点。它将获取一个可读的对象(像 InputStreamReader),并将数据从其中读入一个字符串。
package snippet;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import com.google.common.io.CharStreams;
public class Demo
{
public static String inputStreamToString(InputStream i) throws IOException
{
try(InputStreamReader isr = new InputStreamReader(i))
{
return CharStreams.toString(isr);
}
}
public static void main(String[] args)
{
try
{
InputStream i = new ByteArrayInputStream("hello world".getBytes());//Creating the input stream
String strFromInputStream = inputStreamToString(i);
System.out.print("String from the Input Stream is: " + strFromInputStream);
}
catch(Exception e)
{
System.out.print(e);
}
}
}
来自输入流的字符串是:hello world
使用 Apache Commons IO
org.apache.commons.io
包的IOUtils
类还包含一个 toString()方法。我们可以直接把 InputStream 对象传递给这个方法,它会把其中的数据读入一个字符串。我们还需要指定一个字符集。
package snippet;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;
public class Demo
{
public static void main(String[] args)
{
try
{
InputStream i = new ByteArrayInputStream("hello world".getBytes());//Creating the input stream
String strFromInputStream = IOUtils.toString(i, StandardCharsets.UTF_8.name());
System.out.print("String from the Input Stream is: " + strFromInputStream);
}
catch(Exception e)
{
System.out.print(e);
}
}
}
来自输入流的字符串是:hello world
我们还可以使用 java.io 包的 StringWriter 类,并将 InputStream 的内容复制到 StringWriter 中。我们将使用 IOUtils 类的 copy()方法。
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;
public class Demo
{
public static void main(String[] args)
{
try
{
InputStream i = new ByteArrayInputStream("hello world".getBytes());//Creating the input stream
StringWriter sw = new StringWriter();
IOUtils.copy(i, sw, StandardCharsets.UTF_8.name());
String strFromInputStream = sw.toString();
System.out.print("String from the Input Stream is: " + strFromInputStream);
}
catch(Exception e)
{
System.out.print(e);
}
}
}
来自输入流的字符串是:hello world
摘要
在本教程中,我们学习了将输入流转换为字符串的不同方法。ByteArrayOutputStream
高效地执行转换,是推荐的方法。我们可以使用 InputStream 类本身的readAllBytes()
方法,但不建议大量使用。
InputStreamReader
也不被看好,因为它相当慢,一次只能读取一个字符。我们也可以使用外部库,如番石榴或阿帕奇通用 IO。我们还需要正确处理异常并关闭 InputStream 以避免资源泄漏。
JVM 参数
原文:https://www.studytonight.com/java-examples/jvm-parameters
JVM 参数用于配置 Java 虚拟机(JVM)。JVM 的性能取决于它的配置是否满足 Java 应用的需求。
在本教程中,我们将学习如何设置一些 JVM 参数。
堆内存
借助 Xmx 和 Xms 参数,我们可以设置应用所需的最小和最大堆大小。设置正确的堆大小会影响我们应用的性能。Xmx 用于调整最大堆大小,Xms 用于更改最小堆大小。
-Xms<heap size>[unit]
-Xmx<heap size>[unit]
单位表示内存单位,如“g”代表 GB,“m”代表 MB,依此类推。
堆内的年轻一代内存区域用于存储新创建的对象。我们也可以改变年轻一代的初始和最大规模。 XX:NewSize 调整初始尺寸, XX:MaxNewSize 设置最大尺寸。
-XX:NewSize=<young size>[unit]
-XX:MaxNewSize=<young size>[unit]
碎片帐集
为我们的应用选择合适的垃圾收集器对其性能也至关重要。JVM 提供了四种不同的垃圾收集实现。
串行垃圾收集器
–XX:+UseSerialGC
并行垃圾收集器
-XX:+UseParallelGC
垃圾收集器
-XX:+UseParNewGC
G1 垃圾收集器
XX:+UseG1GC
Java 垃圾收集日志记录
GC 日志记录用于跟踪应用的运行状况和性能。我们可以使用以下参数记录垃圾收集活动。
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=<number of log files>
-XX:GCLogFileSize=<file size><unit>
-Xloggc:[path to gc.log file]
- 使用日志文件旋转启用日志旋转。它通常用于处理长时间运行的应用的大型日志文件。
- number of clogfiles调整循环日志时要使用的日志文件的最大数量。它的默认值是 1。
- GCLogFileSize 定义日志文件的最大大小。
- loggc 表示创建的日志文件的位置。
32/64 位
如果有 32 位和 64 位软件包,Java 虚拟机会自动选择 32 位环境。我们可以通过使用以下参数从 32 位更改为 64 位。
-d<bit>
被遗忘
当 JVM 无法为新对象分配内存,并且垃圾收集器无法清除任何空间时,就会出现内存不足错误。我们可以使用一些 JVM 参数来捕获文件中的堆转储。
- heapdumponetomemoryerror通知 JVM 捕获文件中的堆转储。
- HeapDumpPath 表示我们要捕获堆转储的文件的路径。
- OnTofMemoryerror设置遇到此错误时要执行的操作。
- UseGCOverheadLimit 对 JVM 可以花费在垃圾收集上的时间进行限制。
JVM 的其他常用参数
- -服务器启用 Java HotSpot 服务器虚拟机。请注意,对于 64 位环境,默认情况下使用此选项。
- -XX:+usestringduplication通过维护单个全局字符数组来优化存储重复字符串所使用的内存。
- -XX:+usewpsynchronization使用轻量进程同步(LWP)代替普通线程同步。
- -XX:MaxHeapFreeRatio 设置垃圾收集后空闲堆空间的最大比率。它避免了收缩。
- -XX:minheafreeratio设置垃圾收集后空闲堆空间的最小比率。它避免了膨胀。
- -XX:生存空间设置伊甸园与生存空间的比例。
- -XX:+UseStringCache 允许缓存字符串池中最常见的字符串。
- -XX:+UseCompressedStrings允许使用字节数组以纯 ASCII 格式存储字符串。
- -XX:+OptimizeStringConcat优化字符串的连接操作。
摘要
在本教程中,我们了解了一些关键的 JVM 参数。这些参数配置了 Java 虚拟机,并提高了我们应用的整体性能。我们也可以将它们用于调试目的。
Java 中的【预期类接口或枚举】错误
原文:https://www.studytonight.com/java-examples/class-interface-or-enum-expected-error-in-java
class, interface, or enum expected
错误是一个编译时错误,由于缺少大括号而发生。这个错误很容易解决。让我们看看发生这种错误的一些情况。
缺少大括号
如上所述,the class, interface, or enum expected
错误可能由于缺少大括号而发生。编译器会告诉我们不需要的大括号的确切位置。例如,在下面的代码中,第 9 行有一个额外的右大括号。
public class Demo
{
public static void main(String args[])
{
int a = 10, b = 15;
System.out.print("The Sum is: " + (a + b));
}
}
}
下图显示了我们试图编译上述代码时得到的错误消息。9(突出显示)显示发生错误的行号。我们可以通过移除额外的支架来纠正它。
类外方法
此错误的另一个原因可能是类外部存在的方法。例如,在下面的代码中,someMethod()方法在 Demo 类之外。这个函数不是任何类的一部分,所以我们会在编译过程中得到这个错误。我们可以通过在类内移动方法来解决这个错误。
public class Demo
{
public static void main(String args[])
{
int a = 10, b = 15;
System.out.print("The Sum is: " + (a + b));
}
}
public void someMethod()
{
//do something
}
输出:
多个包
我们只能在一个 Java 文件中声明一个包。如果我们有多个包,那么我们会得到class, interface, or enum expected
编译错误。
package Package1;
package Package2;
public class Demo
{
public static void main(String args[])
{
int a = 10, b = 15;
System.out.print("The Sum is: " + (a + b));
}
}
摘要
由于一些不同的原因,类、接口或枚举出现了预期的错误。解决这个错误非常简单。如果我们使用的是 IDE,这个错误并不是什么大问题。
在 JUnit 中断言异常
原文:https://www.studytonight.com/java-examples/assert-exceptions-in-junit
在 JUnit 4 中,我们可以通过使用 @Test 注释的预期属性来测试一个方法是否抛出异常。我们可以使用断言.资产抛出()在 JUnit 5 中测试同样的事情。
在本教程中,我们将学习如何使用 JUnit 检查异常是否发生。
JUnit 4 预期异常
我们可以使用带有 @Test 注释的期望属性来定义我们期望从测试方法中得到的异常。如果异常发生在测试方法中,那么测试通过。
如果预期的异常没有发生,测试将失败。让我们看看这两种情况。
在下面的代码中,我们期望出现 ArrayIndexOutOfBounds 异常。当我们试图访问大小为 5 的数组的索引 100 处的元素时,会出现异常。在这种情况下,测试将通过。
import org.junit.Test;
public class Demo
{
@Test(expected = ArrayIndexOutOfBoundsException.class)
public void testMethod()
{
int[] intArr = {10, 20, 30, 40, 50};
int x = intArr[100];//Exception
}
}
现在,如果我们尝试访问索引 2 处的元素,则不会出现错误。在这种情况下,测试将会失败,因为我们预期会出现异常。
import org.junit.Test;
public class Demo
{
@Test(expected = ArrayIndexOutOfBoundsException.class)
public void testMethod()
{
int[] intArr = {10, 20, 30, 40, 50};
int x = intArr[2];
}
}
故障跟踪:
java.lang.AssertionError:预期异常:Java . lang . arrayindexoutofboundsexception
如果我们需要验证异常的一些附加属性,那么我们可以使用 ExpectedException 规则。让我们创建一个方法,抛出一个带有“越界”异常消息的 ArrayIndexOutOfBounds 异常。让我们尝试使用 ExpectedException 规则来验证此消息。
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class Demo
{
@Rule
public ExpectedException rule = ExpectedException.none();
void someMethod() throws ArrayIndexOutOfBoundsException
{
throw new ArrayIndexOutOfBoundsException("Out Of Bounds");
}
@Test
public void testMethod()
{
rule.expect(ArrayIndexOutOfBoundsException.class);
rule.expectMessage("Out Of Bounds");
someMethod();
}
}
JUnit 5 预期异常
JUnit 5 引入了断言 API ,我们可以用它来测试一个方法抛出的异常。我们将使用断言方法来断言异常。
此方法采用预期的异常类和可执行代码块或 lambda 表达式作为参数。如果预期的异常发生,那么测试将通过。如果没有异常发生,或者发生了其他类型的异常,那么测试失败。
在下面的代码中,当我们试图解析一个字符串时,我们需要一个numberformateexception。
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class Demo
{
@Test
void testExpectedException()
{
Assertions.assertThrows(NumberFormatException.class, () -> {
Integer.parseInt("Twenty");//Exception
});
}
}
assertThrows()方法也可以预期父类异常。因此,如果我们将异常类作为第一个参数传递,那么对于任何异常,测试都会成功(因为所有异常都扩展了异常类)。
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class Demo
{
@Test
void testExpectedException()
{
Assertions.assertThrows(Exception.class,//Parent Class Exception
() -> {Integer.parseInt("Twenty");}
);
}
}
方法返回一个异常对象。我们可以用它来验证抛出的异常的附加属性。
让我们尝试使用 assertEquals()来验证异常消息。
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class Demo
{
@Test
void testExpectedException()
{
Exception e = Assertions.assertThrows(NumberFormatException.class, () -> {
Integer.parseInt("Twenty");//Exception
});
String msg = e.getMessage();
assertEquals("For input string", msg);
}
}
摘要
在本教程中,我们学习了如何使用 JUnit 断言是否引发了异常。对于 JUnit 4,我们可以在@Test 注释中使用期望的属性。如果我们想要验证其他异常属性,那么我们可以使用 ExpectedException 规则。对于 JUnit 5,我们可以使用断言. assertThrows()方法。
Java final
关键字
原文:https://www.studytonight.com/java-examples/java-final-keyword
final 关键字用于对 Java 中的变量、方法或类进行一些限制。如果一个实体被标记为最终的,那么我们将来就不能改变它的属性。它为不同的实体服务于不同的目的。
在本教程中,我们将学习如何在 Java 中使用 final 关键字。
最终变量
- 如果一个变量被标记为最终变量,那么我们不能给它重新分配一个值。
- 变量将始终具有与初始化时相同的值。
- 如果我们试图进行任何修改,我们将会得到一个编译错误。
- 最终变量用于在程序中定义一个常量值,在程序执行过程中不应改变。
public class Demo
{
public static void main(String[] args)
{
final int num = 10;
num = 500;//Compilation error
}
}
线程“main”Java . lang . error:未解决的编译问题:
最终的局部变量 num 无法赋值。它必须是空白的,并且不能在 Demo.main(Demo.java:6)使用复合赋值
-
如果一个最终变量已经声明但没有初始化,那么它被称为空白最终变量。
-
静态字段也可以成为最终字段。它们必须在声明时或在静态块中初始化。类常量总是大写的。下划线用于分隔多个单词。
final static double PI = 3.1415;//Declaring and Initializing a final static variable
final static int BOILING_POINT;//Declaring
static { BOILING_POINT = 100; }//Initializing in Static block
最终参考变量
- 就像最终的基元变量一样,最终引用变量在初始化后不能被重新分配。
- 但是,我们可以更改被引用对象的属性或字段。
例如,在下面的代码中,我们已经创建了最终的学生类引用变量。我们不能使引用变量指向一个新对象。
class Student
{
String name;
Student(String s){
this.name= s;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Demo
{
public static void main(String[] args)
{
final Student student = new Student("Justin");
student = new Student("Jessica");//Error because of reassignment
}
}
线程“main”Java . lang . error:未解决的编译问题:
最终的局部变量 student 无法赋值。它必须是空白的,并且不能在 Demo.main(Demo.java:23)使用复合赋值
但是,我们可以更改对象的名称字段。
public class Demo
{
public static void main(String[] args)
{
final Student s = new Student("Justin");
s.setName("Justin Greene");//Modifying final object properties is allowed
System.out.print("Name of Student: " + s.getName());
}
}
学生姓名:贾斯汀·格林
请注意,上述情况也适用于数组,因为数组也作为对象存储。下面的代码演示了这一点。
final int[] intArr = {1, 2, 3};
intArr = new int[5]; //Error as reassignment is not allowed
intArr[1] = 10; //Allowed
最终参数或参数
我们不能修改方法体内的一个最终参数。我们会得到一个编译错误。
public class Demo
{
public static void someMethod(final int num)
{
num = 10;//Error
//...
}
public static void main(String[] args)
{
someMethod(10);
}
}
线程“main”Java . lang . error:未解决的编译问题:
最终的局部变量 num 无法赋值。在 Demo.someMethod(Demo.java:5)和 Demo.main(Demo.java:10)中,它必须为空,并且不使用复合赋值
期末班
- 如果一个类被标记为最终类,那么它不能被任何其他类继承。
- 很多核心 Java 库都包含最终类。像整数或双精度这样的包装类是最终的。
String
类也被声明为最终类。这样做是为了避免继承,以保持类的行为可预测。 - final 关键字也用于创建不可变的类。
- 请注意,使类成为最终类不允许任何其他开发人员扩展或添加特性。我们将失去该类的可扩展性和可继承性。
下面的代码显示了最后一个类,如果 ClassB 试图扩展 ClassA,我们将得到一个编译错误。
final class ClassA{
int a;
ClassA(int x){
this.a = x;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
class ClassB extends ClassA//Error
{
//...
}
请注意,使类成为最终类不会改变类成员的可变性。我们仍然可以改变它们。
final class ClassA{
int a;
ClassA(int x){
this.a = x;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
public class Demo
{
public static void main(String[] args)
{
ClassA classA = new ClassA(10);
System.out.println("Before: " + classA.getA());
classA.setA(15);//Allowed
System.out.println("After: " + classA.getA());
}
}
10 点前
15 点后
最终方法
- 我们也可以将方法声明为 final。最终方法不能被覆盖。
- 许多核心 java 库使用最终方法。像 getClass()、notifyAll()、wait()等方法。在对象类中被定义为最终的。
- 当我们只想限制类方法的覆盖时,Final 方法是 final 类的一个很好的替代方法。
- 尽管每个 Java 类都扩展了 Object 类,但是没有其他类可以覆盖上面提到的最终方法。这样做是为了确保对象的行为一致。
例如,在下面的代码中,子类不能覆盖最终的 printA()方法。
class ClassA{
int a;
ClassA(){
this.a = 100;
}
final void printA()
{
System.out.print("Class A or a Subclass of A");
}
}
class ClassB extends ClassA
{
int b;
ClassB(){
super.a = 150;
this.b = 200;
}
@Override
void printA()//Error
{
System.out.print("Class B");
}
}
然而,在上面的代码中,最终的方法是由 ClassB 继承的。我们可以在 ClassB 的对象上使用 printA()方法。
class ClassA{
int a;
ClassA(){
this.a = 100;
}
final void printA()
{
System.out.print("Class A or a Subclass of A");
}
}
class ClassB extends ClassA
{
int b;
ClassB(){
super.a = 150;
this.b = 200;
}
}
public class Demo
{
public static void main(String[] args)
{
ClassB classB = new ClassB();
classB.printA();
}
}
甲类或甲亚类
摘要
final 关键字可以应用于变量、方法和类。我们不能修改或重新分配最终变量的值。最终方法不能在任何子类中被覆盖。最终类不能有任何子类。在本教程中,我们学习了如何使用 final 关键字对 Java 中的变量、方法和类进行某些限制。
如何反编译 Java 类
原文:https://www.studytonight.com/java-examples/how-to-decompile-java-classes
顾名思义,反编译程序用于撤销编译器的效果。反编译程序用于从. class 文件中获取. java 文件。反编译帮助我们理解库的源代码。像 IntelliJ IDEA 这样的一些 ide 自带内置反编译程序,而像 Eclipse 这样的其他 ide 可以安装和使用其他反编译程序。
在本教程中,我们将学习如何反编译一个类来获取它的源代码。
使用 Eclipse IDE 进行反编译
我们可以使用增强类反编译程序(ECD) 插件在 Eclipse 中反编译类文件。ECD 可以从 Eclipse 市场安装。前往帮助> Eclipse 市场,搜索增强类反编译程序。
我们还需要设置 ECD 才能正常工作。转到窗口>首选项>常规>编辑器>文件关联,并选择“*”。没有源的类”选项。选择“类反编译程序查看器”作为它的默认值,并应用更改。
接下来,我们可以通过点击一个类文件来反编译它。下图显示了反编译的 KeyEvent 类。 FernFlower 反编译程序用于此目的。
使用智能思想进行反编译
IntelliJ IDEA 自带一个内置的反编译程序,使用 FernFlower 反编译程序。我们可以用 IntelliJ 打开一个. class 文件,它会自动反编译成它的源代码。让我们尝试反编译由以下源代码生成的类文件。
public class Demo
{
public static void main(String[] args)
{
int num1 = 5;
int num2 = 15;
double result = num2 / num1;
System.out.print(result);
}
}
反编译的代码如下图所示。
使用命令行进行反编译
我们也可以从命令行反编译 JAR 或类文件。我们可以使用一些不同的工具。
JD-CLI
我们可以使用 JD-CLI 使用简单的 java 命令反编译我们的文件。前往 JD-CLI 的 GitHub 页面(https://github.com/intoolswetrust/jd-cli)下载并设置反编译程序。
java -jar jd-cli.jar [class-file]
蕨类植物
我们还可以使用 FernFlower 反编译程序,使用命令行反编译 JARs 或类文件。克隆蕨类植物资源库(https://github.com/fesh0r/fernflower)并使用 Gradle 工具为其构建源代码。
git clone https://github.com/fesh0r/fernflower
cd fernflower
gradle build
接下来,我们可以运行以下命令来反编译一个 JAR 文件,并将内容存储在上述目录中。
java -jar fernflower.jar [path to JAR or .class file] [directory to store the decompiled files]
Javap!javap
我们还可以使用 javap 命令来查看类文件中的反汇编代码。它不会显示任何方法实现,但是我们可以查看每个方法的反汇编代码。
让我们考虑一下,我们将下面的代码编译成了一个 Demo.class 文件。
public class Demo
{
public static void main(String[] args)
{
int num1 = 5;
int num2 = 15;
double result = num2 / num1;
System.out.print(result);
}
}
下图显示了一个简单的 javap 命令的输出。
主要方法查看拆解代码。
摘要
要理解应用背后的逻辑,需要查看编译文件的源代码。我们可以反编译 JARs 或。通过使用像 Eclipse 或 IntelliJ IDEA 这样的 ide 来创建类文件。Eclipse 需要安装额外的插件,而 IntelliJ IDEA 附带了一个使用 FernFlower 的内置反编译程序。我们还可以使用流行的命令行工具,如 JD-CLI 或 FernFlower,使用 IDEs 反编译文件。
如何在 Windows、Linux 和 Mac 上安装 Maven
原文:https://www.studytonight.com/java-examples/how-to-install-maven-on-windows-linux-and-mac
Maven 是一个命令行工具,用于构建和管理基于 Java 的应用。我们可以获得一个包含设置 Maven 所需的所有文件的档案。不需要安装程序。我们需要设置先决条件并配置我们的环境来运行 Maven。
Maven 是使用 Java 编写的,所以请确保您的系统中安装了 Java。
运行以下命令,确保您的系统上安装了 Java。如果没有安装 JAVA,安装最新的 JDK 并添加 JAVA_HOME 环境变量。
java -version
在 Windows 上安装 Maven
- 我们首先需要从官方的 Apache Maven 项目网站-https://maven.apache.org/download.cgi下载最新版本的 Maven。下载可用的最新 ZIP 文件。
- 将内容解压缩到您想要存储 Maven 文件的位置。
- 接下来,使用系统属性将 M2_HOME 和 MAVEN_HOME 变量添加到 Windows 环境变量中。将它们指向您存储 Maven 文件的位置。
- 最后一步包括更新 PATH 变量,以便从任何地方运行 Maven 命令。我们需要将 Maven bin 文件夹- %M2_HOME%\bin -追加到路径变量中。
- 我们可以通过运行以下命令来检查 Maven 的版本,从而确认 Maven 是否设置成功。
mvn -version
在 Linux 上安装 Maven
- 要在 Linux 上安装 Maven,前往官方的 Apache Maven 项目网站(https://maven.apache.org/download.cgi)并下载二进制的 tar.gz 文件。将归档文件提取到您想要使用 Maven 的文件夹中。
- 接下来,打开终端,使用以下命令设置环境变量。请注意,M2_Home 路径必须与提取的 Maven 文件的位置相对应。
export M2_HOME=/usr/local/apache-maven/apache-maven-3.8.1
export M2=$M2_HOME/bin
export MAVEN_OPTS=-Xms256m -Xmx512m
- 接下来,我们需要将 M2 变量附加到路径中。
export PATH=$M2:$PATH
- 要确认是否成功添加了 Maven,请使用以下命令。
mvn -version
在 Ubuntu 上安装 Maven
我们可以通过使用 apt 命令很容易地在 Ubuntu 上安装 Maven。
- 首先,通过运行以下命令更新包索引。
sudo apt update
- 接下来,使用以下 apt 命令安装 Maven。
sudo apt install maven
- 上面的命令可能需要几分钟来下载和安装 Maven。完成后,我们可以使用以下命令验证安装。
mvn -version
在 Mac OS X 上安装 Maven
- 前往 Apache Maven 项目官方网站(https://maven.apache.org/download.cgi)下载最新的 Maven 二进制 tar.gz 文件。将其提取到您希望 Maven 居住的位置。
- 接下来,我们需要设置环境变量。我们需要将 Maven bin 目录添加到路径变量中。打开。并向其中添加以下命令。
export M2_HOME="/Users/User-1/Downloads/apache-maven-3.8.1"
export PATH=${PATH}:${M2_HOME}/bin
- 使用来源。bash_profile 命令来应用更改。要验证安装,请运行以下 mvn 命令。
mvn -version
使用自制程序
如果您已经安装了自制程序,那么您可以简单地运行以下命令来安装 Maven。
brew install maven
要确认安装,请运行 mvn 版本命令。
摘要
Maven 是一个流行的 Java 应用构建和依赖管理工具。安装和设置 Maven 并不复杂。我们可以从 Apache Maven 项目网站下载必要的文件。在本教程中,我们学习了如何在不同的操作系统上安装 Maven。
Java 中【表达式的非法开始】错误
原文:https://www.studytonight.com/java-examples/illegal-start-of-expression-in-java
【表达式的非法开始】错误是使用 Java 时遇到的常见错误。这是一个动态错误,当我们使用 javac 命令时,会在编译时发生。如果我们知道错误的原因,我们可以很容易地解决它。
在本教程中,我们将学习这个错误背后的原因以及如何解决它。
缺少大括号
如果省略左大括号或右大括号,可能会出现表达式的非法开头错误。缺少大括号会违反 Java 编程的语法,代码无法编译。下面的代码显示了这个场景的一个简单示例。
public class Demo
{
public static void print()
{
System.out.print("A curly brace in missing!");
}
public static void main(String[] args)
{
print();
}
}
当我们尝试使用 javac 编译上述代码时,我们将得到以下结果。
若要修复错误,请在正确的位置添加大括号。
方法内部的访问修饰符
任何方法或块内的变量都称为局部变量,它们的范围仅限于该块。我们不能对局部变量使用访问修饰符,如私有、受保护或公共。
如果违反了此规则,编译器将返回一个非法的表达式开始错误。下面的代码无法编译,因为我们在 print()方法中使用了受保护的访问修饰符。
public class Demo
{
public static void print()
{
protected String str = "protected access modifier";
}
public static void main(String[] args)
{
print();
}
}
输出:
移除受保护的访问修饰符将修复上述代码。
嵌套方法
与 Python 等其他编程语言不同,Java 不支持嵌套方法或方法内部的方法。这将导致表达式错误的非法开始。下面的代码演示了这一点。
public class Demo
{
public void print()
{
String str = "Method Inside Method";
public void printString(String s)
{
System.out.print(s);
}
}
}
输出:
方法内部的类
Java 允许我们在一个方法内部编写一个新的类,但是这个类对于这个方法来说是本地的。这些类被称为方法-局部内部类,它们的范围仅限于方法。但是请注意,这个内部类不应该以任何访问修饰符开始。方法不能包含任何访问修饰符。例如,在下面的代码中,print()方法内部有一个带有公共修饰符的内部类(ClassThatPrints)。这将导致表达式错误的非法开始。
public class Demo
{
public void print()
{
public class ClassThatPrints
{
public void printFromClass()
{
System.out.print("Hello, Java");
}
}
}
}
输出:
不带引号的字符串或字符
字符串和Character
类型必须用引号括起来。字符串或字符也可以包含特殊字符或运算符。因此,重要的是要将引号识别为字符串,而不是特殊字符。
如果我们忘记了引号,并且字符串不包含有效的变量名,那么就会出现非法的表达式开始错误。例如,在下面的代码中,我们没有用引号将星号(*)括起来。这将使编译器抛出非法的表达式开始错误。
public class Demo
{
public static void main(String[] args)
{
String symbol = "*";
int num1 = 5, num2 = 10;
int result;
if(symbol == "/")
result = num2 / num1;
if(symbol == *)
result = num2 * num1;
}
}
输出:
摘要
在本教程中,我们了解了表达式错误非法开始背后的原因。通常,解决这个错误非常容易。有时,这个错误还会在我们的代码中导致多个其他错误。因此,寻找错误的根本原因非常重要。编译器有时不会指出错误的根本原因,所以我们应该修复前面几行中的代码。大多数 IDEs 会在我们运行代码之前警告我们错误。但是理解它们背后的原因很重要。
Java 11 新特性
原文:https://www.studytonight.com/java-examples/java-11-new-features
Java 11 于 2018 年 9 月在推出,也就是 Java 10 发布 6 个月后。Java 10 是最后一个无需许可即可用于商业目的的 Java 版本。
Java 11 不是免费的,我们需要付费才能用于商业目的。Oracle 仍然提供可以免费使用的 OpenJDK 版本。
在本教程中,我们将学习 Java 11 中引入的新特性。
运行 Java 文件
要运行一个 Java 文件,我们首先使用 javac 命令编译它。但是使用 Java 11,我们可以通过使用单个 Java 命令直接运行一个 Java 文件。
javac MyFirstJavaProgram.java
java MyFirstJavaProgram
我们不再需要使用上述过程。相反,我们可以使用以下命令,它将给出相同的结果。阅读我们关于的详细文章。
java MyFirstJavaProgram.java
新字符串方法
Java 11 为字符串类引入了一些新方法。下面的列表解释了这些新方法。
isBlank() -该方法用于检查字符串是否为空。空字符串和只有空白的字符串被视为空白。
public class Demo
{
public static void main(String[] args)
{
String s1 = "";
String s2 = " ";
String s3 = "String";
System.out.println("s1 is blank: " + s1.isBlank());
System.out.println("s2 is blank: " + s2.isBlank());
System.out.print("s3 is blank: " + s3.isBlank());
}
}
s1 为空:真
s2 为空:真
s3 为空:假
line()-该方法使用行终止符拆分字符串并返回一个流。
import java.util.List;
import java.util.stream.Collectors;
public class Demo
{
public static void main(String[] args)
{
String s = "This\n is\n a\n String";
List<String> listOfLines = s.lines().collect(Collectors.toList());
System.out.print(listOfLines);
}
}
【这,是,a,字符串】
repeat() - 此方法用于复制或重复字符串。
public class Demo
{
public static void main(String[] args)
{
String s = "String";
System.out.println("String: " + s);
System.out.println("String repeated twice: " + s.repeat(2));
System.out.print("String repeated five times: " + s.repeat(5));
}
}
弦:弦
弦重复两次:弦响
弦重复五次:弦响弦响弦响
strip()、stripLeading()、strip training()-这些方法用于移除字符串中的空白。它们与现有的 trim()方法非常相似,但提供了 Unicode 支持。
public class Demo
{
public static void main(String[] args)
{
String s = " string ";
System.out.println("$" + s + "$");
System.out.println("$" + s.strip() + "$");
System.out.println("$" + s.stripLeading() + "$");
System.out.println("$" + s.stripTrailing() + "$");
}
}
$ string \( \) string \( \) string \( \) string $
基于嵌套的访问控制
以前的 Java 版本允许私有成员访问嵌套类(嵌套类),但是我们不能将它们与反射 API 一起使用。Java 11 不再使用桥方法,而是为反射 API 提供了 getNestHost()、getnestmotof()和 isNestmatOf()方法。
public class Demo {
private void privateMethod() {
System.out.print("Private Method");
}
class NestedClass {
public void callPrivateMethod() {
privateMethod();
}
}
public static void main(String[] args) {
System.out.println(Demo.class.isNestmateOf(Demo.NestedClass.class)); //Demo class is nestmate of NestedClass
System.out.println(Demo.NestedClass.class.isNestmateOf(Demo.class)); //NestedClass is nestmate of Demo class
System.out.println(Demo.NestedClass.class.getNestHost()); //Nest host of NestedClass
System.out.println(Demo.class.getNestMembers()); //Nest host of Demo class
}
}
真
真
班 Demo
【ljava . lang . class;@36baf30c
新文件方法
Java 11 使得读取和写入字符串变得更加容易。为此,在File
类中添加了 readString()和 writeString()静态方法。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class Demo
{
public static void main(String[] args) throws IOException
{
Path path = Files.createTempFile("temporaryFile", ".txt");
//Writing to the file
Files.writeString(path, "Hello World");
//Reading from the file
String s = Files.readString(path);
System.out.print(s);
}
}
你好世界
集合转换为数组
新的默认 toArray()方法用于轻松地将集合转换为正确类型的数组。
import java.util.ArrayList;
import java.util.Arrays;
public class Demo
{
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(5);
list.add(10);
list.add(15);
Integer[] intArr = list.toArray(Integer[]::new);
System.out.print(Arrays.toString(intArr));
}
}
【5,10,15】
not()方法
Java 11 中的谓词接口增加了一个静态 not()方法。顾名思义,这种方法用于否定谓词。not()方法也可以与方法引用一起使用。
让我们使用这个方法来创建两个执行相反任务的谓词。
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class Demo
{
public static void main(String[] args) {
Predicate<String> startWithZ = s -> s.charAt(0) == 'z';
Predicate<String> doesNotStartWithZ = Predicate.not(startWithZ);
List<String> list = Arrays.asList("za", "zq", "az", "aq", "zz");
List<String> strsStartingWithZ = list.stream()
.filter(startWithZ)
.collect(Collectors.toList());
List<String> strsNotStartingWithZ = list.stream()
.filter(doesNotStartWithZ)
.collect(Collectors.toList());
System.out.println(strsStartingWithZ);
System.out.println(strsNotStartingWithZ);
}
}
【za,zq,ZZ】
【az,aq】
HTTP 客户端
HTTP 客户端 API 最初是在 Java 9 中引入的,并在 Java 10 中进行了更新。它是作为 Java 11 版本的标准功能提供的。新的 API 性能更好,兼容 HTTP/1.1 和 HTTP/2。该 API 还提供对网络套接字的支持。
λ的局部变量语法
Java 11 增加了对 lambda 表达式的局部变量语法的支持。Lambdas 可以推断类型,但是使用 var 关键字允许我们在参数中使用像@NotNull 或@Nullable 这样的注释。
(@NotNull var str) -> "$" + str
动态类文件常数
在 Java 11 中,Java 类文件格式支持一种新的常量池形式,称为常量 _ 动态。这将把创建委托给引导方法。这是为了通过创建一个新的常量池表单来降低创建新的可具体化类文件常量的成本,该表单将通过适当的用户定义行为进行参数化。这一特性大大提高了性能。
改进的 Aarch64 内部电路
内部函数是由编译器以某种特殊方式处理的函数。它们利用特定于 CPU 架构的汇编代码来提高性能。
Java 11 改进和优化了 AArch64(或 ARM64)处理器上现有的字符串和数组内部特性。Java 11 还为 java.lang.Math 的 sin、cos 和 log 方法添加了新的内部函数。
ε垃圾收集器
Java 11 引入了一个名为 Epsilon 的无操作(No-Op)垃圾收集器。这是一个实验特征。它被称为无操作垃圾收集器,因为它将分配内存,但永远不会收集任何垃圾。我们可以用它来模拟内存不足的错误。以下是它的一些用例。
- 性能试验
- 记忆压力测试
- 虚拟机接口测试和
- 极其短暂的工作
- 最后一滴延迟和吞吐量改进
使用以下命令启用ε气相色谱。
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC
Java 飞行记录器
Java 飞行记录器(简称 JFR)用于为应用收集分析数据。它过去只能用于商业用途,但现在在 OpenJDK 11 下是开源的。我们可以将它用于生产应用,因为它的开销很小(低于 1%)。它将数据记录在 JFR 文件中,我们可以使用 JDK 任务控制工具来分析收集到的信息。使用以下命令开始 180 秒的 JFR 录音,并将数据存储在 demo.jfr 文件中。
-XX:StartFlightRecording=duration=180s,settings=profile,filename=demo.jfr
弃用的 Java EE 和 CORBA 模块
Java EE 和 COBRA 的一些模块在 Java 9 中被弃用。它们现在已经完全从 Java 11 中移除了。以下包和工具不再是 Java 11 的一部分。但是,它们仍然可以在第三方网站上使用。
- java.xml.ws
- java.xml.bind
- java.activation
- java.xml.ws.annotation
- java.corba
- java .事务
- java.se.ee
- wsgen 和 wsimport
- schemagen 和 xjc
- idlj、orbd、servertool 和 tnamesrv
删除了 JMC 和贾法克斯
JDK 将不再包括 JDK 任务控制(JMC)和 JavaFX 模块。它们可以单独下载。
弃用的模块
在 Java 11 中不推荐使用纳斯霍恩 JavaScript 引擎和 JJS。未来的版本可能会完全删除它们。
也不推荐使用 pack200 和 unpack200 工具以及 java.util.jar 的 pack200 压缩方案 API。
其他变化
- 不安全的 RC4 流密码被 ChaCha20 和 ChaCha20-Poly1305 密码实现所取代。
- 椭圆曲线差分-赫尔曼(ECDH)方案被曲线 25519 和曲线 448 密钥协商方案所取代。
- 传输层安全性(TLS)升级到 1.3 版,以提高安全性和性能。
- 介绍了一种低延迟、可扩展的垃圾收集器——Z 垃圾收集器(ZGC)。这是一个实验特征。
- Unicode 10 带来了新的代码点、字符、符号和表情符号。
摘要
Java 11 引入了很多新的变化和特性。一些现有功能已被弃用或完全删除。在本教程中,我们了解了 Java 11 中引入的变化。
Mockito 的间谍
原文:https://www.studytonight.com/java-examples/spy-in-mockito
Mockito 是一个 Java 框架,用于模拟和单元测试 Java 应用。在内部,这个框架使用反射 API。Mockito 通过创建模拟对象和避免外部依赖来简化测试过程。它与其他测试框架一起使用,如 JUnit 或 TestNG 。
在本教程中,我们将了解 Mockito 的间谍。
莫基托间谍
间谍就像一个局部模拟,它会像模拟一样跟踪与对象的交互。此外,它允许我们调用对象的所有正常方法。每当我们调用间谍对象的一个方法时,真正的方法就会被调用(除非它被存根化)。
使用 Mockito.spy()方法创建间谍
在下面的代码中,我们为ArrayList
创建了一个间谍。Mockito.spy()方法用于此目的。验证()方法用于验证交互是否发生。当对间谍调用 add()方法时,将调用实际的方法,并将元素添加到列表中。我们可以通过查看列表的大小来验证它。
public class MockitoSpyDemo
{
@Test
public void test()
{
ArrayList<Integer> arrList = new ArrayList<>();
ArrayList<Integer> spyArrList = Mockito.spy(arrList);
//Adding Elements
spyArrList.add(5);
spyArrList.add(10);
spyArrList.add(15);
//Verifying interactions
Mockito.verify(spyArrList).add(5);
Mockito.verify(spyArrList).add(10);
Mockito.verify(spyArrList).add(15);
//Verifying that elements were actually added to the list
assertEquals(3, spyArrList.size());
}
}
使用@间谍注释创建间谍
我们也可以使用@Spy 注释创建一个间谍对象。要启用 Mockito 注释,我们可以使用mockitonations . init mocks(this)方法。或者我们可以使用内置的 runner@ RunWith(mockitojunitrunner . class)。两者的示例如下所示。
使用模拟注释
public class MockitoSpyDemo
{
//Using @Spy Annotation
@Spy
ArrayList<Integer> spyArrList = new ArrayList<>();
@Before
public void init()
{
MockitoAnnotations.initMocks(this);
}
@Test
public void test()
{
spyArrList.add(5);
spyArrList.add(10);
spyArrList.add(15);
Mockito.verify(spyArrList).add(5);
Mockito.verify(spyArrList).add(10);
Mockito.verify(spyArrList).add(15);
assertEquals(3, spyArrList.size());
}
}
使用@ RunWith(mockitojunitrunner . class)
@RunWith(MockitoJUnitRunner.class)
public class MockitoSpyDemo
{
//Using @Spy Annotation
@Spy
ArrayList<Integer> spyArrList = new ArrayList<>();
@Test
public void test()
{
spyArrList.add(5);
spyArrList.add(10);
spyArrList.add(15);
Mockito.verify(spyArrList).add(5);
Mockito.verify(spyArrList).add(10);
Mockito.verify(spyArrList).add(15);
assertEquals(3, spyArrList.size());
}
}
干掉一名间谍
我们可以截取一个间谍来覆盖一个方法的正常行为。让我们覆盖 ArrayLists 的 contains()方法的默认行为。让我们让这个方法总是为值 5 返回 false。
public class MockitoSpyDemo
{
@Test
public void test()
{
ArrayList<Integer> spyArrList = Mockito.spy(new ArrayList<>());
spyArrList.add(5);
Mockito.verify(spyArrList).add(5);
assertEquals(true, spyArrList.contains(5));//Default normal behavior
Mockito.doReturn(false).when(spyArrList).contains(5);
assertEquals(false, spyArrList.contains(5));//Stubbed Behavior
}
}
让我们覆盖ArrayList
的 size()方法。它应该总是返回 5 作为列表大小。
public class MockitoSpyDemo
{
@Test
public void test()
{
ArrayList<Integer> spyArrList = Mockito.spy(new ArrayList<>());
spyArrList.add(5);
Mockito.verify(spyArrList).add(5);
assertEquals(1, spyArrList.size());//Default Normal Behavior
Mockito.doReturn(5).when(spyArrList).size();
assertEquals(5, spyArrList.size());//Stubbed Behavior
}
}
Mockito 的模拟 vs 间谍
间谍被称为部分嘲讽。模拟是从一个类型的类中创建的,而间谍是从类的实际实例中创建的。在模拟的情况下,类的所有正常方法都不会被执行。另一方面,间谍会使用原始行为的方法。方法执行的结果也反映在间谍对象上。
例如,在下面的代码中,我们有一个模拟和一个间谍。两个对象都验证了交互。但是当 add()方法被调用时,一个元素只被添加到间谍列表中。模拟列表的大小为零,表明 add()方法没有做任何事情。
public class MockitoSpyDemo
{
@Test
public void test()
{
//Creating a spy and a mock
ArrayList<Integer> spyArrList = Mockito.spy(new ArrayList<Integer>());
ArrayList<Integer> mockArrList = Mockito.mock(ArrayList.class);
//Adding an element to spy and mock
spyArrList.add(5);
mockArrList.add(5);
//Verifying the interaction
Mockito.verify(spyArrList).add(5);
Mockito.verify(mockArrList).add(5);
//verifying the size of the spy and the mock
assertEquals(1, spyArrList.size());
assertEquals(0, mockArrList.size());
}
}
莫基托注意到异常
使用 Mockito 时,经常会遇到 NotAMockException。当我们试图在其他对象上使用模拟特定的方法时,会引发此异常。例如,在下面的代码中,我们创建了一个ArrayList
,但它不是模拟的。当我们对其使用 verify()方法时,会引发 NotAMockException。正如异常的名称所示,ArrayList
不是模拟的,我们不能对它使用 verify()方法。例外情况还附带了一些如何使用该方法的建议。
public class MockitoSpyDemo
{
@Test
public void test()
{
ArrayList<Integer> arrList = new ArrayList<>();
arrList.add(5);
Mockito.verify(arrList).add(5);//NotAMockException
}
}
org . mock ITO . exceptions . misusing . nota mock exception:
传递给 verify()的参数属于 ArrayList 类型,不是 mock!
确保括号放置正确!
参见正确验证示例:
验证(模拟)。some method();
验证(模拟,次数(10))。some method();
验证(模拟,至少测试())。some method();
在 Demo.test(Demo.java:15)
摘要
Mockito 框架用于 Java 应用的单元测试。在本教程中,我们学习了 Mockito 框架的间谍对象。与模拟不同,间谍执行对象的真实方法,方法的结果也反映在对象中。我们还了解了 NotAMockException,如果 Mockito 方法使用不当,就会引发该异常。
Java 8 面试问题
原文:https://www.studytonight.com/java-examples/java-8-interview-questions
Java 是一种非常流行的编程语言,应用非常广泛。 Java 8 于 2014 年发布,增加了很多新功能,克服了之前版本的局限性。在本教程中,我们将讨论一些关于 Java 8 的最常见的面试问题。
Q1。简要说明 Java 8 中增加的新特性
- Lambda 表达式 -用于定义可以作为对象引用的函数。
- 函数式接口 -仅用一个抽象方法进行接口。
- 方法引用 -允许我们使用函数作为调用方法的参数。
- 可选 -用于检查空值的包装类。
- 默认方法 -允许我们在接口内部添加方法的实现。
- 流 API -允许数据流水线处理的特殊迭代器类。
- 日期 API -受 JodaTime 启发而改进的 API。
Q2。解释一下 Java 8 的优点?
- 增加代码的可读性和可重用性。
- 较小的样板代码。
- 稳定性更高。
- 操作的并行执行。
- 紧凑代码
Q3。Java 8 中的方法引用是什么意思?
方法引用是一种在不调用方法的情况下引用方法的方式。双冒号(::)用于方法引用。方法引用用于将方法视为 Lambda 表达式。
Q4。什么是函数式接口?
函数式接口是一个只有一个抽象方法的接口。它们也被称为 SAM 接口。SAM 代表单一抽象方法。可以使用@FunctionalInterface 注释,但它是可选的。默认、静态和覆盖方法的数量没有限制。功能界面的示例如下所示。
@FunctionalInterface
interface FunctionalDemo
{
abstract public void someAbstractMethod();
default public void defaultMethod()
{
System.out.print("Default");
}
}
Q5。什么是 Lambda 表达式?
Lambda 表达式是一个匿名函数,可以被引用并用作对象。以下是 Lambda 表达式的一些关键特征。Lambda 表达式也可以用作其他方法的参数。
Q6。如何创建 Lambda 表达式?解释基本语法。
Lambda 表达式包含三个部分。
- 参数列表用圆括号()括起来。
- 表达式主体用花括号{}括起来。
- 箭头符号(- > ) 将参数列表和正文分开。
下面的代码显示了一个基本的 lambda 表达式。
interface DemoInterface{
abstract void add(int i, int j);
}
public class Demo
{
public static void main(String[] args) throws Exception
{
DemoInterface i = (int a, int b) -> {
System.out.print("Sum is: " + (a + b));
};
i.add(10, 20);
}
}
总和是:30
以下是 Lambda 表达式的一些关键特征。
Optional
类型声明-我们不需要声明参数的类型。编译器可以从它们的值和用法来推断类型。- 参数周围的可选圆括号-如果我们只有一个参数,那么我们不需要用圆括号把它括起来。
- 可选的大括号-如果表达式只包含一行代码,那么我们不需要用大括号把它括起来。
- 可选的 return 关键字-如果表达式返回值并且用花括号包装,那么我们不需要使用 return 语句。
Q7。什么是 Java 8 Streams?
流就像是从一个源获得的一系列对象,就像集合。它们用于以流水线方式对数据执行聚合操作。它们被用来使数据处理变得更简单、更容易。
Q8。解释日期和时间 API 的一些特性。
新的日期和时间 API 解决了以前的日期 API 的一些缺点。日期和时间 API 的主要功能如下所述。
- 类是不可变的
- 提供线程安全以避免并发问题。
- 时区支持
- 符合国际标准化组织标准
- 灵感来自 JodaTime
- 支持时区
Q9。如何使用本地日期、本地时间和本地日期时间 API 获取当前日期和时间?
我们可以对所有这些类使用 now()方法来获取当前日期和时间。
import java.time.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
LocalDate currLocalDate = LocalDate.now();
LocalTime currLocalTime = LocalTime.now();
LocalDateTime currLocalDateTime = LocalDateTime.now();
System.out.println("Local Date: " + currLocalDate);
System.out.println("Local Time: " + currLocalTime);
System.out.println("Local Date and Time: " + currLocalDateTime);
}
}
当地时间:2021-08-06
当地时间:16:06:52.498893400
当地日期和时间:2021-08-06T16:06:52.498893400
Q10。解释纳斯霍恩?
Nashorn 是 Java 8 附带的一个新的 JavaScript 处理引擎。它取代了 JDK 7 附带的 Mozilla Rhino。它提供了更好的运行时性能。它还提供了更好的符合 ECMA(欧洲计算机制造商协会)规范的 JavaScript 规范。
Q11。默认方法是什么意思?
在接口内部实现的方法称为默认方法。默认关键字用在它们的声明中。它们被添加到 Java 8 中,以提供“向后兼容性”。这意味着如果 JDK 修改了一个接口,那么实现它的类将会中断。但是使用默认方法,对实现类不会有任何影响。
interface DemoInterface
{
abstract void print(int i, int j);
abstract String concat(String s1, String s2);
//Default method
default void defaultMethod()
{
System.out.print("Default method called!");
}
}
Q12。什么是 JJS?
JJS 代表 Java JavaScript,它是一个命令行工具,用于在控制台中执行 JavaScript。
Q13。借助一个例子解释 forEach()方法。
forEach()方法是流 API 的一部分。它用于迭代流的每个元素并执行一个操作。让我们尝试添加 10 个元素,并使用 forEach()方法打印一个流的所有元素。
import java.util.stream.Stream;
public class Demo
{
public static void main(String[] args) throws Exception
{
Stream s = Stream.of(1, 2, 3, 4, 5);
s.forEach(i -> System.out.println((int)i + 10));
}
}
11
12
13
14
15
Q14。PermGen 和 MetaSpace 有什么区别?
永久生成的缩写,是 Java 8 之前存储类信息和元数据的地方。这是一个连续的堆内存空间,大小是固定的。MetaSpace 是在 Java 8 中引入的,它提供了一个动态的或可调整大小的本机内存来存储类元数据。它改进了元数据的取消分配和垃圾收集,并且不受大小限制。
Q15。您将如何使用流来查找和打印数组中的偶数?
我们可以使用流的 filter()方法来找到偶数。然后,我们可以使用 forEach()方法简单地PrintStream
元素。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Demo
{
public static void main(String[] args) throws Exception
{
List<Integer> list = Arrays.asList(7, 9, 10, 1, 2, 5, 12, 11, 3, 4);
Stream<Integer> evenNums = list.stream().filter(i -> i % 2 == 0);
evenNums.forEach(System.out::println);
}
}
10
2
12
4
Q16。Java 8 中什么是 Spliterator?
Spliterator 是 Java 8 中引入的迭代器接口。就像普通的迭代器一样,它可以迭代或遍历集合或流的每个元素。与普通迭代器不同,Spliterator 支持并行和顺序遍历。
Q17。流和集合有什么区别?
| 流 | 集合 |
| 用于处理数据。 | 用于存储数据。 |
| 可以处理无限多的元素。 | 可以存储有限数量的元素。 |
| 不能直接访问元素。 | 更容易接触到元素。 |
Q18。解释 Java 8 中的流流水线。
流水线是将多个操作链接在一起的概念。操作可以有两种类型——中间操作和终端操作。中间操作返回流的一个实例,终端操作用于终止管道。
Q19。借助示例解释中间和终端操作。
流流水线通过使用中间和终端操作来完成。中间操作返回流的一个实例,用于链接多个操作。中间操作是懒惰的,因为它们不会开始执行,直到终端操作被调用。中间操作大多使用 lambda 表达式来处理流。一些常见的中间操作有 map、flatMap、filter、peek 等。
顾名思义,终端操作用于终止流流水线操作。它们用于启动流处理。一些常见的终端操作包括 forEach()、forEachOrdered()、collect()、reduce()等。
例如,在下面的代码中,我们首先使用两个中间操作(map()和 filter()),然后使用终端 forEach()方法打印结果。
import java.util.Arrays;
import java.util.List;
public class Demo
{
public static void main(String[] args) throws Exception
{
List<String> list = Arrays.asList("Hello", "Hola", "Ola");
list.stream().map(s -> s.toUpperCase()) //Intermediate
.filter(s -> s.startsWith("H")) //Intermediate
.forEach(System.out::println); //Terminal
}
}
你好
你好
Q20。什么是可选的,为什么使用它?
可选是可以包含零(空)或一个值的容器或包装类。此类包含检查值是否存在的方法。此类用作可能返回 null 的方法的返回类型。该方法需要返回一个对象而不是一个值。这有助于我们避免空指针异常。
Q21。谓词和函数有什么区别?
谓词和函数都是函数接口,它们存在于 java.util.function 包中。谓词用于测试某些东西,而函数用于更通用的目的。谓词根据测试返回真或假。函数返回一个对象。
Q22。如何使用 LocalDate 和 LocalDateTime API 在当前日期的基础上增加一年?
plusYears()方法用于向 LocalDate 或 LocalDateTime 对象添加年数。我们还有 plusDays()和 plusMonths()方法来为我们的日期添加天数或月数。使用负年数()、负月数()或负日数()方法从日期中减去年、月或日。
import java.time.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
LocalDate currLocalDate = LocalDate.now();
System.out.println("Current Date: " + currLocalDate);
LocalDate dateAfterOneYear = currLocalDate.plusYears(1);
System.out.println("Date after one year: " + dateAfterOneYear);
}
}
当前日期:2021-08-06
一年后日期:2022-08-06
摘要
Java 仍然是使用最广泛的编程语言之一,人们必须精通 Java 的基础知识才能在技术面试中胜出。Java 8 引入了几个新特性,在本教程中,我们讨论了与 Java 技术访谈相关的一些最重要的主题。
Java 中的 HTTP 请求
原文:https://www.studytonight.com/java-examples/http-requests-in-java
HttpURLConnection
类是java.net
包的一部分,用于发送 HTTP 请求和获取响应。这是一个抽象类,扩展了URLConnection
类。该类提供基本功能。高级功能最好使用其他 HTTP 库。在本教程中,我们将学习如何使用这个类来处理 HTTP 请求。
使用 http 连接创建请求
要获取HttpURLConnection
类的实例,我们需要在 URL 上使用 openConnection() 方法。还需要显式强制转换。
我们可以通过在 HttpURLConnection 对象上使用 setRequestMethod() 来设置请求的类型。它可以采用以下值之一,默认值是 GET。
- 得到
- 邮政
- 头
- 选择
- 放
- 删除
- 微量
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.studytonight.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
}
}
添加请求参数
我们可以向我们的 HTTP 请求添加请求或查询参数。我们首先需要使用 setDoOutput() 方法在连接对象上启用写入。然后我们可以获取数据输出流并向其写入字符串。字符串的格式必须为“参数 1=val1 &参数 2=val2 &参数 3=val3”。
import java.net.*;
import java.io.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.demo.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
String parameter = "param1=val1¶m2=val2";
DataOutputStream outputStream = (DataOutputStream)connection.getOutputStream();
outputStream.writeChars(parameter);
outputStream.flush();
outputStream.close();
}
}
我们可以通过编写一个方法来简化我们的工作,该方法采用一个 HashMap,并从映射的键值对中生成参数值字符串。
import java.net.*;
import java.io.*;
import java.util.*;
public class Demo
{
public static String addParameters(HashMap<String, String> parameters) throws Exception
{
StringBuilder sb = new StringBuilder();
for(Map.Entry<String, String> e : parameters.entrySet())
{
sb.append(URLEncoder.encode(e.getKey(), "UTF-8"));
sb.append("=");
sb.append(URLEncoder.encode(e.getValue(), "UTF-8"));
sb.append("&");
}
String params = sb.toString();
if(params.length() > 0)
return params.substring(0, params.length() - 1);
else
return params;
}
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.demo.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
HashMap<String, String> parameters = new HashMap<>();
parameters.put("param1", "val1");
parameters.put("param2", "val2");
parameters.put("param3", "val3");
String params = addParameters(parameters);
DataOutputStream outputStream = (DataOutputStream)connection.getOutputStream();
outputStream.writeChars(params);
outputStream.flush();
outputStream.close();
}
}
读取请求标题
为了读取请求头的值,我们在连接对象上使用 getHeaderField() 方法。此方法可以将标题字段的名称作为参数,并返回相应的值。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.studytonight.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
String date = connection.getHeaderField("Date");
System.out.print(date);
}
}
Fri,2021 年 8 月 6 日,格林尼治时间 02:52:29
我们也可以使用一个整数来获取第 n 个标题字段。使用 getHeaderFieldKey() 方法获取第 n 个头字段的名称。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.studytonight.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
String headerKey1 = connection.getHeaderFieldKey(1);
String headerField1 = connection.getHeaderField(1);
String headerKey2 = connection.getHeaderFieldKey(2);
String headerField2 = connection.getHeaderField(2);
System.out.println("Header Field 1: " + headerKey1 + "-->" + headerField1);
System.out.println("Header Field 2: " + headerKey2 + "-->" + headerField2);
}
}
标头字段 1:日期- > Fri,2021 年 8 月 6 日 02:52:29 格林尼治标准时间
标头字段 2:服务器->Apache/2 . 4 . 46(Unix)OpenSSL/1 . 1 . 1d
设置请求标题
我们可以在HttpURLConnection
实例上使用 setRequestProperty() 方法来设置请求头值。让我们设置连接和缓存控制头的值。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.studytonight.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Cache-Control", "no-cache");
}
}
设置超时
我们可以使用 HttpURLConnection 类的 setConnectTimeout() 和 setReadTimeout() 方法来更改连接和读取的默认超时值。我们可以使用 getConnectTimeout() 和 getReadTimeout() 方法查看这些值。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.studytonight.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
System.out.println("Default Timeout Values:");
System.out.println("Connect Timeout: " + connection.getConnectTimeout());
System.out.println("Read Timeout: " + connection.getReadTimeout());
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
//After
System.out.println("After Setting Timeout Values:");
System.out.println("Connect Timeout: " + connection.getConnectTimeout());
System.out.println("Read Timeout: " + connection.getReadTimeout());
}
}
默认超时值:
连接超时:0
读取超时:0
设置超时值后:
连接超时:10000
读取超时:10000
处理饼干
HttpCookie
和CookieManager
课程可以帮助我们使用饼干。为了读取 Cookie,我们可以获取 Set-Cookie 头的值,并使用 HttpCookie 类的 parse() 方法对其进行解析。
import java.net.*;
import java.util.*;
import org.apache.commons.lang3.StringUtils;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.gmail.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
String cookieHeaderField = connection.getHeaderField("Set-Cookie");
List<HttpCookie> cookiesList = HttpCookie.parse(cookieHeaderField);
System.out.println(cookieHeaderField);
System.out.println(cookiesList);
}
}
_ _ Host-gap = 1:wozoyd 84 dr 89 kgux6-xfHQcJX0PpqA:KS-fe4ij 1w 4 gim;路径=/;到期=孙,06-2023 年 8 月 06 日 06:23:56 格林尼治标准时;安全;HttpOnly 优先级=高
[_ _ 主机-间隙= 1:wozoyd 84 dr 89 kgux6-xfhqcjx0 ppqa:KS-fe4ij 1 w4 gim]
我们也可以在食谱中加入饼干。我们可以使用 CookieStore 来设置连接的 Cookie 请求属性。为此,我们需要关闭并重新打开我们的连接。
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.gmail.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
String cookieHeaderField = connection.getHeaderField("Set-Cookie");
List<HttpCookie> cookiesList = HttpCookie.parse(cookieHeaderField);
CookieManager cm = new CookieManager();
cookiesList.forEach(cookie -> cm.getCookieStore().add(null, cookie));
connection.disconnect();
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Cookie",
StringUtils.join(cm.getCookieStore().getCookies(), ";"));
}
}
处理重定向
我们可以在 HttpURLConnection 实例上使用setinstancefloredirections()方法来启用或禁用重定向。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.google.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setInstanceFollowRedirects(true);
}
}
我们还可以通过使用setfollowsredirections()方法来启用或禁用所有连接的重定向。
HttpURLConnection.setFollowRedirects(true);
我们可以使用位置头字段来获取新的重定向网址。我们可以用它向新的重定向网址发送请求。请注意,重定向的响应代码是 301(永久移动)或 302(临时重定向)。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.google.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
boolean redirect = false;
if(connection.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP || connection.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM)
redirect = true;
if(redirect)
{
String redirectURL = connection.getHeaderField("Location");
URL newURL = new URL(redirectURL);
connection = (HttpURLConnection) newURL.openConnection();
}
}
}
阅读回应
HttpURLConnection 类提供了几种方法来读取对我们请求的响应。
读取响应代码和响应消息
我们可以在连接实例上使用 getResponseCode() 和 getResponseMessage() 方法来读取响应代码和响应消息。
import java.net.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("http://www.google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
String responseMsg = connection.getResponseMessage();
System.out.print("Response Code: " + responseCode + " Response Message: " + responseMsg);
}
}
响应代码:200 响应消息:OK
读取响应标题
我们可以使用 getHeaderField() 方法来访问单个头字段。我们可以使用 getHeaderFields() 方法获取所有的头。它将返回一个映射集合。映射中的每个键表示标题字段,相应的值存储在列表中。
import java.net.*;
import java.util.List;
import java.util.Map;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("https://www.studytonight.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
Map<String, List<String>> headerFields = connection.getHeaderFields();
for(Map.Entry<String, List<String>> e : headerFields.entrySet())
System.out.println(e.getKey() + "-->" + e.getValue());
}
}
传输-编码- >【分块】
保活- >【超时=5,最大= 100】
空->【HTTP/1.1 200 OK】
服务器->【Apache/2 . 4 . 46(Unix)OpenSSL/1 . 1 . 1d】
X-内容-类型-选项->【nosniff】
连接- >【保活】【T6 包括域名;预加载]
缓存-控制- >【无存储,无缓存,必须-重新验证】
Vary - >【接受-编码】
Set-Cookie->【phpsesid = 8 iqquicvn 5 ada 6 cjb1 ktkbjlcg;路径=/]
过期->【1981 年 11 月 19 日星期四格林尼治时间 08:52:00】
X-XSS-保护->【1;模式=块]
内容-类型- >【文本/html;charset = UTF-8]
X-power-By->【PHP/7 . 4 . 15】
阅读回复内容
我们可以借助 HttpURLConnection 对象的 InputStream 读取响应内容。如果响应代码大于 200,那么我们将使用geterrortstream()方法。否则,请使用 getInputStream()方法。我们将使用BufferedReader
类来包装InputStreamReader
。
import java.net.*;
import java.io.*;
public class Demo
{
public static void main(String[] args) throws Exception
{
URL url = new URL("http://www.google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
InputStreamReader isr;
if(connection.getResponseCode() > 299)
isr = new InputStreamReader(connection.getErrorStream());
else
isr = new InputStreamReader(connection.getInputStream());
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null)
System.out.println(line);
}
}
摘要
HTTP 连接类经常用于处理 HTTP 请求。这个类是 java.net 包的一部分,它扩展了 URLConnection 类。在本教程中,我们学习了这门课的基础知识。我们学习了如何从一个网址创建一个连接。我们学习了如何设置不同的属性和头值。我们还学习了如何读取响应状态、响应头和响应内容。
org.json
简介
原文:https://www.studytonight.com/java-examples/introduction-to-orgjson
JSON 是 JavaScript 对象符号的缩写,是一种广泛用于存储和传输数据的文件格式。它使用人类可读的格式,以键值对或数组的形式存储数据。在本教程中,我们将学习如何在 org.json 库的帮助下在 Java 中使用 JSON。
org.json 图书馆
org.json 库为我们提供了许多使用 json 的类。它也被称为 Java-JSON 库。我们可以使用JSONObject
类来创建 JSON 对象。我们还可以通过使用 JSONArray 类来创建 JSON 数组。它还为 JSON 到其他格式的转换提供了方便的类和方法。
org.json 中的 JSONObject
- JSONObject 用于存储键值对。该键只能是非空字符串,但值可以是任何类型。
- put() 方法用于向 JSONObject 添加键值对。
- 我们可以使用 get(String key) 方法获取一个键对应的值。
- 我们也可以使用 opt(String key) 方法来获取与该键关联的对象。
- 这个类有很多可用的方法,但这些是最常用的。
下面的代码显示了这些方法的工作原理。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
JSONObject jsonObj = new JSONObject();
jsonObj.put("one", 1);
jsonObj.put("two", "2");
jsonObj.put("three", false);
jsonObj.put("four", JSONObject.NULL);
System.out.println("The JSONObject is: " + jsonObj);
System.out.println("get(one): " + jsonObj.get("one"));
System.out.println("get(two): " + jsonObj.get("two"));
System.out.println("get(three): " + jsonObj.get("three"));
System.out.println("get(four): " + jsonObj.get("four"));
}
}
JSON object 为:{“四”:null,“一”:1、“二”:“二”、“三”:false}
get(一):1
get(二):2
get(三):false
get(四):null
使用映射创建 Using 对象
JSONObject 构造器可以采用一个映射实例,它将使用映射中存在的键值对来初始化 JSONObject。
import java.util.HashMap;
import java.util.Map;
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
Map<String, Integer> map = new HashMap<>();
map.put("one", 1);
map.put("two", 2);
map.put("three", 3);
map.put("four", 4);
JSONObject jsonObj = new JSONObject(map);
System.out.print(jsonObj);
}
}
{“四”:4、“一”:1、“二”:2、“三”:3}
使用字符串创建 JSONObject
如果我们有一个有效的 JSON 字符串,那么我们可以使用这个字符串来初始化一个 JSON 对象。JSONObject 构造器可以用从 JSON 字符串中获得的键值对来初始化 JSONObject。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
String jsonStr = "{\"one\":\"1\",\"two\":\"2\",\"three\":\"3\"}";
JSONObject jsonObj = new JSONObject(jsonStr);
System.out.print(jsonObj);
}
}
{“一”:“1”、“二”:“2”、“三”:“3”}
使用 Bean 类创建 JSONObject
我们可以将一个 Java Bean 类对象传递给 JSONObject 构造器,它将使用 Bean 对象中设置的类属性和值创建一个 JSON 对象。
为此,让我们使用下面的 Java Bean 类。
import java.io.Serializable;
public class Student implements Serializable
{
private String name;
private Double gpa;
Student(){}
Student(String s, Double d)
{
this.name = s;
this.gpa = d;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getGpa() {
return gpa;
}
public void setGpa(Double gpa) {
this.gpa = gpa;
}
}
现在,当我们使用这个类的一个实例创建一个 JSONObject 时,我们将使用名称和 GPA 作为键。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
Student student = new Student();
student.setName("Justin");
student.setGpa(8.50);
JSONObject jsonObj = new JSONObject(student);
System.out.print(jsonObj);
}
}
{“姓名”:“贾斯汀”、“GPA”:8.5 }
org.json 中的 JSONArray
- JSONArray 是一个有序的值集合。
- put() 方法用于向数组中添加值。这些值可以是任何类型。
- 我们可以使用 get() 方法通过它们的索引来获取这些值。
- JSONArray 表示为以方括号开始和结束的字符串,包含逗号分隔的值。
让我们使用上面讨论的方法创建一个 JSONArray。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
JSONObject jsonObj = new JSONObject();
jsonObj.put("one", 1);
jsonObj.put("two", "2");
JSONArray jsonArr = new JSONArray();
//Adding values to the JSONArray
jsonArr.put("String");
jsonArr.put(100.0);
jsonArr.put(JSONObject.NULL);
jsonArr.put(jsonObj);
System.out.println(jsonArr);
System.out.println("Element at index 1:" + jsonArr.get(1));
System.out.println("Element at index 3:" + jsonArr.get(3));
}
}
[“String”,100,null,{“one”:1,“two”:“2”}]
索引 1 处的元素:100.0
索引 3 处的元素:{“one”:1,“two”:“2”}
使用字符串创建 JSONArray
JSONArray 构造器可以接受 JSON 字符串来初始化数组。确保传递给构造器的字符串是有效的 JSON 字符串。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
String jsonStr = "[1, \"String\", false]";
JSONArray jsonArr = new JSONArray(jsonStr);
System.out.print(jsonArr);
}
}
【1,“弦”,假】
使用集合创建 JSONArray
我们也可以使用集合来初始化一个 JSONArray。JSONArray 构造器用于实现这一点。
import java.util.ArrayList;
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
ArrayList<String> arrList = new ArrayList<>();
arrList.add("one");
arrList.add("2");
arrList.add("three");
JSONArray jsonArr = new JSONArray(arrList);
System.out.print(jsonArr);
}
}
【“一”、“二”、“三”】
json 组织中的 JSONTokener
JSONTokener 类用于将字符串拆分成单个字符。这个类不常用。我们有其他流行的 Java 方法可以达到同样的结果。这个类被其他类(JSONObject 和 JSONArray)用来解析 JSON 字符串。
让我们尝试使用这个类来拆分字符串。我们将使用 more() 方法来检查 JSONTokener 是否包含更多的字符。我们将使用 next() 方法获取单个字符。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
JSONTokener jsonTokener = new JSONTokener("This is a string.");
while(jsonTokener.more())
System.out.println(jsonTokener.next());
}
}
T
h
I
s
T5】I
s
T8】a
T10】s
T
r
I
n
g
。
org.json 中的逗号分隔列表
org.json 库的逗号分隔列表(CDL)类提供了 JSONObject 或 JSONArray 与逗号分隔文本之间的简单转换方法。我们还需要 JSONTokener 来进行一些转换。
逗号分隔文本中的字符串
我们可以将逗号分隔的字符串转换为 JSONArray,方法是首先使用 JSONTokener,然后使用 CDL 类的row to sonarray()方法。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
String s = "This, is, a, string, .";
JSONTokener jsonTokener = new JSONTokener(s);
JSONArray jsonArrUsingCDL = CDL.rowToJSONArray(jsonTokener);
System.out.print(jsonArrUsingCDL);
}
}
【“这”、“是”、“一”、“串”、“”]
来自 JSONArray 的逗号分隔文本
要将我们的 JSONArray 转换为逗号分隔的字符串,我们可以使用 CDL 类的 rowToString() 方法。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
String s1 = "This, is, a, string, .";
JSONTokener jsonTokener = new JSONTokener(s1);
//String to JSONArray
JSONArray jsonArrUsingCDL = CDL.rowToJSONArray(jsonTokener);
System.out.println("JSON Array: " + jsonArrUsingCDL);
//JSONArray to String
String s2 = CDL.rowToString(jsonArrUsingCDL);
System.out.print("String from JSON Array: " + s2);
}
}
JSON 数组:【“这个”“是”“一个”“字符串”、】】【JSON 数组中的字符串:这是一个字符串。
逗号分隔文本中的 JSONObjects 数组
我们可以将字符串格式化为头(或键)和 JSONObject 值,以创建一个 JSONObjects 数组。我们将使用 CDL 类的 toJSONArray()方法。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
String jsonObjs = "name, gpa, regNo \n" //Headers
+ "Justin, 8.21, 101 \n"//First JSONObject
+ "Jessica, 8.55, 102 \n"; //Second JSONObject
JSONArray jsonArr = CDL.toJSONArray(jsonObjs);
System.out.println("First JSONObject in the JSONArray: " + jsonArr.get(0));
System.out.println("First JSONObject in the JSONArray: " + jsonArr.get(1));
}
}
JSON array 中的第一个 JSON object:{“regNo”:“101”、“name”:“Justin”、“GPA”:“8.21”}
JSON array 中的第一个 JSON object:{“regNo”:“102”、“name”:“Jessica”、“GPA”:“8.55”}
toJSONArray()有一个重载方法,可以将另一个 JSONArray() 作为参数。这个 JSONArray 将包含 JSONObjects 的头(或键)。我们还需要一个包含 JSONObject 值的字符串。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
JSONArray header = new JSONArray();
header.put("Name");
header.put("GPA");
header.put("RegNo");
String jsonObjs = "Justin, 8.21, 101 \n"//First JSONObject
+ "Jessica, 8.55, 102 \n"; //Second JSONObject
JSONArray jsonArr = CDL.toJSONArray(header, jsonObjs);
System.out.println("First JSONObject in the JSONArray: " + jsonArr.get(0));
System.out.println("First JSONObject in the JSONArray: " + jsonArr.get(1));
}
}
JSON array 中的第一个 JSON object:{“RegNo”:“101”、“GPA”:“8.21”、“Name”:“Justin”}
JSON array 中的第一个 JSON object:{“RegNo”:“102”、“GPA”:“8.55”、“Name”:“Jessica”}
org.json 的 Cookie 类
org.json 库包含一个 Cookie 类,可以将 web 浏览器的 cookies 转换为 JSONObjects,并将 JSONObjects 转换回 cookies。
Cookie 字符串中的 JSONObject
我们将使用这个类的to sonobject()来执行转换。确保表示 cookies 的字符串格式正确。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
String cookie = "username = Justin Kan; expires = Thu, 5 Jul 2021 12:00:00 UTC; path = /\"";
JSONObject jsonObjCookie = Cookie.toJSONObject(cookie);
System.out.println(jsonObjCookie);
}
}
{“路径”:“/\”、“到期时间”:“世界协调时 2021 年 7 月 5 日星期四 12:00:00”、“名称”:“用户名”、“值”:“Justin Kan”}
JSONObject 中的 Cookie 字符串
这个类的 toString() 方法可以将包含 cookie 的 JSONObject 转换成字符串。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
//String cookie to JSONObject
String cookie = "username = Justin Kan; expires = Thu, 5 Jul 2021 12:00:00 UTC; path = /\"";
JSONObject jsonObjCookie = Cookie.toJSONObject(cookie);
//JSONObject to String cookie
String cookieFromJsonObj = Cookie.toString(jsonObjCookie);
System.out.print(cookieFromJsonObj);
}
}
用户名= Justin Kan 过期时间=世界协调时 2021 年 7 月 5 日星期四 12:00:00;路径=/”
组织类
org.json 库的 HTTP 类用于 HTTP 头和 JSONObjects 之间的转换。
HTTP 头字符串中的 JSONObject
就像 Cookie 类一样,HTTP 类也包含一个to sonobject()方法。这用于将一个 HTTP 头字符串转换为一个 JSONObject。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
String httpString = "POST \"http://www.somesite.com/\" HTTP/1.1";
JSONObject httpJsonObj = HTTP.toJSONObject(httpString);
System.out.print("HTTP JSON Object: " + httpJsonObj);
}
}
HTTP JSON 对象:{“请求-URI”:“HTTP://www . somesite . com/”、“方法”:“POST”、“HTTP-Version”:“HTTP/1.1”}
来自 from 对象的 HTTP 头字符串
HTTP 类还包含 toString() 方法,该方法可以将包含 HTTP 头的 JSONObject 转换为字符串。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
JSONObject httpJsonObj = new JSONObject();
httpJsonObj.put("Method", "POST");
httpJsonObj.put("Request-URI", "http://www.somesite.com/");
httpJsonObj.put("HTTP-Version", "HTTP/1.1");
System.out.println("HTTP JSON Object: " + httpJsonObj);
String stringFromHttpJsonObj = HTTP.toString(httpJsonObj);
System.out.println("String from HTTP JSON Object: " + stringFromHttpJsonObj);
}
}
HTTP JSON 对象:{“Request-URI”:“HTTP://www . somesite . com/”、“Method”:“POST”、“HTTP-Version”:“HTTP/1.1”}
字符串来自 HTTP JSON 对象:POST“HTTP://www . somesite . com/”HTTP/1.1
jsoneexception
在使用 org.json 库时,我们会经常遇到 JSONException。此异常还包含一条描述错误背后原因的消息。让我们看一看引发此错误的几个场景。
当我们使用无效密钥时,JSONException
如果我们尝试使用 get()方法获取一个 JSONObject 值,但该键不存在,将会返回此错误。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
JSONObject jsonObj = new JSONObject();
jsonObj.put("one", 1);
jsonObj.put("two", "2");
jsonObj.put("three", false);
jsonObj.put("four", JSONObject.NULL);
System.out.println(jsonObj.get("five"));//Invalid Key
}
}
线程“main”org . JSON . jsonexception 中出现异常:未找到 JSONObject[“五”]。
在 org . JSON . JSON object . get(JSON object . Java:516)
在 Demo.main(Demo.java:13)
当我们使用无效的 JSON 字符串时,会出现 JSON 异常
我们学习了一些不同的方法,在这些方法中,我们将 JSON 字符串用于不同的目的。但是,如果字符串不是有效的 JSON 格式,那么我们将得到 JSONException。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
String jsonStr = "one : 1, two: 2, three: 3";
JSONObject jsonObj = new JSONObject(jsonStr);
System.out.print(jsonObj);
}
}
线程“main”中的异常 org.json.JSONException:一个 JSONObject 文本必须在 org . JSON . jsontkener . syntaxerror(jsontkener . Java:413)
在 org . JSON . JSON object .
在 org . JSON . JSON object .
在 Demo.main(Demo.java:9)
当我们使用无效的 JSONArray 索引时,出现 JSONException
通常,如果我们试图使用一个无效的索引,我们会得到一个 ArrayIndexOutOfBounds 异常。对于 JSONArrays,我们将获得 JSONException。
import org.json.*;
public class Demo
{
public static void main(String[] args) throws JSONException
{
JSONArray jsonArr = new JSONArray();
//Adding values to the JSONArray
jsonArr.put("String");
jsonArr.put(100.0);
jsonArr.put(JSONObject.NULL);
System.out.println("Element at index 10:" + jsonArr.get(10));//Invalid Index
}
}
线程“main”org . JSON . jsonexception 中出现异常:未找到 JSONArray[10]。
在 org . JSON . jsonarray . get(jsonarray . Java:247)
在 Demo.main(Demo.java:13)
摘要
json.org 是一个流行的 Java 包,用于与 JSON 一起工作。在本教程中,我们看了这个包的一些最重要的类和方法。我们还了解了 JSONException,这个包的所有类都使用它。
Java ExecutorService
原文:https://www.studytonight.com/java-examples/java-executorservice
ExecutorService
是用于在后台并发执行异步任务的接口。ExecutorService 维护一个线程池,并将任务分配给这些线程。当没有空闲线程可用时,它还维护一个队列来存储任务。
在本教程中,我们将学习如何在 Java 中使用 ExecutorService。
创建执行器服务
我们可以使用 Executors 类的三种不同工厂方法来创建一个 ExecutorService。
- NewsingLeadExecutor()方法创建一个具有单线程的执行器。
- NewFixedThreadPool(int poolSize)方法用 PoolSize 提到的固定线程数创建一个执行器。
- newScheduledThreadPool(int pool size)方法创建一个具有上述线程池大小的执行器,该执行器可以在给定延迟后调度任务。它还可以定期执行任务。
下面的代码演示了这些方法的工作原理。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo
{
public static void main(String[] args) throws InterruptedException
{
Runnable task = new Runnable() {
public void run() {
System.out.println("Performing a Task...");
}
};
ExecutorService exeService1 = Executors.newSingleThreadExecutor();
exeService1.execute(task);
ExecutorService exeService2 = Executors.newFixedThreadPool(5);
exeService2.execute(task);
ExecutorService exeService3 = Executors.newScheduledThreadPool(5);
exeService3.execute(task);
}
}
执行任务...
执行任务...
执行任务...
我们也可以选择一个执行器服务实现,比如线程池执行器类或者调度线程池执行器类。
将任务分配给执行器服务
我们可以使用 execute()、submit()、invokeAny()或 invokeAll()方法来使用 ExecutorService 分配和执行任务。
执行()方法
execute()方法将一个 Runnable 任务作为参数,并异步执行它。它不会返回任何内容,我们也无法检查任务状态。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo
{
public static void main(String[] args) throws InterruptedException
{
Runnable task = new Runnable() {
public void run() {
System.out.println("Performing a Task...");
}
};
ExecutorService exeService = Executors.newSingleThreadExecutor();
exeService.execute(task);
}
}
执行任务...
提交()方法
submit()方法可以执行一个 Runnable 或 Callable 任务。与 execute()不同,它将以 Future 对象的形式返回任务状态。我们可以在 Future 对象上使用 get()方法来检查任务状态。如果可运行任务成功执行,并且调用()方法的结果为可调用任务,get()方法将返回 null。
对于可运行任务:
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Demo
{
public static void main(String[] args) throws InterruptedException, ExecutionException
{
Runnable task = new Runnable() {
public void run() {
System.out.println("Performing a Runnable Task...");
}
};
ExecutorService exeService = Executors.newSingleThreadExecutor();
Future status = exeService.submit(task);
System.out.println("Status: " + status.get());
}
}
执行可运行任务...
状态:空
对于可调用任务
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Demo
{
public static void main(String[] args) throws InterruptedException, ExecutionException
{
Callable task = new Callable() {
public Object call() throws Exception{
System.out.println("Performing a Callable Task...");
return "Callable Task Performed";
}
};
ExecutorService exeService = Executors.newSingleThreadExecutor();
Future status = exeService.submit(task);
System.out.println("Status: " + status.get());
}
}
执行可调用任务...
状态:可调用任务已执行
invokeAny()方法
invokeAny()方法获取一组可调用任务并执行它们。它将返回任何成功执行的任务的状态。状态通过使用未来对象返回。
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo
{
public static void main(String[] args) throws InterruptedException, ExecutionException
{
//Creating callable tasks
Callable task1 = new Callable() {
public Object call() throws Exception{
System.out.println("Performing a Callable Task1...");
return "Callable Task1 Performed";
}
};
Callable task2 = new Callable() {
public Object call() throws Exception{
System.out.println("Performing a Callable Task2...");
return "Callable Task2 Performed";
}
};
Callable task3 = new Callable() {
public Object call() throws Exception{
System.out.println("Performing a Callable Task3...");
return "Callable Task3 Performed";
}
};
//Creating a list of callable tasks
ArrayList<Callable<String>> callableTasks = new ArrayList<>();
callableTasks.add(task1);
callableTasks.add(task2);
callableTasks.add(task3);
ExecutorService exeService = Executors.newSingleThreadExecutor();
String status = exeService.invokeAny(callableTasks);
System.out.println("Status: " + status);
}
}
执行可调用任务 1...
执行可调用任务 2...
执行可调用任务 3...
状态:可调用任务 1 已执行
invokeAll()方法还获取可调用任务的集合并执行它们。但是与 invokeAny()方法不同,它将返回一个包含所有已执行任务状态的列表。状态通过使用未来对象返回。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Demo
{
public static void main(String[] args) throws InterruptedException, ExecutionException
{
//Creating callable tasks
Callable task1 = new Callable() {
public Object call() throws Exception{
return "Callable Task1 Performed";
}
};
Callable task2 = new Callable() {
public Object call() throws Exception{
return "Callable Task2 Performed";
}
};
Callable task3 = new Callable() {
public Object call() throws Exception{
return "Callable Task3 Performed";
}
};
//Creating a list of callable tasks
ArrayList<Callable<String>> callableTasks = new ArrayList<>();
callableTasks.add(task1);
callableTasks.add(task2);
callableTasks.add(task3);
ExecutorService exeService = Executors.newSingleThreadExecutor();
List<Future<String>> status = exeService.invokeAll(callableTasks);
//Printing the status
for(Future f : status)
System.out.println(f.get());
}
}
可调用任务 1 已执行
可调用任务 2 已执行
可调用任务 3 已执行
关闭执行器服务
当 ExecutorService 没有更多任务要执行时,它不会自动关闭。它将继续等待未来可能出现的新任务。执行器服务内部的活动线程将继续运行,并且不允许 JVM 停止。
关机()方法
我们可以使用 shutdown()方法来停止 ExecutorService。此方法将阻止 ExecutorService 接受新任务。当所有现有任务完成后,执行器服务将关闭。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Demo
{
public static void main(String[] args) throws InterruptedException
{
Runnable task1 = new Runnable() {
public void run() {
System.out.println("Performing a Task1...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.print(e);
}
}
};
Runnable task2 = new Runnable() {
public void run() {
System.out.println("Performing a Task2...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.print(e);
}
}
};
Runnable task3 = new Runnable() {
public void run() {
System.out.println("Performing a Task3...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.print(e);
}
}
};
ExecutorService exeService = Executors.newSingleThreadExecutor();
exeService.execute(task1);
exeService.execute(task2);
exeService.execute(task3);
exeService.shutdown();//All Tasks will be executed
}
}
执行任务 1...
执行任务 2...
执行任务 3...
关闭现在()方法
shutdownNow()方法用于立即停止正在运行的任务。这种方法会尽最大努力停止所有正在运行的任务,但不能保证。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Demo
{
public static void main(String[] args) throws InterruptedException
{
Runnable task1 = new Runnable() {
public void run() {
System.out.println("Performing a Task1...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.print(e);
}
}
};
Runnable task2 = new Runnable() {
public void run() {
System.out.println("Performing a Task2...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.print(e);
}
}
};
Runnable task3 = new Runnable() {
public void run() {
System.out.println("Performing a Task3...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.print(e);
}
}
};
ExecutorService exeService = Executors.newSingleThreadExecutor();
exeService.execute(task1);
exeService.execute(task2);
exeService.execute(task3);
exeService.shutdownNow();//Only a few Tasks will be executed
}
}
执行任务 1...
java.lang .断续异常:睡眠中断
预警终端()方法
关闭执行器服务的推荐方法是将 shut down()和 shutdownNow()方法与 awaitTermination()方法一起使用。
首先,ExecutorService 将停止使用 shutdown()或 shutdownNow()方法接受新任务。然后,awaitTermination()要么等待所有任务完成执行,要么等待超时发生,无论哪个先发生。awaitTermination()方法的常见实现如下所示。
public static void shutdownUsingAwaitTermination(ExecutorService exeService)
{
exeService.shutdown();
try {
//Wait till timeout for existing tasks to end
if(!exeService.awaitTermination(10, TimeUnit.SECONDS))//Wait till timeout for existing tasks to end
exeService.shutdownNow();//Cancel executing tasks
if(!exeService.awaitTermination(20, TimeUnit.SECONDS))//Wait for the tasks to be cancelled
System.err.println("ExecutorService did not terminate");
}
catch(Exception e){
exeService.shutdownNow();
}
}
调度执行服务接口
ScheduledExecutorService 可以在一定延迟后运行任务。它还可以以固定的速率或在固定的延迟后重复运行任务。
让我们在初始延迟 5 秒后执行一个可运行的任务。我们将为此使用 schedule() 命令。
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Demo
{
public static void main(String[] args) throws InterruptedException
{
Runnable runnableTask = new Runnable() {
public void run()
{
System.out.println("Task Performed At: " + new Date());
}
};
System.out.println("Current Date and Time: " + new Date());
long delay = 5;
ScheduledExecutorService exeService = Executors.newSingleThreadScheduledExecutor();
exeService.schedule(runnableTask, delay, TimeUnit.SECONDS);
}
}
当前日期和时间:2021 年 8 月 05 日星期四 11:22:12 IST
任务执行时间:2021 年 8 月 05 日星期四 11:22:17 IST
让我们每 5 秒钟重复一次某个任务。为此使用 scheduleAtFixedRate() 方法。请注意,重复周期将根据绝对时间工作。下一个任务的开始不受上一个任务终止时间的影响。
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Demo
{
public static void main(String[] args) throws InterruptedException
{
Runnable runnableTask = new Runnable() {
public void run()
{
System.out.println("Task Performed At: " + new Date());
}
};
System.out.println("Current Date and Time: " + new Date());
long delay = 1;
long repeatPeriod = 5;
ScheduledExecutorService exeService = Executors.newSingleThreadScheduledExecutor();
exeService.scheduleAtFixedRate(runnableTask, delay, repeatPeriod, TimeUnit.SECONDS);
}
}
当前日期和时间:2021 年 8 月 05 日星期四 11:23:29 IST
任务执行时间:2021 年 8 月 05 日星期四 11:23:30 IST
任务执行时间:2021 年 8 月 05 日星期四 11:23:35 IST
任务执行时间:2021 年 8 月 05 日星期四 11:23:40 IST
任务执行时间:2021 年 8 月 05 日星期四 11:23:45 IST
如果我们想在一个任务的终止和下一个任务的开始之间引入一个固定的延迟,那么我们将使用 scheduleWithFixedDelay() 方法。
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Demo
{
public static void main(String[] args) throws InterruptedException
{
Runnable runnableTask = new Runnable() {
public void run()
{
System.out.println("Task Performed At: " + new Date());
}
};
System.out.println("Current Date and Time: " + new Date());
long delay = 1;
long repeatPeriod = 5;
ScheduledExecutorService exeService = Executors.newSingleThreadScheduledExecutor();
exeService.scheduleWithFixedDelay(runnableTask, delay, repeatPeriod, TimeUnit.SECONDS);
}
}
当前日期和时间:2021 年 8 月 05 日星期四 11:24:23 IST
任务执行时间:2021 年 8 月 05 日星期四 11:24:24 IST
任务执行时间:2021 年 8 月 05 日星期四 11:24:29 IST
任务执行时间:2021 年 8 月 05 日星期四 11:24:34 IST
摘要
Java 中的 ExecutorService 用于异步执行任务。初始化 ExecutorService 有几种不同的方法。在使用 newFixedThreadPool()方法初始化 ExecutorService 时,我们应该始终使用适当的池大小。较小的池大小会增加任务的等待时间,而较大的池大小会导致性能开销。
我们还可以使用不同的方法来执行任务,如 execute()或 submit()。我们也应该谨慎使用未来界面。尝试对取消的任务使用 get()方法将导致取消异常。在 Future 接口的 get()方法中使用超时也是一个好主意。请记住在使用后关闭执行器服务。
Java 定时器和定时器任务
原文:https://www.studytonight.com/java-examples/java-timer-and-timertask
Java 中的计时器用于调度任务。时间任务是我们想要执行的任务。我们可以在 TimerTask 的帮助下定义一个任务,并使用 Timer 对其进行调度。java.util.Timer
类使用后台线程来调度任务。
TimerTask
也是 java.util 的一部分,是一个实现 Runnable
接口的抽象类。我们需要覆盖 run() 方法来定义任务。
在本教程中,我们将学习如何使用计时器安排时间任务。
延迟后计划任务
Timer 类的 schedule() 方法用于通过使用线程来调度未来的任务。这个方法需要一个 TimerTask 实例和一个延迟,之后我们要执行任务。
如果我们想立即执行任务,那么我们可以传递零作为第二个参数。请注意,延迟以毫秒为单位。
import java.util.Timer;
import java.util.TimerTask;
public class Demo
{
public static void main(String[] args)
{
TimerTask t = new TimerTask() {
public void run()
{
System.out.println("Performing the task(takes 2000ms)");
try {
Thread.sleep(2000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Task Completed");
}
};
Timer timer = new Timer();
timer.schedule(t, 1000);//Scheduling the task after a delay of 1000ms
}
}
执行任务(耗时 2000 毫秒)
任务完成
我们也可以新建一个类,扩展TimerTask
类。请注意,多个定时器任务可以共享一个定时器,因为定时器类是线程安全的,不需要任何外部同步。
让我们创建两个用户定义类的实例,并使用一个计时器对它们进行调度。
import java.util.Timer;
import java.util.TimerTask;
class AdditionTask extends TimerTask
{
int a;
int b;
AdditionTask(int i, int j)
{
this.a = i;
this.b = j;
}
@Override
public void run()
{
System.out.println("Performing the Addition(takes 2000ms)");
try {
Thread.sleep(2000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("The sum is: " + (a+b));
}
}
public class Demo
{
public static void main(String[] args)
{
AdditionTask t1 = new AdditionTask(10, 20);
AdditionTask t2 = new AdditionTask(40, 60);
Timer timer = new Timer();
timer.schedule(t1, 0);//Scheduling the first task without any delay
timer.schedule(t2, 5000);//Scheduling the second task after a delay of 5000ms
}
}
执行加法(耗时 2000 毫秒)
总和为:30
执行加法(耗时 2000 毫秒)
总和为:100
另一件需要注意的事情是,即使在任务完成后,我们的程序也会继续运行。要终止我们的程序,我们可以在 run()方法中使用 System.exit(0) 。
@Override
public void run()
{
System.out.println("Performing the Addition(takes 2000ms)");
try {
Thread.sleep(2000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("The sum is: " + (a+b));
System.exit(0);
}
按日期和时间安排任务
schedule()方法可以采用一个日期对象来代替延迟。计时器将在该日期和时间安排任务。下面的代码演示了这一点。
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
class AdditionTask extends TimerTask
{
int a;
int b;
AdditionTask(int i, int j)
{
this.a = i;
this.b = j;
}
@Override
public void run()
{
System.out.println("Performing the task on: " + new Date());
System.out.println("The sum is: " + (a+b));
}
}
public class Demo
{
public static void main(String[] args)
{
Date date = new Date();
System.out.println("Current Date: " + date);
date.setTime(date.getTime() + 5000);//increasing the time by 5000ms
AdditionTask t = new AdditionTask(10, 20);
Timer timer = new Timer();
timer.schedule(t, date);//Scheduling the task on the given date
}
}
当前日期:2021 年 8 月 04 日星期三 19:19:32 IST
执行任务时间:2021 年 8 月 04 日星期三 19:19:37 IST
总计:30
安排可重复的任务
我们可以将第三个参数传递给 schedule()方法,以便在某个时间段后重复该任务。第三个参数表示任务两次出现之间的时间间隔(毫秒)。
该时间间隔表示前一任务发生后的固定延迟。时间间隔是相对的,因为它是在前一个任务完成后计算的。
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
class AdditionTask extends TimerTask
{
int a;
int b;
AdditionTask(int i, int j)
{
this.a = i;
this.b = j;
}
@Override
public void run()
{
System.out.println("Performing the task on: " + new Date());
System.out.println("The sum is: " + (a+b));
}
}
public class Demo
{
public static void main(String[] args)
{
AdditionTask t = new AdditionTask(10, 20);
long delay = 100;
long repeatPeriod = 1000;
Timer timer = new Timer();
timer.schedule(t, delay, repeatPeriod);//Repeat task every 1000ms
}
}
执行任务时间:2021 年 8 月 05 日星期四 08:55:19 IST
执行任务时间:2021 年 8 月 05 日星期四 08:55:20 IST
执行任务时间:2021 年 8 月 05 日星期四 08:55:21 T4
执行任务时间:2021 年 8 月 05 日星期四 08:55:22
我们也可以使用 scheduleAtFixedRate() 方法以固定的速率调度任务。这将使用绝对时间来安排任务。如果其中一个任务被延迟,这个方法不会影响其他任务。
在这种情况下,时间差距是绝对的,不会受到前一个任务完成时间的影响。
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
class AdditionTask extends TimerTask
{
int a;
int b;
AdditionTask(int i, int j)
{
this.a = i;
this.b = j;
}
@Override
public void run()
{
System.out.println("Performing the task on: " + new Date());
System.out.println("The sum is: " + (a+b));
}
}
public class Demo
{
public static void main(String[] args)
{
AdditionTask t = new AdditionTask(10, 20);
long delay = 100;
long repeatPeriod = 1000;
Timer timer = new Timer();
timer.scheduleAtFixedRate(t, delay, repeatPeriod);//Repeat task every 1000ms
}
}
执行任务时间:2021 年 8 月 04 日星期三 19:21:46 IST
执行任务时间:2021 年 8 月 04 日星期三 19:21:47 IST
执行任务时间:2021 年 8 月 04 日星期三 19:21:48 IST
执行任务时间:2021 年 8 月 04 日星期三 19:21:49 IST
我们可以使用这些方法(有适当的重复周期)每分钟、每小时、每天执行一项任务,等等。
取消任务
我们可以在 TimerTasks 的 run()方法中使用 cancel() 方法,在一次执行后取消它们。
在下面的代码中,我们安排了一个每秒重复一次的任务。但是由于 cancel()方法,任务将只执行一次。
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
class AdditionTask extends TimerTask
{
int a;
int b;
AdditionTask(int i, int j)
{
this.a = i;
this.b = j;
}
@Override
public void run()
{
System.out.println("Performing the task on: " + new Date());
System.out.println("The sum is: " + (a+b));
cancel();//cancel after one execution
}
}
public class Demo
{
public static void main(String[] args)
{
AdditionTask t = new AdditionTask(10, 20);
Timer timer = new Timer();
timer.scheduleAtFixedRate(t, 1000, 1000);//Repeat task every 1000ms
}
}
执行任务时间:2021 年 8 月 04 日星期三 19:24:10 IST
总计:30
我们也可以使用 Timer.cancel() 方法取消一个预定的任务。我们可以让线程休眠几秒钟,至少执行一次任务。
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
class AdditionTask extends TimerTask
{
int a;
int b;
AdditionTask(int i, int j)
{
this.a = i;
this.b = j;
}
@Override
public void run()
{
System.out.println("Performing the task on: " + new Date());
System.out.println("The sum is: " + (a+b));
}
}
public class Demo
{
public static void main(String[] args) throws InterruptedException
{
AdditionTask t = new AdditionTask(10, 20);
Timer timer = new Timer();
timer.scheduleAtFixedRate(t, 0, 1000);//Start after a delay of 1000 and Repeat task every 1000ms
Thread.sleep(1);
timer.cancel();//Canceling the timer
}
}
执行任务时间:2021 年 8 月 04 日星期三 19:26:44 IST
总计:30
执行器服务
我们还可以使用执行器服务来安排时间任务。
import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
class AdditionTask extends TimerTask
{
int a;
int b;
AdditionTask(int i, int j)
{
this.a = i;
this.b = j;
}
@Override
public void run()
{
System.out.println("Performing the task on: " + new Date());
System.out.println("The sum is: " + (a+b));
}
}
public class Demo
{
public static void main(String[] args) throws InterruptedException
{
AdditionTask at = new AdditionTask(10, 20);
long delay = 1;
long repeatPeriod = 2;
ScheduledExecutorService exe = Executors.newSingleThreadScheduledExecutor();
exe.scheduleAtFixedRate(at, delay, repeatPeriod, TimeUnit.SECONDS);
}
}
执行任务时间:2021 年 8 月 04 日星期三 19:33:21 IST
执行任务时间:2021 年 8 月 04 日星期三 19:33:23 IST
执行任务时间:2021 年 8 月 04 日星期三 19:33:25 IST
执行任务时间:2021 年 8 月 04 日星期三 19:33:27 IST
它们与 Timer 类非常相似,但有一些显著的区别。以下几点总结了计时器和执行器服务之间的主要区别。
- 计时器受系统时钟变化的影响,但 ExecutorService 不受影响。
- 计时器只能有一个线程,但是执行器服务可以使用多个线程。
- 计时器线程中的运行时异常将取消所有剩余的任务。异常不会影响执行器服务。
摘要
定时器任务通过使用定时器类进行调度。Timer 类包含用于调度任务的重载 schedule()方法。我们也可以使用 schedule()方法在特定的时间间隔后重复任务。本教程中讨论的重载 schedule()方法总结如下。
- 计划(TimerTask t,长延迟)用于在延迟后计划任务。
- 计划(时间任务,日期 d)用于将任务安排在特定的日期和时间。
- 计划(时间任务、长延迟、长重复周期)用于在初始延迟后计划可重复的任务。重复周期结束后,任务会重复执行。
- 计划(时间任务 t,日期 d,长重复周期)将在重复周期后重复任务,但任务将在提到的日期开始。
Java JSON 库
原文:https://www.studytonight.com/java-examples/java-json-libraries
JSON 代表 JavaScript 对象符号,是一种流行的文件格式,用于存储和传输数据对象。有很多外部库可以让我们在 Java 中使用 JSON。
最受欢迎的有 Jaskson、Gson、Genson 和 json-io。
在本教程中,我们将学习这些库的基础知识。我们将看到一些例子来理解如何使用这些库将对象序列化和反序列化为 JSON。
我们将在序列化和反序列化示例中使用以下类。
class ClassA
{
private String field1;
private Double field2;
//Constructors
ClassA()
{}
ClassA(String field1, Double field2)
{
this.field1 = field1;
this.field2 = field2;
}
//getters and setters
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public Double getField2() {
return field2;
}
public void setField2(Double field2) {
this.field2 = field2;
}
}
JavaJaskson
Jackson 是一个流行的 Java JSON 处理库。这个库由三个核心包组成——流、数据绑定和注释。要在您的项目中使用这一点,请将 Jaskson 的以下 Maven 依赖项添加到 pom.xml 文件中。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
Jackson 提供了ObjectMapper
类将对象序列化为 JSON 字符串,并将 JSON 字符串反序列化为对象。
这个类的 writeValueAsString() 方法可以将对象序列化为 JSON 字符串。类似地, readValue() 方法将字符串反序列化回对象。下面的代码演示了这一点。
public class Demo
{
public static void main(String[] args) throws IOException
{
ClassA classAObj = new ClassA("Demo", 20.0);//object
ObjectMapper objMapper = new ObjectMapper();
String jsonString = objMapper.writeValueAsString(classAObj);//Generating JSON String from object
System.out.println("String: " + jsonString);
ClassA objFromStr = objMapper.readValue(jsonString, ClassA.class);//Getting object from the JSON string
System.out.print("Object: " + objFromStr.getField1() + " " + objFromStr.getField2());
}
}
字符串:{“field 1”:“Demo”,“field 2”:20.0 }
对象:Demo 20.0
Java json
Gson 是谷歌开发的开源库。Gson 易于使用和理解。与其他一些库不同,Gson 为 Java 中的泛型提供了广泛的支持。Gson 的 Maven 依赖关系如下所示。您可以使用这些到项目的 pom.xml 文件中。
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
我们可以使用 toJson() 和 fromJson() 方法对对象进行序列化和反序列化。下面的代码演示了这一点。
public class Demo
{
public static void main(String[] args)
{
ClassA obj = new ClassA("Demo", 20.0);
Gson gson = new Gson();
String jsonStrFromObj = gson.toJson(obj);//Object to JSON String
System.out.println("String: " + jsonStrFromObj);
ClassA objFromJsonStr = gson.fromJson(jsonStrFromObj, ClassA.class);//JSON String to Object
System.out.print("Object: " + objFromJsonStr.getField1() + " " + objFromJsonStr.getField2());
}
}
字符串:{“field 1”:“Demo”,“field 2”:20.0 }
对象:Demo 20.0
Java genson(Java genson)
Genson 库提供了简单的序列化()和反序列化()方法,用于对象和 JSON 之间的 conJavversion。Genson 库还为泛型和多态类型以及不提供默认构造器的不可变对象提供了完整的支持。我们可以使用下面的 Maven 依赖项或者从官方网站下载 Jenson jar 文件。
<dependency>
<groupId>com.owlike</groupId>
<artifactId>genson</artifactId>
<version>${genson.version}</version>
</dependency>
下面的代码演示了 serialize()和 serialize()方法的工作原理。
public class Demo
{
public static void main(String[] args)
{
ClassA obj = new ClassA("Demo", 20.0);
Genson genson = new Genson();
String jsonStrFromObj = genson.serialize(obj);//Serializing object to JSON String
System.out.println("String: " + jsonStrFromObj);
ClassA objFromJsonStr = genson.deserialize(jsonStrFromObj, ClassA.class);//Deserializing JSON String to Object
System.out.print("Object: " + objFromJsonStr.getField1() + " " + objFromJsonStr.getField2());
}
}
字符串:{“field 1”:“Demo”,“field 2”:20.0 }
对象:Demo 20.0
Java Json-io
Json-io 是另一个流行的用于 Json 处理的库。它包含两个主要的类 JsonReader 和 JsonWriter。
我们可以使用 JsonWriter 的 objectToJson() 方法将一个对象序列化为 Json 字符串。同样,我们可以使用 JsonReader 类的 jsonToJava() 方法将 JSON 字符串反序列化为对象。
请注意,类型信息也包含在 JSON 字符串中,以告诉 JsonReader 要实例化哪个类。反序列化时,我们还需要显式强制转换。
马文依赖:
<dependency>
<groupId>com.cedarsoftware</groupId>
<artifactId>json-io</artifactId>
<version>${json-io.version}</version>
</dependency>
下面的代码演示了 JsonWriter 和 JsonReader 的工作原理。
public class Demo
{
public static void main(String[] args)
{
ClassA obj = new ClassA("Demo", 20.0);
String jsonStrFromObj = JsonWriter.objectToJson(obj);//Object to JSON String
System.out.println("String: " + jsonStrFromObj);
ClassA objFromJsonStr = (ClassA) JsonReader.jsonToJava(jsonStrFromObj);//JSON String to Object
System.out.print("Object: " + objFromJsonStr.getField1() + " " + objFromJsonStr.getField2());
}
}
字符串:{“@ type”:“class a”、“field 1”:“Demo”、“field 2”:20.0 }
对象:Demo 20.0
摘要
JSON 是一种广泛使用的对象格式。有很多外部库可以用来处理 Java 中的 JSON。在本教程中,我们学习了 Jaskson 库、Gson 库、Genson 库和 Json-io 库的基础知识。我们还看到了所有这些库的序列化和反序列化的例子。
Java Math.pow()
方法
原文:https://www.studytonight.com/java-examples/java-math-pow-method
pow()
法(幂的缩写)是用来求一个数的幂与另一个数的幂的乘积。它是java.lang package
的 Math
班的一部分。它返回一个双数值。
如果我们想将输出转换成其他类型,就需要显式转换。该方法的一般签名如下所示。
public static double pow(double base, double power)
示例:Java pow()
方法
让我们看几个例子来了解它的工作原理。
import java.lang.Math;
public class PowDemo
{
public static void main(String[] args)
{
double d1 = Math.pow(3, 5);
double d2 = Math.pow(3.5, 1.5);
int i = (int) Math.pow(3.5, 1.5);//Casting is required for int type
System.out.println("3 raised to the power 5: " + d1);
System.out.println("3.5 raised to the power 1.5: " + d2);
System.out.print("3.5 raised to the power 1.5(for int type): " + i);
}
}
3 升至 5 次方:243.0
3.5 升至 1.5 次方:6.547900426854397
3.5 升至 1.5 次方(对于 int 型):6
我们也可以用它来求数字的平方根或立方根。
import java.lang.Math;
public class PowDemo
{
public static void main(String[] args)
{
double squareRoot = Math.pow(16, 0.5);
double cubeRoot = Math.pow(27, (1.0 / 3));
System.out.println("Square root of 16 is: " + squareRoot);
System.out.print("Cube root of 27 is: " + cubeRoot);
}
}
16 的平方根是:4.0
27 的立方根是:3.0
幂()方法的特例
有几个特例值得一提。
- 如果第二个参数(幂)为正或负零,则返回 1.0。
- 如果第二个参数是 1.0,那么它只返回第一个参数。
- 如果第二个参数是 NaN(不是数字),那么它返回 NaN。
- 如果第一个参数是 NaN,第二个参数是非零的,那么它返回 NaN。
- 如果第一个参数是 NaN,但是第二个参数是零,那么它返回 1。
import java.lang.Math;
public class PowDemo
{
public static void main(String[] args)
{
System.out.println("When Second parameter is zero:");
System.out.println(Math.pow(5.0, 0.0));
System.out.println(Math.pow(5.0, -0.0));
System.out.println("When Second parameter is one:");
System.out.println(Math.pow(5.0, 1));
System.out.println("When Second parameter is NaN:");
System.out.println(Math.pow(5.0, Double.NaN));
System.out.println("When first parameter is NaN and second parameter is non-zero:");
System.out.println(Math.pow(Double.NaN, 14));
System.out.println("When first parameter is NaN and second parameter is zero:");
System.out.println(Math.pow(Double.NaN, 0));
}
}
当第二个参数为零时:
1.0
1.0
当第二个参数为 1 时:
5.0
当第二个参数为 NaN 时:
NaN
当第一个参数为 NaN 且第二个参数为非零时:
NaN
当第一个参数为 NaN 且第二个参数为零时:
1.0
还有一些特殊情况。简单的指数数学用于理解输出。例如,我们知道-1 的平方根不是实数。如果我们尝试用 pow()做这个,我们应该得到 NaN 值。
import java.lang.Math;
public class PowDemo
{
public static void main(String[] args)
{
System.out.print("Square root of -1: " + Math.pow(-1, 0.5));
}
}
1 的平方根:NaN
我们也知道,一个正的值提升到无穷大,就会趋向于正无穷大。正值,当上升到负无穷大时,趋向于零。pow()方法也复制了这一点。
import java.lang.Math;
public class PowDemo
{
public static void main(String[] args)
{
System.out.println("Positive Value raised to Infinity: " + Math.pow(5, Double.POSITIVE_INFINITY));
System.out.print("Positive Value raised to Negative Infinity: " + Math.pow(5, Double.NEGATIVE_INFINITY));
}
}
正值升至无穷大:无穷大
正值升至负无穷大:0.0
摘要
在这个简短的教程中,我们学习了如何使用java.lang.Math
类的pow()
方法将一个数提升到给定的幂。我们还研究了使用这种方法时可能出现的一些特殊情况。
Java 等待和通知
原文:https://www.studytonight.com/java-examples/java-wait-and-notify
多线程是同时运行多个线程的过程。多线程提高了我们代码的效率,因为多个线程将问题分开,同时处理较小的部分。然而,多个线程可能需要访问一个公共资源。
在这个公共资源上使用锁来避免并行修改。当线程没有同步到使用这个锁时,就会出现不一致。在 Java 中wait()
和notify()
方法用于线程通信和同步。
让我们更多地了解这些方法。
Java 等待()方法
Java 中的Object
类有一个最终的wait()
方法。它用于暂停线程的执行。它还会使线程放弃它的锁,以便其他线程可以访问临界区。代码中修改共享资源的部分称为临界区。
此方法有三个重载签名。
- 等待()
- 等待(长时间超时)
- 等待(长超时,整数纳秒)
如果我们指定超时持续时间,那么线程将在超时后自动唤醒。如果没有提到超时,那么线程必须等待其他线程对其调用 notify。
使用wait()
方法进行同步的一般语法如下所示。
synchronized(object)
{
while(condition is false)
{
object.wait();
}
//do the task
}
Java notify()方法
notify()
方法也属于 Object 类。此方法用于唤醒等待的线程。如果多个线程正在等待,那么随机选择的线程将被唤醒。
请注意,此方法不会使调用(或通知)线程放弃其锁。
Java notifyAll()方法
notifyAll()方法与 notify()方法非常相似,但是它将唤醒所有等待的线程,而不是只唤醒一个线程。
为什么 wait()被包含在 while 循环中?
wait()
方法应该包含在 while 循环中,因为线程可以在没有notify()
调用的情况下被唤醒。这被称为虚假唤醒。while 循环的另一个原因是一个邪恶的线程可能会调用 notifyAll()并唤醒所有等待的线程。
线程需要检查条件,如果条件不满足,那么它们应该继续等待。
例子:生产者和消费者问题
让我们通过一个例子来了解如何使用 wait()和 notify()。我们将用这些方法解决传统的生产者-消费者问题。我们先来了解生产者-消费者问题。
- 这个问题涉及到生产者和消费者。
- 生产者将生产物品并将它们添加到缓冲区。
- 消费者将消费来自缓冲区的产品。
- 如果缓冲区已满,生产者不应生产新项目。
- 如果缓冲区为空,使用者不应使用。
让我们为生产者类编写代码。这个类将实现可运行的接口。它将有一个名为缓冲区的成员。
当缓冲区已满时,生产者应调用wait()
方法。缓冲区的最大容量设置为 5 个元素。在生成一个新项目并将其添加到缓冲区后,它应该通知使用者线程。如果消费线程正在等待,那么它将醒来并开始消费。
class Producer implements Runnable
{
//buffer to store the produced items
private final LinkedList<Integer> buffer;
Producer(LinkedList<Integer> buffer)
{
this.buffer = buffer;
}
@Override
public void run()
{
//Infinitely produce items
while(true)
{
try {
this.produce();
}
catch(Exception e) {
System.out.print(e);
}
}
}
public void produce() throws InterruptedException
{
synchronized(buffer)
{
//If the buffer is full then wait
while(buffer.size() == 5)
{
System.out.println("Producer is waiting");
buffer.wait();
}
//Produce a new random number
Random r = new Random();
int num = r.nextInt(100);
System.out.println("Producer produced: " + num);
buffer.add(num);
buffer.notifyAll();
Thread.sleep(10);
}
}
}
如果缓冲区为空,消费者类应该等待。当它获取锁时,使用者应该从缓冲区弹出第一个元素并使用它。完成后,使用者应该通知生产者线程。
class Consumer implements Runnable
{
//buffer to consume items from
private final LinkedList<Integer> buffer;
Consumer(LinkedList<Integer> buffer)
{
this.buffer = buffer;
}
@Override
public void run()
{
//Infinitely consume
while(true)
{
try {
this.consume();
}
catch(Exception e) {
System.out.print(e);
}
}
}
public void consume() throws InterruptedException
{
synchronized(buffer)
{
//Wait if the buffer is empty
while(buffer.size() == 0)
{
System.out.println("Consumer is waiting");
buffer.wait();
}
//Consume the first item from the buffer
int num = buffer.remove(0);
System.out.println("Consumer consumed: " + num);
buffer.notifyAll();
Thread.sleep(5);
}
}
}
请注意,我们使用同步块来确保一次只有一个线程可以访问缓冲区。
下面显示了上述方法的演示。
public class WaitNotifyDemo
{
public static void main(String args[])
{
LinkedList<Integer> buffer = new LinkedList<>();
Producer producer = new Producer(buffer);
Consumer consumer = new Consumer(buffer);
Thread p = new Thread(producer);
Thread c = new Thread(consumer);
p.start();
c.start();
}
}
生产者生产:26
生产者生产:37
消费者消费:26
消费者消费:37
消费者等待
生产者生产:66
生产者生产:91
生产者生产:51
生产者生产:88
生产者生产:61
生产者等待
摘要
wait(), notify()
和notifyAll()
方法用于线程通信和同步。
在本教程中,我们学习了如何使用这些方法。我们还学习了如何使用这些方法解决生产者-消费者问题。请注意,这些是传统的方法,使用起来比新的 API 复杂一点。
Java 流filter()
原文:https://www.studytonight.com/java-examples/java-stream-filter
Java 中的流是元素或对象的序列。 Java 8 引入流。它们允许我们以高效的方式对数据源执行各种操作。
在本教程中,我们将学习如何在 Java 中过滤流。
流过滤器()方法
Streams 的filter()
方法允许我们基于一个条件或一个谓词来过滤一个给定的流。
请注意,此方法不会改变给定的流。它将返回一个包含满足条件的元素的新流。该方法的签名如下所示。
Stream<T> filter(Predicate<? super T> condition)
让我们看几个例子来了解它的工作原理。
示例 1:用 Java 过滤流
让我们从一个流中过滤掉所有大于 7 的元素。我们将从列表中创建一个流,然后在这个流上应用filter()
方法。
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class Demo
{
public static void main(String[] args)
{
List<Integer> list = Arrays.asList(7, 9, 1, 2, 5, 11, 21);
System.out.println("The List is: " + list);
Predicate<Integer> numGreaterThanSeven = p -> (p > 7);//Writing the condition or Predicate
Stream<Integer> s = list.stream();//Stream of the list
Stream<Integer> filteredStream = s.filter(numGreaterThanSeven);
System.out.println("Filtered Elements are: ");
filteredStream.forEach(System.out :: println);
}
}
列表为:【7、9、1、2、5、11、21】
过滤元素为:
9
11
21
示例 2:过滤用户数据流
让我们处理一个用户定义的类。我们将创建下面定义的学生类。
class Student
{
private String name;
private int regNo;
private Double gpa;
Student(String s, int i, Double gpa)
{
this.name = s;
this.regNo = i;
this.gpa = gpa;
}
//Getters and Setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getRegNo() {
return regNo;
}
public void setRegNo(int regNo) {
this.regNo = regNo;
}
public Double getGpa() {
return gpa;
}
public void setGpa(Double gpa) {
this.gpa = gpa;
}
}
让我们过滤掉所有 GPA 大于 8 的学生。我们将为此条件创建一个谓词,并将其与 filter()方法一起使用。
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class Demo
{
public static void main(String[] args)
{
Student s1 = new Student("Jack", 102, 8.55);
Student s2 = new Student("Joe", 101, 8.75);
Student s3 = new Student("Clay", 107, 9.1);
Student s4 = new Student("Simon", 105, 7.99);
Student s5 = new Student("Reacher", 103, 7.00);
List<Student> list = Arrays.asList(s1, s2, s3, s4, s5);
Predicate<Student> gpaGreaterThanEight = c -> c.getGpa() > 8.0;//Lambda expression for Predicate
Stream filteredStream = list.stream().filter(gpaGreaterThanEight);
}
}
我们还可以在 Student 类中定义一个返回布尔值的方法。然后,我们可以将此方法直接与 filter()方法一起使用。我们将使用 collect()方法将过滤后的流收集到一个列表中。
public boolean gpaGreaterThanEight()
{
return this.getGpa() > 8.0;
}
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Demo
{
public static void main(String[] args)
{
Student s1 = new Student("Jack", 102, 8.55);
Student s2 = new Student("Joe", 101, 8.75);
Student s3 = new Student("Clay", 107, 9.1);
Student s4 = new Student("Simon", 105, 7.99);
Student s5 = new Student("Reacher", 103, 7.00);
List<Student> list = Arrays.asList(s1, s2, s3, s4, s5);
System.out.println("The Student List is: ");
for(Student s : list)
System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());
Stream filteredStream = list.stream().filter(Student :: gpaGreaterThanEight);//Class Method for Predicate
List<Student> filteredList = (List<Student>) filteredStream.collect(Collectors.toList());
System.out.println("\nThe Filtered List is: ");
for(Student s : filteredList)
System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());
}
}
学生名单为:
杰克 102 8.55
乔 101 8.75
克莱 107 9.1
西蒙 105 7.99
雷彻 103 7.0
T7【过滤名单为:
杰克 102 8.55
乔 101 8.75
克莱 107 9.1
示例 3:使用 Lambda 表达式过滤流
我们也可以使用多个条件进行过滤。这些条件可以使用谓词中的Lambda 表达式来创建。或者我们可以在用户定义的类中创建一个方法(如果我们使用的是用户定义的类)。让我们继续前面的例子,过滤掉所有 GPA 大于 8 且姓名正好包含三个字符的学生。
让我们首先使用一个 Lambda 表达式来完成我们的任务。
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Demo
{
public static void main(String[] args)
{
Student s1 = new Student("Jack", 102, 8.55);
Student s2 = new Student("Joe", 101, 8.75);
Student s3 = new Student("Clay", 107, 9.1);
Student s4 = new Student("Simon", 105, 7.99);
Student s5 = new Student("Reacher", 103, 7.00);
List<Student> list = Arrays.asList(s1, s2, s3, s4, s5);
System.out.println("The Student List is: ");
for(Student s : list)
System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());
Predicate<Student> p = c -> (c.getGpa() > 8.0) && (c.getName().length() == 3);
Stream filteredStream = list.stream().filter(p);
List<Student> filteredList = (List<Student>) filteredStream.collect(Collectors.toList());
System.out.println("\nThe Filtered List is: ");
for(Student s : filteredList)
System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());
}
}
学生名单为:
杰克 102 8.55
乔 101 8.75
克莱 107 9.1
西蒙 105 7.99
雷彻 103 7.0
T7】过滤名单为:
乔 101 8.75
让我们在 Student 类中定义一个方法来检查这两个条件,并相应地返回一个布尔值。
public boolean predicateCondition()
{
if(this.getGpa() > 8.0 && this.getName().length() == 3)
return true;
else
return false;
}
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Demo
{
public static void main(String[] args)
{
Student s1 = new Student("Jack", 102, 8.55);
Student s2 = new Student("Joe", 101, 8.75);
Student s3 = new Student("Clay", 107, 9.1);
Student s4 = new Student("Simon", 105, 7.99);
Student s5 = new Student("Reacher", 103, 7.00);
List<Student> list = Arrays.asList(s1, s2, s3, s4, s5);
System.out.println("The Student List is: ");
for(Student s : list)
System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());
Stream filteredStream = list.stream().filter(Student :: predicateCondition);
List<Student> filteredList = (List<Student>) filteredStream.collect(Collectors.toList());
System.out.println("\nThe Filtered List is: ");
for(Student s : filteredList)
System.out.println(s.getName() + " " + s.getRegNo() + " " + s.getGpa());
}
}
学生名单为:
杰克 102 8.55
乔 101 8.75
克莱 107 9.1
西蒙 105 7.99
雷彻 103 7.0
T7】过滤名单为:
乔 101 8.75
Lambda 表达式中的异常处理
在我们用于谓词的 Lambda 表达式中,可能会出现选中或未选中的异常。在 lambda 表达式中使用 try-catch 块来处理异常是一个好主意。
Predicate<Student> p = c ->
{
try{
return c.predicateCondition();
}
catch(Exception e) {
System.out.print(e);
}
return false;
};
我们也可以使用像 ThrowingFunction 这样的第三方库来处理被检查的异常。我们将使用这个库的抛出类。它将返回一个包装异常。
try
{
List<Student> customersWithValidProfilePhoto = list
.stream()
.filter(ThrowingPredicate.unchecked(Student :: predicateCondition))
.collect(Collectors.toList());
}
catch(Exception e)
{
System.out.print(e);
}
如果上述代码中出现异常,那么我们将得到以下输出。
pl . touk . throwing . exception . wrappedexception
摘要
流只是一系列元素。filter()
方法允许我们根据条件从流中过滤出元素。条件是使用谓词定义的。我们可以使用 Lambda 表达式或类方法(对于用户定义的类)来创建谓词。谓词在确定如何过滤元素方面起着至关重要的作用。
在 Java 中生成一个范围内的随机数
原文:https://www.studytonight.com/java-examples/generating-random-numbers-in-a-range-in-java
Java 提供了一些生成随机数的方法,但是要在特定范围内生成随机数是相当棘手的。在本教程中,我们将学习如何利用内置的 Java 方法来实现给定范围内的随机数生成器方法。
使用数学随机()方法
数学类的 random()方法用于生成一个介于 0 和 1 之间的十进制值(包括 0,不包括 1)。
public class RandomRangeDemo
{
public static void main(String[] args)
{
double r1 = Math.random();
double r2 = Math.random();
System.out.println("The first random number is: " + r1);
System.out.println("The second random number is: " + r2);
}
}
第一个随机数为:0.8998047971282644
第二个随机数为:0.94659999991
我们可以使用这个方法来构建我们自己的随机方法,该方法将获取最小和最大范围值,并将返回该范围内的随机数。
- 我们将在方法中使用公式(math . random()*(max-min))+min。
- 这个公式是有效的,因为如果 Math.random()生成 0(最低值),那么(0 *(最大-最小值))+ min 将等于 min。
- 如果 Math.random()生成 1(最高值),那么公式将给出 1 * (max-min) + min,等于 max。
- 但是请记住,Math.random()不会返回 1,而是返回一个略小于 1 的值(比如 0.999999)。所以我们函数的最大返回值会略小于 max。
- 因此,我们的方法返回一个介于最小值和最大值之间的值(包括最小值,不包括最大值)
public class RandomRangeDemo
{
public static int randomNumberGenerator(int min, int max)
{
double r = Math.random();
int randomNum = (int)(r * (max - min)) + min;
return randomNum;
}
public static void main(String[] args)
{
int r1 = randomNumberGenerator(5, 105);//random number between 5 and 105
int r2 = randomNumberGenerator(2199, 2200);//random number between 2199 and 2200
System.out.println("The first random number is: " + r1);
System.out.println("The second random number is: " + r2);
}
}
第一个随机数为:47
第二个随机数为:2199
我们也可以使用 Random 类的 nextDouble()和 nextFloat()方法来代替 Math.random()方法。所有这些方法都会生成一个介于 0 和 1 之间的随机十进制数。
使用 nextDouble()方法的上述代码如下所示。
import java.util.Random;
public class RandomRangeDemo
{
public static int randomNumberGenerator(int min, int max)
{
Random r = new Random();
double randomNum = r.nextDouble();
int result = (int)(randomNum * (max - min)) + min;
return result;
}
public static void main(String[] args)
{
int r1 = randomNumberGenerator(5, 105);//random number between 5 and 105
int r2 = randomNumberGenerator(2199, 2200);//random number between 2199 and 2200
System.out.println("The first random number is: " + r1);
System.out.println("The second random number is: " + r2);
}
}
第一个随机数为:53
第二个随机数为:2199
使用随机类的 nextInt()方法
nextInt()方法可用于生成随机整数。如果我们将一个正参数 n 传递给这个方法,那么它将返回一个范围在 0 到 n(包括 0,不包括 n)之间的随机数。
import java.util.Random;
public class RandomRangeDemo
{
public static void main(String[] args)
{
Random r = new Random();
int randomNum1 = r.nextInt(100);
int randomNum2 = r.nextInt(1);
System.out.println("The first random number is: " + randomNum1);
System.out.println("The second random number is: " + randomNum2);
}
}
第一个随机数为:63
第二个随机数为:0
我们将使用这个方法来构建我们自己的随机数生成器方法。我们将使用公式 nextInt(max-min) + min 。让我们试着理解这个公式。
例如,如果 max = 31,min = 7,那么(max-min)将等于 24。因此,nextInt(24)将生成一个介于 0 和 24 之间的随机数。如果它生成 0(最低值),那么 0 + min 将等于 7。如果它生成 24(最大值),那么 24 + min 将等于 31,这是最大值。因为 nextInt(n)不包括 n 值,所以我们的方法也不包括最大值。
import java.util.Random;
public class RandomRangeDemo
{
public static int randomNumberGenerator(int min, int max)
{
Random r = new Random();
int randomNum = r.nextInt(max - min);
int result = randomNum + min;
return result;
}
public static void main(String[] args)
{
int randomNum1 = randomNumberGenerator(500, 2000);//random number between 500 and 2000
int randomNum2 = randomNumberGenerator(500, 501);//random number between 500 and 501
System.out.println("The first random number is: " + randomNum1);
System.out.println("The second random number is: " + randomNum2);
}
}
第一个随机数为:846
第二个随机数为:500
使用随机类的 ints()方法
java.util.Random.ints()方法可以返回随机生成的无限整数流。我们可以指定一个范围,所有的随机数都会在这个范围内生成。我们还可以指定流的大小,这样我们只能得到有限数量的整数。
以下代码无限运行,因为我们没有为 ints()方法指定流大小。我们只显示了输出中的几个数字。
import java.util.Random;
import java.util.stream.IntStream;
public class RandomRangeDemo
{
public static void main(String[] args)
{
Random r = new Random();
IntStream stream = r.ints(10, 20);
stream.forEach(s -> System.out.println(s));
}
}
11
16
16
14
12
13
现在让我们通过设置流大小来生成 5 个随机整数。
import java.util.Random;
import java.util.stream.IntStream;
public class RandomRangeDemo
{
public static void main(String[] args)
{
Random r = new Random();
IntStream stream = r.ints(5, 100, 120);
stream.forEach(s -> System.out.println(s));
}
}
103
106
114
117
109
我们可以使用 findFirst()和 getAsInt()方法,只从流中获取第一个随机数。
import java.util.Random;
import java.util.stream.IntStream;
public class RandomRangeDemo
{
public static void main(String[] args)
{
int min = 150, max = 2000;//defining the range
Random r = new Random();
IntStream stream = r.ints(1, min, max);
int randomNum = stream.findFirst().getAsInt();
System.out.print("The random number is: " + randomNum);
}
}
随机数为:1193
摘要
在本教程中,我们学习了在指定范围内生成随机数的不同方法。我们使用数学类的内置 random()方法和 Random 类的 nextInt()实现了我们的方法。我们还可以直接使用 ints()方法来生成给定范围内的随机数流。
Java 中等待和睡眠的区别
原文:https://www.studytonight.com/java-examples/difference-between-wait-and-sleep-in-java
使用线程时,等待和睡眠会频繁出现。这些术语不可互换,含义不同。两者都用于暂停线程的执行,但是它们之间有一些主要的区别。让我们了解更多关于等待和睡眠的区别。
Java 中的等待与睡眠
- 等待和睡眠都用于暂停线程的执行,并使其进入不可运行状态。但是在睡眠的情况下,线程会在固定的时间段后醒来。当使用 wait()方法时,只有当对线程正在等待的同步块调用 notify() 或 notifyAll() 方法时,才能唤醒线程。
- 当我们只处理一个线程,并希望在一段时间内停止它的执行时,我们将使用 sleep。而多线程和同步总是采用等待的方式。等待方法应该总是在同步块中调用。
- 两者的另一个主要区别是等待会释放锁定,但睡眠不会。由于这个原因,睡眠不用于同步目的,因为线程可以长时间睡眠,没有其他线程可以访问关键部分。
以上几点总结了 Java 中等待和睡眠方法的主要区别。下表讨论了几个不同之处。
| 等待 | 睡眠 |
| 在对象上调用 wait()方法。 | 在当前执行的线程上调用 sleep()。 |
| 用于线程同步。 | 用于时间同步。 |
| Wait()不是静态方法。 | sleep()是一个静态方法。 |
| 只能从同步块中调用 Wait()。如果我们从同步块外部调用它,那么我们将得到一个illegalmonitorstatexception。 | sleep()也可以在同步块之外调用。 |
| wait()可以在下列重载方法的帮助下使用:
- 等待()
- 等待(长时间超时)
- 等待(长超时,整数纳秒)
| sleep()可以在以下三种重载方法的帮助下使用:
- 睡眠(长毫秒)
- 睡眠(长毫秒,整数纳秒)
|
睡眠的方法签名()
public static void sleep(long milliseconds) throws Interrupted_Execption
等待的方法签名()
public final void wait(long timeout)
示例:Java 中的 sleep()和 wait()
让我们借助下面的例子来理解 sleep()和 wait()方法的工作原理。
在下面的例子中,主线程将休眠 1 秒钟,然后继续执行。但是当调用 wait()时,线程会无限等待,因为没有其他线程在对象上调用 notify()。该程序将无限期运行。
public class SleepvsWait
{
private static Object o = new Object();
public static void main(String[] args) throws InterruptedException
{
System.out.println("Thread Going to sleep...");
Thread.sleep(1000);
System.out.println("Thread woke up after 1 second.");
synchronized(o)
{
System.out.println("Thread will wait for notify...");
o.wait();
}
System.out.println("Thread woken up after notify() or notifyAll() or timeout.");
}
}
线程要睡觉了...
线程 1 秒后唤醒。
线程将等待通知...
现在,让我们为 wait()方法指定一个超时持续时间。超时后,线程将继续执行。
public class SleepvsWait
{
private static Object o = new Object();
public static void main(String[] args) throws InterruptedException
{
System.out.println("Thread Going to sleep...");
Thread.sleep(1000);
System.out.println("Thread woke up after 1 second.");
synchronized(o)
{
System.out.println("Thread will wait for notify...");
o.wait(1000);
}
System.out.println("Thread woken up after notify() or notifyAll() or timeout.");
}
}
线程要睡觉了...
线程 1 秒后唤醒。
线程将等待通知...
线程在 notify()或 notifyAll()或超时后被唤醒。
常见问题
问:notify()和 notifyAll()有什么区别?
notify()只会唤醒一个等待锁定的线程,而 notifyAll()会唤醒所有等待锁定对象的线程。
问:收益率()是用来做什么的?
yield()是一种暂停线程执行的方式,以便其他线程可以执行关键部分。它用于给其他具有相同或更高优先级的线程一个执行的机会。如果所有其他线程都具有较低的优先级,那么当前线程将继续执行。
问:什么是 Java 中的同步块?
同步块是一次只能由单个线程访问的块。同步块使用监视器或锁来实现特定对象的同步。
结论
在这个简短的教程中,我们了解了 Java 中线程使用的 wait()和 sleep()方法之间的区别。我们只需要记住 wait()用于线程同步并通过记住其他线程的存在来完成一切。另一方面,S leep 主要用于单线程和时间同步。
Java 元组介绍
原文:https://www.studytonight.com/java-examples/introduction-to-java-tuples
元组是一种数据结构,它像数组或列表一样以有序序列存储数据。但是与数组或列表不同,元组可以存储不同类型的数据。
例如,我们可以在元组中存储[“string”,123,123.321,' c']但不能使用数组或列表来存储。使用数组或列表实现这一点的唯一方法是创建一个字符串数组,并使用字符串存储它们,但这可能非常麻烦。
String[] arr = {"string", "123", "123.321", "c"};
我们还可以用所需类型的数据成员创建自己的类,这也会导致混乱和延迟。
Java 不提供任何实现元组的数据结构或集合,但是我们可以将名为 Java 元组的外部库添加到我们的项目中来使用它的元组类。这是一个简单明了的库,提供了不同的方法来处理元组。
Java 元组库
Java 元组库提供了十个不同的类,可以用来处理元组。这些类之间的区别在于可以存储在其中的元素数量。我们不能在一个 Java 元组类中存储超过 10 个元素。这些类的名称如下。
- 单元< A > 存储一个单元素。
- 配对< A、B > 储存两个元素。
- 三元组< A、B、C > 储存三个元素。
- 四方< A、B、C、D > 储存四元素。
- 五重奏< A、B、C、D、E > 储存五个元素。
- 六位< A、B、C、D、E、F > 储存六个元素。
- 九月< A、B、C、D、E、F、G > 储存七个元素。
- 八位字节< A、B、C、D、E、F、G、H > 存储八个元素。
- Ennead < A、B、C、D、E、F、G、H、I > 储存九个元素。
- 十年< A、B、C、D、E、F、G、H、I、J > 储存十个元素。
我们还有两个类叫做键值< A,B > 和标签值< A,B > 。这些类似于配对< A、B >类。字母 A、B、C 等表示要存储在元组中的不同元素的数据类型。
这个库的所有元组类都是类型安全和不可变。我们不能在创建对象后更改数据或元组的结构。所有这些类都实现了可迭代、可序列化和可比较接口。
在 Java 中创建元组
创建元组非常简单。我们只需要向类构造器指定元素的数据类型及其值。
import org.javatuples.*;
public class TupleDemo
{
public static void main(String[] args)
{
Triplet<String, Double, Integer> tuple1 = new Triplet<String, Double, Integer>("Str", 5.0, 5);
System.out.println(tuple1);
}
}
【Str,5.0,5】
我们也可以使用和()方法来创建一个新的元组。
import org.javatuples.*;
public class TupleDemo
{
public static void main(String[] args)
{
Triplet<String, Double, Integer> tuple2 = Triplet.with("Str", 5.0, 5);
System.out.println(tuple2);
}
}
【Str,5.0,5】
我们也可以使用 fromCollection() 和 fromIterable() 方法从集合中创建一个新的元组。使用 fromCollection()时,请确保根据集合的大小使用正确的元组类。fromIterable()方法可以用来创建一个较小大小的元组,方法是指定应该从其中挑选元素的索引。
import java.util.Arrays;
import java.util.List;
import org.javatuples.*;
public class TupleDemo
{
public static void main(String[] args)
{
List<String> list = Arrays.asList("unit","pair", "triplet");
Triplet<String, String, String> tuple1 = Triplet.fromCollection(list);
System.out.println(tuple1);
Pair<String, String> tuple2 = Pair.fromIterable(list, 1);//two elements to be fetched from index 1
System.out.println(tuple2);
}
}
【单位、对、三元组】
【对、三元组】
在 Java 中获取元组的值
我们可以使用 getValue(X) 或 getValueX() 方法来获取元组中索引 X 处的元素。就像数组一样,元组也遵循零基索引。注意 getValue()方法不是类型安全的。使用这种方法时,我们需要使用铸造。但是 getValueX()方法是类型安全的,不需要铸造。
import org.javatuples.*;
public class TupleDemo
{
public static void main(String[] args)
{
Triplet<String, Integer, Double> tuple = Triplet.with("Str", 5, 5.0);
Integer i = (Integer)tuple.getValue(1);//casting
Integer j = tuple.getValue1();
System.out.println("Value fetched by getValue(): " + i);
System.out.println("Value fetched by getValueX(): " + j);
}
}
getValue()获取的值:5
getValueX()获取的值:5
在 Java 中设置元组的值
我们可以通过使用 setAtX() 方法来改变元组中元素的值,其中 X 是索引。这将返回与原始元组相同类的元组。由于元组是不可变的,所以原始元组不会以任何方式改变。
import org.javatuples.*;
public class TupleDemo
{
public static void main(String[] args)
{
Triplet<String, Integer, Double> tuple1 = Triplet.with("Str", 5, 5.0);
Triplet<String, Integer, Double> tuple2 = tuple1.setAt2(5.1);
System.out.println("Original Tuple: " + tuple1);
System.out.println("New Tuple with changes: " + tuple2);
}
}
原始元组:[Str,5,5.0]
有变化的新元组:[Str,5,5.1]
在元组中添加元素
我们可以向现有的元组添加值,但是我们需要创建一个更大的新元组来容纳新元素。
例如,如果我们向 Septet 类元组添加一个元素,那么我们将得到一个 Octet 元组。
我们可以使用 add() 方法在元组的末尾添加一个元素。或者我们可以使用 addAtX() 方法在索引 x 处添加一个元素。这将把其他元素向右推一个位置。在插入新元素之前,请确保数据类型匹配。
import org.javatuples.*;
public class TupleDemo
{
public static void main(String[] args)
{
Triplet<String, String, String> tuple1 = Triplet.with("str1", "str2", "str3");
Quartet<String, String, String, String> tuple2 = tuple1.add("str4");
Quartet<String, String, String, String> tuple3 = tuple1.addAt0("str0");
System.out.println("Original Tuple: " + tuple1);
System.out.println("Adding using add(): " + tuple2);
System.out.println("Adding using addAtX(): " + tuple3);
}
}
原始元组:[str1,str2,str3]
使用 add(): [str1,str2,str3,str4]
使用 addAtX(): [str0,str1,str2,str3]添加
这两种方法也可以用来将一个元组添加到另一个元组。我们需要小心新元组的最终大小。例如,如果一个配对类元组被添加到一个三元组类元组,则创建一个五元组元组。确保两个元组的组合大小不超过 10。
import org.javatuples.*;
public class TupleDemo
{
public static void main(String[] args)
{
Triplet<String, String, String> tuple1 = Triplet.with("str1", "str2", "str3");
Pair<String, String> tuple2 = Pair.with("str4", "str5");
Quintet<String, String, String, String, String> tuple3 = tuple1.add(tuple2);
Quintet<String, String, String, String, String> tuple4 = tuple1.addAt1(tuple2);
System.out.println("Adding tuples using add(): " + tuple3);
System.out.println("Adding tuples using addAtX(): " + tuple4);
}
}
使用 add()添加元组:【str1、str2、str3、str4、str5】
使用 addAtX()添加元组:【str1、str4、str 5、str2、str3】
移除元素
removeFromX() 方法可用于从索引 x 中移除元素。这将返回比原始数组小一个大小的元组。例如,当 removeFromX()用于四元组时,则返回一个三元组元组。
import org.javatuples.*;
public class TupleDemo
{
public static void main(String[] args)
{
Triplet<String, String, String> tuple1 = Triplet.with("str1", "str2", "str3");
Pair<String, String> tuple2 = tuple1.removeFrom0();
Pair<String, String> tuple3 = tuple1.removeFrom1();
System.out.println("Original Tuple: " + tuple1);
System.out.println("Removing element at index 0: " + tuple2);
System.out.println("Removing element at index 1: " + tuple3);
}
}
原始元组:[str1,str2,str3]
移除索引 0 处的元素:[str2,str3]
移除索引 1 处的元素:[str1,str3]
循环/迭代元组
由于元组实现了可迭代接口,我们可以使用简单的 for-each 循环轻松地循环或迭代一个元组。
import org.javatuples.*;
public class TupleDemo
{
public static void main(String[] args)
{
Triplet<String, String, String> tuple = Triplet.with("str1", "str2", "str3");
for(Object o : tuple)
System.out.print(o + " ");
}
}
str1 str2 str3
Java 元组包含()和 containsAll()方法
顾名思义,contains()方法根据元组中元素的存在情况返回一个布尔值。
import org.javatuples.*;
public class TupleDemo
{
public static void main(String[] args)
{
Triplet<String, String, String> tuple = Triplet.with("str1", "str2", "str3");
boolean containsStr1 = tuple.contains("Str1");
boolean containsstr1 = tuple.contains("str1");
System.out.println("Tuple contains Str1: " + containsStr1);
System.out.println("Tuple contains str1: " + containsstr1);
}
}
元组包含 Str1:假
元组包含 str1:真
containsAll()方法可用于检查元组中是否存在集合的所有元素。这个方法也返回一个布尔值。
import java.util.Arrays;
import java.util.List;
import org.javatuples.*;
public class TupleDemo
{
public static void main(String[] args)
{
Triplet<String, String, String> tuple = Triplet.with("str1", "str2", "str3");
List<String> list1 = Arrays.asList("str1", "str3", "str2");
List<String> list2 = Arrays.asList("str1", "str5", "str2");
System.out.println("Tuple contains list1: " + tuple.containsAll(list1));
System.out.println("Tuple contains list2: " + tuple.containsAll(list2));
}
}
元组包含列表 1:真
元组包含列表 2:假
Java 元组 indexOf()和 lastIndexOf()方法
indexOf()方法返回元组中第一个元素的索引。
方法返回元组中元素最后一次出现的索引。
import org.javatuples.*;
public class TupleDemo
{
public static void main(String[] args)
{
Quartet<String, String, String, String> tuple = Quartet.with("str1", "str2", "str1", "str3");
System.out.println("Tuple: " + tuple);
System.out.println("First index of str1:" + tuple.indexOf("str1"));
System.out.println("Last index of str1: " + tuple.lastIndexOf("str1"));
}
}
元组:【str1,str2,str1,str 3】
str 1 的第一个索引:0
str 1 的最后一个索引:2
将元组转换为数组或列表
我们可以使用 toArray() 方法轻松地将元组转换为数组。同样,我们可以使用 toList() 方法将元组转换为列表。注意这两个方法将返回对象类型的数组和列表(对象[] arr,列表<对象>列表),即使元组的所有元素具有相同的数据类型。
import java.util.Arrays;
import java.util.List;
import org.javatuples.*;
public class TupleDemo
{
public static void main(String[] args)
{
Quartet<String, String, String, String> tuple = Quartet.with("str1", "str2", "str1", "str3");
Object[] arrFromTuple = tuple.toArray();
List<Object> listFromTuple = tuple.toList();
System.out.println("Tuple: " + tuple);
System.out.println("Array: " + Arrays.toString(arrFromTuple));
System.out.println("List: " + listFromTuple);
}
}
元组:[str1,str2,str1,str3]
数组:[str1,str2,str1,str3]
列表:[str1,str2,str1,str3]
常见问题
问:在 Java 中使用类如何实现元组?
元组的大小是固定的,用于将不同类型的数据存储在一起。例如,如果我们想要存储一个字符串、一个整数和一个双数,那么我们可以用这三个数据成员创建一个类,并编写适当的构造器来创建一个这种类型的新对象。但是最好使用像 Java 元组这样的外部库。
问:元组比列表快吗?
是的,元组比列表更快,因为它们的大小是固定的,并且是不可变的,所以我们可以只给它们分配一块内存,而不需要为额外的元素添加额外的空间。与列表相比,遍历元组也更快。
摘要
如果我们只希望分配一次数据,而不想再次更改该数据,元组是一种重要的数据结构。它们可以用来存储包含不同数据类型字段的记录,如[101,“巧克力”,5.99]。Java 元组库提供了不同的类,可以用来处理元组。元组类最多可以存储 10 个元素。关于元组需要注意的一点是,当我们设置、添加或移除值时,我们并没有改变原始元组,而是用修改创建了一个新的元组。这是因为元组是不可变的。
在 Java 中【找不到或加载主类】错误
原文:https://www.studytonight.com/java-examples/could-not-find-or-load-main-class-error-in-java
使用 Java 或任何其他编程语言时,错误和异常非常常见。找不到或加载主类错误非常常见,并且可能频繁发生。这个错误仅仅意味着 JVM 找不到主类。让我们看看发生此错误的原因,并尝试解决此错误。
这里,我们在一个名为ErrorDemo.java的 java 文件中有以下代码。
public class ErrorDemo
{
public static void main(String[] args)
{
System.out.println("Error Fixed");
}
}
我们可以使用 javac 命令编译这段代码,并提供 java 文件名。
上述命令生成一个。与主方法的类同名的类文件。
我们可以使用 java 命令运行代码并查看输出。我们可以看到一切都很好,我们得到了预期的输出。
类别文件名不正确时出错
让我们故意把事情搞砸来查看找不到或者加载主类的错误。如果我们试图运行一个 java 程序,但是没有通过正确的,就会出现这个错误。类文件名称。
另一件需要记住的事情是,我们使用 javac 命令来编译一个 java 文件,并且我们需要添加。使用文件名时的 java 扩展名。但是当运行。类文件,不要传递。具有类名的类扩展。这也将返回相同的错误。
目录不正确时出错
注意,我们必须为。正确文件夹中的类文件。例如,如果我们导航到桌面(使用 cd..命令),那么同样,我们也会得到同样的错误。
错误不正确的包名
Java 中的包是一组相似的类或接口,它们被组合在一起以便于访问。当试图运行包中存在的. class 文件时,我们需要使用包名和类名。
让我们修改我们的程序,以便将类包含在一个包中。
package p;
public class ErrorDemo
{
public static void main(String[] args)
{
System.out.println("Error Fixed");
}
}
现在,当我们用 -d 和一个点(。)然后是。类文件将在包 p 中创建。
让我们尝试运行这个类文件,就像我们在上面的例子中所做的那样。但是我们现在得到一个错误。
为了纠正它,我们还需要在运行文件时传递包名。
请记住,我们是从父目录而不是从包目录 p 运行上述命令。
类路径
如上所述,如果我们运行。不包含此文件的目录中的类文件。这是因为,默认情况下,JVM 将在我们当前的目录中搜索类文件。类路径通知 JVM 在特定的文件夹中查找文件。定义类路径有助于我们从其他目录中运行 java 类文件。运行时,使用 java 命令的-类路径或 -cp 选项来传递类路径。类文件。
比如,如果我们的。类文件存在于一个名为错误的文件夹中,我们试图从桌面运行代码,然后我们会得到以下错误。
我们可以使用类路径来纠正这个错误。
常见问题
我们如何在 Java 中运行一个文件?
如本文开头所示,首先使用 javac 命令编译一个 Java 文件,这会生成一个. class 文件。接下来,我们可以运行这个。类文件。阅读更多。
路径与类路径有何不同?
路径是我们可以找到扩展名为。exe 或。jar,而类路径就是我们可以找到的位置。类文件。默认情况下,类路径被设置为我们正在工作的当前目录。
什么是 classnotfoundexception?
当 JVM 在提到的类路径中找不到我们试图运行的类时,就会出现 ClassNotFoundException。
当我们在运行 javac 命令后得到以下错误时怎么办:javac 不被识别为内部和外部命令?
出现此错误是因为我们没有设置 PATH 环境变量。我们可以使用以下命令临时设置它。传递 JDK 的文件夹路径。
C:\Users\user1>set path=C:\Program Files\Java\jdk1.8.0_144\bin
阅读更多关于 Java 环境设置的内容。
摘要
找不到或加载主类错误在 Java 中很常见。大多数情况下,这是因为我们写的类名不正确,或者我们添加了不必要的。运行时的类扩展。如果类是包的一部分,那么我们必须在运行代码时提供完全限定类名以避免错误。
Java instanceof
运算符
原文:https://www.studytonight.com/java-examples/java-instanceof-operator
在面向对象编程中,对象被定义为类的实例。顾名思义,Java 中的 instanceof 运算符用于检查这种关系。该运算符也称为类型比较运算符。
运算符的实例返回一个布尔值。如果对象是特定类型,则该运算符返回真,否则返回假。该运算符的语法如下所示。
实例的语法
(object) instanceof (class or subclass or interface)
示例:Java 中的实例
instanceof 运算符只需检查对象和类型之间的 is-a 关系。在下面的例子中,我们可以说苹果是水果,但是汽车是车辆而不是水果。
class Fruit{}
class Vehicle{}
public class InstanceofDemo
{
public static void main(String[] args)
{
Fruit pineapple = new Fruit();
Vehicle truck = new Vehicle();
System.out.println("pineapple IS A fruit: " + (pineapple instanceof Fruit));
System.out.println("truck IS A vehicle: " + (truck instanceof Vehicle));
}
}
菠萝是水果:真
卡车是车辆:真
但是如果我们运行下面的代码,那么我们会得到一个编译错误,因为汽车和水果之间没有关系。
class Fruit{}
class Vehicle{}
public class InstanceofDemo
{
public static void main(String[] args)
{
Fruit apple = new Fruit();
Vehicle car = new Vehicle();
System.out.println("car IS A Fruit: " + (car instanceof Fruit));
}
}
示例:带有子类的实例
让我们创建一个父类和一个子类来理解它们之间的关系。子类的对象也是父类的实例。
class A{}
class B extends A{}
public class InstanceofDemo
{
public static void main(String[] args)
{
B objOfClassB = new B();
System.out.println("objOfClassB is an instance of B: " + (objOfClassB instanceof B));
System.out.println("objOfClassB is an instance of the parent class A: " + (objOfClassB instanceof A));
}
}
objOfClassB 是 B 的实例:真
objOfClassB 是父类 A 的实例:真
子类是父类的类型,但事实并非如此。如果我们创建一个父类的对象,并将其与子类进行比较,那么 instanceof 运算符将返回 false 。
class A{}
class B extends A{}
public class InstanceofDemo
{
public static void main(String[] args)
{
B objOfClassB = new B();
A objOfClassA = new A();
System.out.println("objOfClassB is an instance of the parent class A: " + (objOfClassB instanceof A));
System.out.println("objOfClassA is an instance of the child class B: " + (objOfClassA instanceof B));
}
}
objOfClassA 是父类 A 的实例:true
objOfClassA 是子类 B 的实例:false
示例:带接口的实例
还要注意,如果子类实现了一个接口,那么如果我们将子类的对象与接口进行比较,instanceof 运算符将返回 true。
class A{}
interface C{}
class B extends A implements C{}
public class InstanceofDemo
{
public static void main(String[] args)
{
B objOfClassB = new B();
System.out.println((objOfClassB instanceof B));
}
}
真
示例:带有对象类的实例
在 Java 中,每个类都扩展了对象类,因此任何对象都是对象类的一个实例。这可以通过使用 instanceof 运算符来验证。
class A{}
interface C{}
class B extends A implements C{}
public class InstanceofDemo
{
public static void main(String[] args)
{
B objOfClassB = new B();
String str = "string";
Exception e = new Exception();
System.out.println((objOfClassB instanceof Object));
System.out.println((str instanceof Object));
System.out.println((e instanceof Object));
}
}
真
真
真
如果对象为空,则实例将始终返回假。
class A{}
interface C{}
class B extends A implements C{}
public class InstanceofDemo
{
public static void main(String[] args)
{
B objOfClassB = null;
System.out.println((objOfClassB instanceof B));
System.out.println((objOfClassB instanceof A));
System.out.println((objOfClassB instanceof C));
System.out.println((objOfClassB instanceof Object));
}
}
假
假
假
假
instanceof 运算符只能用于具体化类型(其信息在运行时可用的类型)。我们不能对泛型类型使用此运算符,因为泛型类型信息在运行时会丢失。下面的代码演示了这个场景。它会给出一个编译错误,说明泛型类型信息在运行时被删除,因此 instanceof 运算符无法处理它。
public static <T> boolean instanceCheck(List<T> list)
{
return list instanceof ArrayList<String>;
}
无法对参数化类型ArrayList
<字符串>执行实例检查。使用表格ArrayList
<?>相反,因为更多的泛型类型信息将在运行时被删除
摘要
instanceof 运算符仅用于检查对象是否是类的实例或类型。它主要用于在尝试访问其数据或方法之前检查对象类型。运算符的实例只是一个is-一个关系检查。如果对象和类型没有任何关系,instanceof 运算符将给出一个编译错误,如果对象为 null,它将始终为 false。
Java 中的异或运算符
原文:https://www.studytonight.com/java-examples/xor-operator-in-java
异或是按位运算符,它通过比较操作数的各个位来工作。异或代表异或,当且仅当被比较的两位不同时,它才返回真。下面的真值表解释了异或运算的输出。记住,在二进制中,1 代表真,0 代表假。
| A | B | A 异或 B |
| Zero | Zero | Zero |
| Zero | one | one |
| one | Zero | one |
| one | one | Zero |
“异或”也可以用“与”、“或”和“非”等其他基本运算符来表示。异或 B 相当于 (A 与(非 B))或(B 与(非 A)) 。我们可以用这种方式写异或,因为在任何时刻,要么 A 应该为真,B 应该为假,要么 A 应该为假,B 应该为真。
示例:Java 中的异或
在 Java 中,XOR 运算符由插入符号 symbol(^) 表示。它可以用于任何原始数据类型。让我们试着用这个运算符来验证异或的真值表。
public static void main(String[] args)
{
System.out.println("0 XOR 0: " + (0 ^ 0));
System.out.println("0 XOR 1: " + (0 ^ 1));
System.out.println("1 XOR 0: " + (1 ^ 0));
System.out.print("1 XOR 1: " + (1 ^ 1));
}
0 异或 0: 0
0 异或 1: 1
1 异或 0: 1
1 异或 1: 0
示例:与布尔值异或
异或也可以作用于布尔值。让我们尝试使用布尔真和假来重新创建表。
public static void main(String[] args)
{
System.out.println("False XOR False: " + (false ^ false));
System.out.println("False XOR True: " + (false ^ true));
System.out.println("True XOR False: " + (true ^ false));
System.out.print("True XOR True: " + (true ^ true));
}
假异或假:假
假异或真:真
真异或假:真
真异或真:假
示例:Java 中与整数值的异或运算
异或运算符可用于非 0 或 1 的整数。异或运算符将对整数的二进制表示的各个位进行运算。例如,如果 9 与 15 异或,那么异或运算符将应用于两个数字的各个位(1001 代表 9,1111 代表 15)。
public static void main(String[] args)
{
System.out.println("9 XOR 15: " + (9 ^ 15));//1001 XOR 1111 = 0110
System.out.println("1 XOR 20: " + (1 ^ 20));//00001 XOR 10100 = 10101
System.out.println("7 XOR 7: " + (7 ^ 7));//0111 XOR 0111 = 0000
System.out.print("32 XOR 0: " + (32 ^ 0));//100000 XOR 000000 = 100000
}
9 异或 15: 6
1 异或 20: 21
7 异或 7: 0
32 异或 0: 32
二进制字符串的异或
异或只适用于原始数据类型。但是,我们可以编写自己的方法,使用异或运算符和一些附加逻辑来查找两个二进制字符串的异或。我们将简单地同时循环两个字符串的每个字符,并对它们使用异或运算符。请记住,异或可以对字符数据类型起作用,如果两个字符相同,则返回 0。
public class XOR
{
public static String binaryStringXOR(String binStr1, String binStr2)
{
String xor = "";
//adding zeroes to make the two strings equal in length
if(binStr1.length() > binStr2.length())
{
String temp = "";
for(int i = 0; i < binStr1.length() - binStr2.length(); i++)
temp += "0";
binStr2 = temp + binStr2;
}
else if(binStr2.length() > binStr1.length())
{
String temp = "";
for(int i = 0; i < binStr2.length() - binStr1.length(); i++)
temp += "0";
binStr1 = temp + binStr1;
}
for(int i=0; i < binStr1.length(); i++)
{
xor += binStr1.charAt(i) ^ binStr2.charAt(i);
}
return xor;
}
public static void main(String[] args)
{
System.out.println("1001 XOR 1111: " + binaryStringXOR("1001", "1111"));
System.out.println("1 XOR 10100: " + binaryStringXOR("1", "10100"));
System.out.println("0111 XOR 1: " + binaryStringXOR("0111", "1"));
System.out.print("100000 XOR 0: " + binaryStringXOR("100000", "0"));
}
}
1001 异或 1111: 0110
1 异或 10100: 10101
0111 异或 1: 0110
100000 异或 0: 100000
示例:在 Java 中使用 xor 查找非重复值
我们学习了异或运算符的基础知识。现在让我们用它来解决一个问题。假设我们有一个整数数组,我们知道除了一个特定的整数之外,每个整数恰好出现两次。我们的任务是找到这个不重复的整数。
我们可以简单地迭代数组,存储每个整数的频率,并返回只出现一次的整数。但是有一种更有效的方法来实现这一点,那就是使用异或运算符。请记住,数字与自身的异或运算返回 0,数字与 0 的异或运算返回数字本身。
例如,考虑输入数组【10,12,5,6,10,6,12】。我们可以看到,除了 5,所有元素都出现了两次。所有元素的异或可以写成 10 ^ 12 ^ 5 ^ 6 ^ 10 ^ 6 ^ 12。这可以重新安排,写成(10 ^ 10) ^ (12 ^ 12 ) ^ (6 ^ 6) ^ 5。这与写入 0 ^ 0 ^ 0 ^ 5 相同,这将返回 5。
public class XOR
{
public static int nonRepeatingInteger(int[] numArray)
{
int xor = numArray[0];
for(int i = 1; i < numArray.length; i++)
xor = xor ^ numArray[i];
return xor;
}
public static void main(String[] args)
{
int[] arr = {10, 12, 5, 6, 10, 6, 12};
int nonRepeatingNum = nonRepeatingInteger(arr);
System.out.print("The non-repeating integer is:" + nonRepeatingNum);
}
}
非重复整数为:5
摘要
在本教程中,我们学习了异或运算的基础知识。插入符号 symbol(^)在 Java 中用作 XOR 运算符,它可以处理所有原始数据类型。我们还实现了一个方法来寻找两个二进制字符串的异或。
Java 中如何将一个数字四舍五入到小数点后N
位?
原文:https://www.studytonight.com/java-examples/how-to-round-a-number-to-n-decimal-places-in-java
取整一个数意味着得到一个更简单的近似值。圆周率通常四舍五入到小数点后两三位,三分之一通常写成 0.334。在 Java 中,有几种不同的方法来舍入浮点数。让我们学习如何做到这一点。
使用 printf()方法进行舍入
我们可以简单地使用 System.out.printf() 将四舍五入后的数字打印到控制台上。我们可以通过使用精度修饰符来指定要舍入的小数位数。下面的代码演示了 printf()方法的使用。
public static void main(String args[])
{
double pi = 3.14159265359;
double oneThird = 1.0/3.0;
float g = 9.807f;
System.out.printf("Pi: %.2f %n", pi);
System.out.printf("One Third: %.3f %n", oneThird);
System.out.printf("Gravitation Acceleration(g): %.0f", g);
}
π:3.14
三分之一:0.333
重力加速度(g): 10
使用十进制格式()方法舍入
DecimalFormat 类可以用来定义我们想要格式化数字的模式。我们可以通过使用标签(#) 来指定小数位数,然后我们需要使用格式()方法来舍入数字。下面的代码演示了十进制格式的工作原理。
public static void main(String args[])
{
double pi = 3.14159265359;
double oneThird = 1.0/3.0;
float g = 9.807f;
DecimalFormat d1 = new DecimalFormat("#.##");
DecimalFormat d2 = new DecimalFormat("#.###");
DecimalFormat d3 = new DecimalFormat("#");
System.out.println("Pi: " + d1.format(pi));
System.out.println("One Third: " + d2.format(oneThird));
System.out.print("Gravitation Acceleration(g):" + d3.format(g));
}
π:3.14
三分之一:0.333
重力加速度(g):10
如果您不确定小数点前的数字,那么只使用一个哈希。十进制格式()不会删除小数点前的任何数字。
使用数学舍入()方法进行舍入
Java 的 Math 类为我们提供了很多执行基本数学运算的方法。Math.round()用于舍入十进制数。当我们只想将一个数字四舍五入到小数点后零位时,可以使用它。使用 Math.round()时,请记住以下三种边缘情况。
- 如果输入的是而不是数字(NaN) ,那么 Math.round() 返回 0 。
- 如果输入为正无穷大或大于整数的任何值。最大值,数学圆()返回整数。最大值。
- 如果输入是负无穷大或任何小于整数的值。最小值,数学圆()返回整数。最小值。
public static void main(String args[])
{
double pi = 3.14159265359;
double oneThird = 1.0/3.0;
float g = 9.807f;
System.out.println("Pi: " + Math.round(pi));
System.out.println("One Third: " + Math.round(oneThird));
System.out.println("Gravitation Acceleration(g):" + Math.round(g));
}
π:3
三分之一:0
重力加速度(g):10
我们可以通过使用 Math.round()对超过零个小数位进行舍入来构建自己的方法。我们的 round()方法将取一个小数值和要舍入的小数位数作为参数,并将返回舍入后的数字。这方面的代码如下所示。但是,建议使用下面的代码,因为它会产生意想不到的结果。
public static double round(double num, int places)
{
double scale = Math.pow(10, places);
double roundedNum = Math.round(num * scale) / scale;
return roundedNum;
}
public static void main(String args[])
{
double pi = 3.14159265359;
double oneThird = 1.0/3.0;
float g = 9.807f;
System.out.println("Pi: " + round(pi, 2));
System.out.println("One Third: " + round(oneThird, 3));
System.out.println("Gravitation Acceleration(g):" + round(g, 0));
}
Pi: 3.14
三分之一:0.333
重力加速度(g):10.0
使用大十进制进行舍入
我们可以使用 BigDecimal 类的 round()方法对一个数字进行舍入。下面的代码演示了如何使用 BigDecimal 的 round()方法对十进制数进行舍入。
public static void main(String args[])
{
BigDecimal pi = new BigDecimal("3.14159265359");
pi = pi.setScale(4, RoundingMode.HALF_UP);
System.out.println("Pi: " + pi);
}
Pi: 3.1416
如果这个数字不是大十进制类型,那么我们可以先转换它,然后对它进行舍入。以下方法可用于舍入双数据类型的数字。
public static double round(double num, int places)
{
BigDecimal b = new BigDecimal(Double.toString(num));
b = b.setScale(places, RoundingMode.HALF_UP);
return b.doubleValue();
}
public static void main(String args[])
{
double pi = 3.14159265359;
double oneThird = 1.0/3.0;
double g = 9.807f;
pi = round(pi, 4);
oneThird = round(oneThird, 3);
g = round(g, 0);
System.out.println("Pi: " +pi);
System.out.println("One Third: " + oneThird);
System.out.println("Gravitation Acceleration(g):" + g);
}
Pi: 3.1416
三分之一:0.333
重力加速度(g):10.0
使用双舍入器舍入
DoubleRounder 是一个属于 decimal4j 库的实用程序类。它可以用来舍入数字,但有时会给出意想不到的结果。例如,当将 256.025 舍入到两位小数时,它返回 256.02 而不是 256.03。
public static void main(String args[])
{
double g = 9.807f;
System.out.println("Gravitation Acceleration(g):" + DoubleRounder.round(g, 1);
}
重力加速度(g):9.8
摘要
Java 为我们提供了很多舍入小数的方法。我们学习了如何使用 printf()和 DecimalFormat()格式化十进制数。我们还使用了 Math.round()方法和 BigDecimal 类来对一个数字进行舍入。