使用Jackson通过JSON文件的键选择值

huangapple go评论56阅读模式
英文:

selection of values by keys of json file using jackson

问题

以下是完成任务的步骤:

步骤 1: 导入所需的Jackson库

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

步骤 2: 创建数据类 Data

public class Data {
    private int id;
    private String firstName;
    private String lastName;
    private String dateOfBirth;
    private String city;

    // 构造函数、Getter和Setter方法等...
}

步骤 3: 在主类中读取JSON文件并解析数据

public class Main {
    public static void main(String[] args) {
        ObjectMapper mapper = new ObjectMapper();

        try {
            List<Data> data = Arrays.asList(mapper.readValue(Paths.get("C:\\data.json").toFile(), Data[].class));
            
            // 输出解析后的数据
            System.out.println(data);

        } catch (JsonParseException jsonParseException) {
            jsonParseException.printStackTrace();
        } catch (JsonMappingException jsonMappingException) {
            jsonMappingException.printStackTrace();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }
}

步骤 4: 进行数据处理以满足任务要求

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        ObjectMapper mapper = new ObjectMapper();

        try {
            List<Data> data = Arrays.asList(mapper.readValue(Paths.get("C:\\data.json").toFile(), Data[].class));

            // 1. 获取年龄在20到30之间的人,按姓名排序
            List<Data> peopleBetween20And30 = data.stream()
                .filter(person -> person.getAge() >= 20 && person.getAge() <= 30)
                .sorted(Comparator.comparing(Data::getFirstName))
                .collect(Collectors.toList());

            // 2. 获取唯一的城市列表
            HashSet<String> uniqueCities = data.stream()
                .map(Data::getCity)
                .collect(Collectors.toCollection(HashSet::new));

            // 3. 获取不同年龄区间的人数
            Map<String, Long> ageGroupCounts = data.stream()
                .collect(Collectors.groupingBy(Data::getAgeGroup, Collectors.counting()));

            // 输出结果
            System.out.println("People between 20 and 30: " + peopleBetween20And30);
            System.out.println("Unique cities: " + uniqueCities);
            System.out.println("Age group counts: " + ageGroupCounts);

        } catch (JsonParseException jsonParseException) {
            jsonParseException.printStackTrace();
        } catch (JsonMappingException jsonMappingException) {
            jsonMappingException.printStackTrace();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }
}

请注意,上述代码假定 Data 类具有名为 getAge()getAgeGroup() 的方法,用于计算年龄和年龄区间。你需要在 Data 类中添加这些方法,以及其他必要的辅助方法。

以上就是完成任务的基本步骤和代码。希望这对你有所帮助!如果有任何问题,请随时问我。

英文:

This is possibly the dumbest question on the entire site. I am new to Java and JSON and I need help. I am using API Jackson. The program receives a JSON file. From it I need to get:

  1. List of people between the ages of 20 and 30, sorted by name
  2. Unique list of cities;
  3. The number of people with an age interval of 0-10, 11-20, 21-30 and so on.

At the moment I have learned how to translate a json file into a List java

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
try {
List&lt;Data&gt; data = Arrays.asList(mapper.readValue(Paths.get(&quot;C:\\data.json&quot;).toFile(), Data[].class));
System.out.println(data);
} catch (JsonParseException jsonParseException) {
jsonParseException.printStackTrace();
} catch (JsonMappingException jsonMappingException) {
jsonMappingException.printStackTrace();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}

A class was created to read the json file

public class Data {
private int id;
private String firstName;
private String lastName;
private String dateOfBirth;
private String city;
public Data(int id, String firstName, String lastName, String dateOfBirth, String city) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.dateOfBirth = dateOfBirth;
this.city = city;
}
public Data() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(String dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return &quot;[id = &quot; + id + &quot;, firstName = &quot; + firstName + &quot;, lastName = &quot; + lastName + &quot;, dateOfBirth = &quot; + dateOfBirth + &quot;, city = &quot; + city + &quot;]&quot;;
}
}

Json file looks like this

