JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成(网络传输速率)。
JSON 语法是 JavaScript 对象表示语法的子集。
1. 数据在名称/值对中
2. 数据由逗号分隔
3. 花括号保存对象
4. 方括号保存数组
XML和JSON都使用结构化方法来标记数据,下面来做一个简单的比较。
用XML表示中国部分省市数据如下:
<?xml version="1.0" encoding="utf-8"?>
<country>
<name>中国</name>
<province>
<name>黑龙江</name>
<cities>
<city>哈尔滨</city>
<city>大庆</city>
</cities>
</province>
<province>
<name>广东</name>
<cities>
<city>广州</city>
<city>深圳</city>
<city>珠海</city>
</cities>
</province>
<province>
<name>台湾</name>
<cities>
<city>台北</city>
<city>高雄</city>
</cities>
</province>
<province>
<name>新疆</name>
<cities>
<city>乌鲁木齐</city>
</cities>
</province>
</country>
用JSON表示如下:
{
"name": "中国",
"province": [{ "name": "黑龙江", "cities": { "city": ["哈尔滨", "大庆"] } }, { "name": "广东", "cities": { "city": ["广州", "深圳", "珠海"] } }, { "name": "台湾", "cities": { "city": ["台北", "高雄"] } }, { "name": "新疆", "cities": { "city": ["乌鲁木齐"] } }] }
编码的可读性,xml有明显的优势,毕竟人类的语言更贴近这样的说明结构。json读起来更像一个数据块,读起来就比较费解了。不过,我们读起来费解的语言,恰恰是适合机器阅读,所以通过json的索引.province[0].name就能够读取“黑龙江”这个值。
编码的手写难度来说,xml还是舒服一些,好读当然就好写。不过写出来的字符JSON就明显少很多。去掉空白制表以及换行的话,JSON就是密密麻麻的有用数据,而xml却包含很多重复的标记字符。
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class JsonTest {
public static void main(String[] args) {
String s=creatJson();
if(s!=null){ //解析JSON文本
JSONObject clazz=JSONObject.fromObject(s);
System.out.println("班级:"+clazz.getString("班级"));
System.out.println("班级人数:"+clazz.getString("班级人数"));
JSONArray array=clazz.getJSONArray("学生");
for (int i = 0; i < array.size(); i++) {
JSONObject obj =array.getJSONObject(i);
System.out.print("学生姓名:"+obj.getString("姓名")+"\t");
System.out.println("学生年龄:"+obj.getString("年龄"));
}
}
}
private static String creatJson() {//生成JSON文本格式
JSONObject obj1 = new JSONObject();
obj1.put("姓名", "张三");
obj1.put("年龄", "18");
JSONObject obj2 = new JSONObject();
obj2.put("姓名", "李四");
obj2.put("年龄", "19");
JSONObject obj3 = new JSONObject();
obj3.put("姓名", "王五");
obj3.put("年龄", "20");
JSONArray array = new JSONArray();
array.add(obj1);
array.add(obj2);
array.add(obj3);
JSONObject clazz = new JSONObject();
clazz.put("班级", "2012163");
clazz.put("班级人数", "27");
clazz.put("学生", array);
System.out.println(clazz.toString());
return clazz.toString();
}
}
运行结果:
另一种生成JSON文本的方法
//创建一个Student类
public class Student {
private String name;
private int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
public int getage() {
return age;
}
public void setage(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
创建JsonTest类
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class JsonTest {
public static void main(String[] args) {
Student zhangsan = new Student("张三", 12);
Student lisi = new Student("李四", 12);
Student wangwu = new Student("王五", 12);
Student zhaoliu = new Student("赵六", 12);
JSONObject obj= new JSONObject();
JSONArray array = new JSONArray();
array.add(zhangsan);
array.add(lisi);
array.add(wangwu);
array.add(zhaoliu);
obj.put("学生", array);
System.out.println(obj.toString());
}
}
运行结果:
Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
Date() 分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒)。
public long getTime()返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
它是一个抽象类
import java.util.Calendar;
import java.util.Date;
public class ShiJian {
public static void main(String[] args) {
Date date = new Date();
System.out.println(date);
System.out.println(date.getTime());//返回格林尼治时间之后的毫秒数
Calendar cal= Calendar.getInstance();
System.out.println(cal.getTime());
System.out.println(cal.getTimeInMillis());//返回格林尼治时间之后的毫秒数
System.out.println(cal.get(Calendar.YEAR)+"年"+(cal.get(Calendar.MONTH)+1)+"月"+cal.get(Calendar.DATE)+"日");
cal.add(Calendar.DATE, 50);//往后加50天的时间
System.out.println(cal.get(Calendar.YEAR)+"年"+(cal.get(Calendar.MONTH)+1)+"月"+cal.get(Calendar.DATE)+"日");
}
}
SimpleDateFormat 是一个以与语言环境有关的方式来格式化和解析日期的具体类。它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)和规范化。
SimpleDateFormat()
用默认的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Time {
public static void main(String[] args) {
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd kk:mm:ss");
System.out.println(format.format(date));//按所要格式输出当前时间
String s = "2015/07/24 11:40:20";
try {
Date date1 = format.parse(s);//按格式解析一个时间字符串
System.out.println(date1.getDate());
} catch (ParseException e) {
e.printStackTrace();
}
}
}
ArrayList里边的元素不唯一,有序。
内存空间连续。
元素遍历快,增删慢。
java.util.Collections
1.public static <T extends Comparable<? super T>> void sort(List<T> list)
根据元素的自然顺序 对指定列表按升序进行排序。列表中的所有元素都必须实现 Comparable 接口。
2.public static <T> void sort(List<T> list,Comparator<? super T> c)
根据指定比较器产生的顺序对指定列表进行排序。
Comparator接口的方法:public int compare(T o1,T o2)比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。
创建一个Student 类
public class Student {
private String name;
private int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
public int getage() {
return age;
}
public void setage(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
编写一个比较的类
import java.util.Comparator;
public class paixu implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
return s1.getage() - s2.getage();//按年龄大小排序
}
}
创建JiheTset类
mport java.util.ArrayList;
import java.util.Collections;
public class JiheTest { //ArrayList
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<Student>();
Student zhangsan= new Student("张三", 11);
Student lisi= new Student("李四", 12);
Student wangwu= new Student("王五", 13);
list.add(zhangsan);
list.add(lisi);
list.add(wangwu);
list.add(1, wangwu);
list.get(3).setName("我换了个名字");
System.out.println(list.size());
Collections.sort(list, new paixu());//排序
for(Student s:list){ //foreach语句
System.out.println(s.getName());
}
}
}
元素唯一,无序。
此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
//随机生成10个随机数,放入一个HashSet中
public class Demo { //HashSet
public static void main(String[] args) {
HashSet<Integer> set = new HashSet<Integer>();
Random random = new Random();
while (set.size() < 10) {
int i = random.nextInt(90) + 10;
set.add(i);
}
Iterator<Integer> it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
System.out.println(set.size());
}
}
存在一个K到V的一一映射,且K值不允许重复。
K - 此映射所维护的键的类型,V - 所映射值的类型
基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
创建一个Student类
public class Student {
private String name;
private int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
public int getage() {
return age;
}
public void setage(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
创建Test类
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
public class Test {
public static void main(String[] args) {
HashMap<Integer, Student> map = new HashMap<>();
Student zhangsan = new Student("张三", 18);
Student lisi = new Student("李四", 19);
Student wangwu = new Student("王五", 20);
map.put(201216301, zhangsan);
map.put(201216302, lisi);
map.put(201216303, wangwu);
Set<Integer> keys = map.keySet();
Iterator<Integer> it = keys.iterator();
while (it.hasNext()) {
Integer i = it.next();
System.out.println(i + "----" + map.get(i).getName());
}
//另一种写法
for (Integer key : map.keySet()) {
System.out.println(key + "----" + (String) map.get(key).getName());
}
}
}
运行结果:
ArrayList<Integer> list = new ArrayList<Integer>();
<>中写的数据类型必须是封装类和引用数据类型
HashMap<String,String> map = new HashMap<String,String>();
public class 类名<T>{
private T 变量名1;
private T 变量名1;
}
[访问权限修饰符] [static] [final] <类型参数列表> 返回值类型 方法名([形式参数列表])
public static <T extends Comparable> Pair<T> minmax(T[] a) //<T extends Comparable> 是指 类型参数列表
【方法中传入或返回的泛型类型由调用方法时所设置的参数类型所决定。】可用extends 和 super 关键字分别来指定上限和下限类型。
Pair 是返回值。minmax 方法名,T[] a 形式参数列表
创建Pair泛型类
public class Pair<T> {
private T first;
private T second;
public Pair(){
first=null;
second=null;
}
public Pair(T first,T second){
this.first=first;
this.second=second;
}
public T getFirst() {
return first;
}
public void setFirst(T first) {
this.first = first;
}
public T getSecond() {
return second;
}
public void setSecond(T second) {
this.second = second;
}
}
创建ArrayAlg类
public class ArrayAlg {
public static <T extends Comparable<T>> Pair<T> minmax(T[] a) {
if (a == null || a.length == 0) {
return null;
}
T min = a[0];
T max = a[0];
for (int i = 0; i < a.length; i++) {
if (min.compareTo(a[i]) > 0) {
min = a[i];
}
if (max.compareTo(a[i]) < 0) {
max = a[i];
}
}
return new Pair<T>(min,max);
}
}
创建Test类
public class Test {
public static void main(String[] args) {
Integer[]a={1,2,3,4};
Pair<Integer> pair = ArrayAlg.minmax(a);
System.out.println("最小值为:"+pair.getFirst());
System.out.println("最大值为:"+pair.getSecond());
}
}
用法一:常量
在JDK1.5之前,我们定义常量都是:publicstaticfianl….。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。
public enum Color {
RED, GREEN, BLANK, YELLOW
}
用法二:switch
JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。
enum Signal {
GREEN, YELLOW, RED
}
public class TrafficLight {
Signal color = Signal.RED;
public void change() {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
}
用法三:向枚举中添加新方法
如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且Java要求必须先定义enum实例。
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
// 普通方法
public static String getName(int index) {
for (Color c : Color.values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
}
// get set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
用法四:覆盖枚举的方法
下面给出一个toString()方法覆盖的例子。
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//覆盖方法
@Override
public String toString() {
return this.index+"_"+this.name;
}
}
用法五:实现接口
所有的枚举都继承自java.lang.Enum类。由于Java不支持多继承,所以枚举对象不能再继承其他类。
public interface Behaviour {
void print();
String getInfo();
}
public enum Color implements Behaviour{
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//接口方法
@Override
public String getInfo() {
return this.name;
}
//接口方法
@Override
public void print() {
System.out.println(this.index+":"+this.name);
}
}
用法六:使用接口组织枚举
public interface Food {
enum Coffee implements Food{
BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO
}
enum Dessert implements Food{
FRUIT, CAKE, GELATO
}
}
用法七:关于枚举集合的使用
java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的key是enum类型,而value则可以是任意类型。关于这个两个集合的使用就不在这里赘述,可以参考JDK文档。
public enum Color {//枚举
RED,ORANGE,YELLOW,GREEN,BULE,PURPLE
}
创建Test类
public class Test {
public static void main(String[] args) {
Color color = Color.RED;
switch (color) {
case RED:
System.out.println("这是红色");
break;
case ORANGE:
System.out.println("这是橙色");
break;
case YELLOW:
System.out.println("这是黄色");
break;
default:
break;
}
}
}