[
{
&quot;id&quot;: &quot;1&quot;,
&quot;firstName&quot;: &quot;Lesley&quot;,
&quot;lastName&quot;: &quot;Bryan&quot;,
&quot;dateOfBirth&quot;: &quot;11/28/61&quot;,
&quot;city&quot;: &quot;Southampton–Portsmouth&quot;
},
{
&quot;id&quot;: &quot;2&quot;,
&quot;firstName&quot;: &quot;Edward&quot;,
&quot;lastName&quot;: &quot;Houston&quot;,
&quot;dateOfBirth&quot;: &quot;10/5/92&quot;,
&quot;city&quot;: &quot;Southampton–Portsmouth&quot;
},
{
&quot;id&quot;: &quot;3&quot;,
&quot;firstName&quot;: &quot;Donald&quot;,
&quot;lastName&quot;: &quot;Ross&quot;,
&quot;dateOfBirth&quot;: &quot;12/10/79&quot;,
&quot;city&quot;: &quot;Glasgow&quot;
},
{
&quot;id&quot;: &quot;4&quot;,
&quot;firstName&quot;: &quot;Peter&quot;,
&quot;lastName&quot;: &quot;Kelly&quot;,
&quot;dateOfBirth&quot;: &quot;3/17/04&quot;,
&quot;city&quot;: &quot;Birmingham–Wolverhampton&quot;
},
{
&quot;id&quot;: &quot;5&quot;,
&quot;firstName&quot;: &quot;Anthony&quot;,
&quot;lastName&quot;: &quot;McKinney&quot;,
&quot;dateOfBirth&quot;: &quot;3/6/68&quot;,
&quot;city&quot;: &quot;Liverpool&quot;
},
{
&quot;id&quot;: &quot;6&quot;,
&quot;firstName&quot;: &quot;David&quot;,
&quot;lastName&quot;: &quot;Stewart&quot;,
&quot;dateOfBirth&quot;: &quot;4/11/73&quot;,
&quot;city&quot;: &quot;Leeds–Bradford&quot;
},
{
&quot;id&quot;: &quot;7&quot;,
&quot;firstName&quot;: &quot;Christopher&quot;,
&quot;lastName&quot;: &quot;Austin&quot;,
&quot;dateOfBirth&quot;: &quot;12/28/74&quot;,
&quot;city&quot;: &quot;Birmingham–Wolverhampton&quot;
},
{
&quot;id&quot;: &quot;8&quot;,
&quot;firstName&quot;: &quot;Alvin&quot;,
&quot;lastName&quot;: &quot;Hodge&quot;,
&quot;dateOfBirth&quot;: &quot;11/25/58&quot;,
&quot;city&quot;: &quot;Newcastle upon Tyne–Sunderland&quot;
},
{
&quot;id&quot;: &quot;9&quot;,
&quot;firstName&quot;: &quot;Gerald&quot;,
&quot;lastName&quot;: &quot;Higgins&quot;,
&quot;dateOfBirth&quot;: &quot;6/28/55&quot;,
&quot;city&quot;: &quot;Liverpool&quot;
},
{
&quot;id&quot;: &quot;10&quot;,
&quot;firstName&quot;: &quot;Amos&quot;,
&quot;lastName&quot;: &quot;Owens&quot;,
&quot;dateOfBirth&quot;: &quot;1/16/01&quot;,
&quot;city&quot;: &quot;Manchester-Salford&quot;
},
{
&quot;id&quot;: &quot;11&quot;,
&quot;firstName&quot;: &quot;Christian&quot;,
&quot;lastName&quot;: &quot;Bishop&quot;,
&quot;dateOfBirth&quot;: &quot;11/14/50&quot;,
&quot;city&quot;: &quot;Nottingham&quot;
},
{
&quot;id&quot;: &quot;12&quot;,
&quot;firstName&quot;: &quot;Robert&quot;,
&quot;lastName&quot;: &quot;Caldwell&quot;,
&quot;dateOfBirth&quot;: &quot;12/8/80&quot;,
&quot;city&quot;: &quot;Manchester-Salford&quot;
},
{
&quot;id&quot;: &quot;13&quot;,
&quot;firstName&quot;: &quot;Brian&quot;,
&quot;lastName&quot;: &quot;Heath&quot;,
&quot;dateOfBirth&quot;: &quot;9/23/02&quot;,
&quot;city&quot;: &quot;Newcastle upon Tyne–Sunderland&quot;
},
{
&quot;id&quot;: &quot;14&quot;,
&quot;firstName&quot;: &quot;Mark&quot;,
&quot;lastName&quot;: &quot;Anthony&quot;,
&quot;dateOfBirth&quot;: &quot;1/8/92&quot;,
&quot;city&quot;: &quot;London&quot;
},
{
&quot;id&quot;: &quot;15&quot;,
&quot;firstName&quot;: &quot;Mark&quot;,
&quot;lastName&quot;: &quot;Watson&quot;,
&quot;dateOfBirth&quot;: &quot;7/27/91&quot;,
&quot;city&quot;: &quot;Nottingham&quot;
},
{
&quot;id&quot;: &quot;16&quot;,
&quot;firstName&quot;: &quot;Charles&quot;,
&quot;lastName&quot;: &quot;Stafford&quot;,
&quot;dateOfBirth&quot;: &quot;1/26/90&quot;,
&quot;city&quot;: &quot;Birmingham–Wolverhampton&quot;
},
{
&quot;id&quot;: &quot;17&quot;,
&quot;firstName&quot;: &quot;Steven&quot;,
&quot;lastName&quot;: &quot;Merritt&quot;,
&quot;dateOfBirth&quot;: &quot;12/4/63&quot;,
&quot;city&quot;: &quot;Leeds–Bradford&quot;
},
{
&quot;id&quot;: &quot;18&quot;,
&quot;firstName&quot;: &quot;John&quot;,
&quot;lastName&quot;: &quot;Holmes&quot;,
&quot;dateOfBirth&quot;: &quot;4/22/52&quot;,
&quot;city&quot;: &quot;Southampton–Portsmouth&quot;
},
{
&quot;id&quot;: &quot;19&quot;,
&quot;firstName&quot;: &quot;Mervin&quot;,
&quot;lastName&quot;: &quot;Lewis&quot;,
&quot;dateOfBirth&quot;: &quot;10/27/95&quot;,
&quot;city&quot;: &quot;Birmingham–Wolverhampton&quot;
},
{
&quot;id&quot;: &quot;20&quot;,
&quot;firstName&quot;: &quot;Peter&quot;,
&quot;lastName&quot;: &quot;Marsh&quot;,
&quot;dateOfBirth&quot;: &quot;12/10/63&quot;,
&quot;city&quot;: &quot;Glasgow&quot;
},
{
&quot;id&quot;: &quot;21&quot;,
&quot;firstName&quot;: &quot;Piers&quot;,
&quot;lastName&quot;: &quot;Harrington&quot;,
&quot;dateOfBirth&quot;: &quot;4/27/85&quot;,
&quot;city&quot;: &quot;London&quot;
},
{
&quot;id&quot;: &quot;22&quot;,
&quot;firstName&quot;: &quot;Matthew&quot;,
&quot;lastName&quot;: &quot;O’Brien’&quot;,
&quot;dateOfBirth&quot;: &quot;1/19/59&quot;,
&quot;city&quot;: &quot;Manchester-Salford&quot;
}
]

Please tell me in what sequence of actions to complete the task. Once again I apologize for such a stupid message.
P.S.: All names, surnames and dates from the json file were obtained at random.

答案1

得分: 0

首先,您需要更新 Data 类以便处理年龄和年龄组:

  1. dateOfBirth 的类型更改为 LocalDate,更新构造函数/获取器/提供自定义的设置器以处理 20 世纪的日期
  2. 添加方法以获取年龄(以年为单位)和年龄组(以字符串形式)
  3. 更新 toString 方法以打印年龄
class Data {
// ...
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "M/d/yy")
	private LocalDate dateOfBirth;

    public LocalDate getDateOfBirth() {
	    return dateOfBirth;
	}

	public void setDateOfBirth(LocalDate dob) {
	    if (dob.isAfter(LocalDate.now())) {
	    	dob = dob.minusYears(100);
	    }
	    this.dateOfBirth = dob;
	}

    @JsonIgnore
	public int getAge() {
	    return Period.between(dateOfBirth, LocalDate.now()).getYears();
	}
	    
	@JsonIgnore
	public String getAgeGroup() {
	    int age = getAge();
	    if (age < 11) {
	    	return "0..10";
	    }
	    return (age/10*10+1) + ".." + ((age/10 + 1) * 10);
	}

    @Override
	public String toString() {
	    return "[id = " + id + ", age=" + getAge() + ", firstName = " + firstName + ", lastName = " + lastName + ", dateOfBirth = " + dateOfBirth + ", city = " + city + "]";
	}
}

然后,您可以从输入列表中获取所需的数据子集:

// 获取年龄在 20 到 30 岁之间的人,按姓氏/名字排序
List<Data> age20to30 = data
        .stream()
    	.filter(p -> p.getAge() >= 20 && p.getAge() < 30)
    	.sorted(Comparator.comparing(p -> p.getLastName() + " " + p.getFirstName()))
    	.collect(Collectors.toList());
age20to30.forEach(System.out::println);

// 获取唯一城市的排序列表(使用 TreeSet 作为 SortedSet)
Set<String> cities = data
        .stream()
    	.map(Data::getCity)
    	.collect(Collectors.toCollection(TreeSet::new));
cities.forEach(System.out::println);

// 按年龄组获取统计信息
Map<String, Long> byAges = data
        .stream()
    	.collect(Collectors.groupingBy(Data::getAgeGroup, TreeMap::new, Collectors.counting()));
System.out.println(byAges);

输出

[id = 14, age=28, firstName = Mark, lastName = Anthony, dateOfBirth = 1992-01-08, city = London]
[id = 2, age=27, firstName = Edward, lastName = Houston, dateOfBirth = 1992-10-05, city = Southampton–Portsmouth]
[id = 19, age=24, firstName = Mervin, lastName = Lewis, dateOfBirth = 1995-10-27, city = Birmingham–Wolverhampton]
[id = 15, age=29, firstName = Mark, lastName = Watson, dateOfBirth = 1991-07-27, city = Nottingham]

Birmingham–Wolverhampton
Glasgow
Leeds–Bradford
Liverpool
London
Manchester-Salford
Newcastle upon Tyne–Sunderland
Nottingham
Southampton–Portsmouth

{11..20=3, 21..30=4, 31..40=3, 41..50=3, 51..60=4, 61..70=5}
英文:

First, you need to update Data class to facilitate handling of ages and age groups:

  1. Change type of dateOfBirth to LocalDate, update constructor/getter/provide custom setter to handle dates in the 20-th century
  2. Add methods to get age in years and age group as String:
  3. Update toString to print age
class Data {
// ...
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = &quot;M/d/yy&quot;)
	private LocalDate dateOfBirth;

    public LocalDate getDateOfBirth() {
	    return dateOfBirth;
	}

	public void setDateOfBirth(LocalDate dob) {
	    if (dob.isAfter(LocalDate.now())) {
	    	dob = dob.minusYears(100);
	    }
	    this.dateOfBirth = dob;
	}

    @JsonIgnore
	public int getAge() {
	    return Period.between(dateOfBirth, LocalDate.now()).getYears();
	}
	    
	@JsonIgnore
	public String getAgeGroup() {
	    int age = getAge();
	    if (age &lt; 11) {
	    	return &quot;0..10&quot;;
	    }
	    return (age/10*10+1) + &quot;..&quot; + ((age/10 + 1) * 10);
	}

    @Override
	public String toString() {
	    return &quot;[id = &quot; + id + &quot;, age=&quot; + getAge() + &quot;, firstName = &quot; + firstName + &quot;, lastName = &quot; + lastName + &quot;, dateOfBirth = &quot; + dateOfBirth + &quot;, city = &quot; + city + &quot;]&quot;;
	}
}

Then you can get required subsets of data from the input list:

// get people aged from 20 to 30 sorted by last name/first name
List&lt;Data&gt; age20to30 = data
        .stream()
    	.filter(p -&gt; p.getAge() &gt;= 20 &amp;&amp; p.getAge() &lt; 30)
    	.sorted(Comparator.comparing(p -&gt; p.getLastName() + &quot; &quot; + p.getFirstName()))
    	.collect(Collectors.toList());
age20to30.forEach(System.out::println);

// get sorted list of unique cities (using TreeSet as a SortedSet)
Set&lt;String&gt; cities = data
        .stream()
    	.map(Data::getCity)
    	.collect(Collectors.toCollection(TreeSet::new));
cities.forEach(System.out::println);

// get stats by age groups
Map&lt;String, Long&gt; byAges = data
        .stream()
    	.collect(Collectors.groupingBy(Data::getAgeGroup, TreeMap::new, Collectors.counting()));
System.out.println(byAges);

Output

[id = 14, age=28, firstName = Mark, lastName = Anthony, dateOfBirth = 1992-01-08, city = London]
[id = 2, age=27, firstName = Edward, lastName = Houston, dateOfBirth = 1992-10-05, city = Southampton–Portsmouth]
[id = 19, age=24, firstName = Mervin, lastName = Lewis, dateOfBirth = 1995-10-27, city = Birmingham–Wolverhampton]
[id = 15, age=29, firstName = Mark, lastName = Watson, dateOfBirth = 1991-07-27, city = Nottingham]
Birmingham–Wolverhampton
Glasgow
Leeds–Bradford
Liverpool
London
Manchester-Salford
Newcastle upon Tyne–Sunderland
Nottingham
Southampton–Portsmouth
{11..20=3, 21..30=4, 31..40=3, 41..50=3, 51..60=4, 61..70=5}

huangapple
  • 本文由 发表于 2020年9月26日 20:05:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/64077482.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定