JSON anahtarlarının CSV'ye dönüştürülmesi sırasında JSON anahtarlarının sırasını koruyun


82

Sahip olduğum bir json dizesini CSV'ye dönüştürmek için http://www.json.org/java/index.html burada sağlanan JSON kitaplığını kullanıyorum . Ama benim sorunum, anahtarların sırasının dönüştürmeden sonra kaybolması.

Bu dönüşüm kodudur:

    JSONObject jo = new JSONObject(someString);
    JSONArray ja = jo.getJSONArray("items");
    String s = CDL.toString(ja);
    System.out.println(s);

Bu, "someString" içeriğidir:

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
    ]
}

Sonuç şu:

WO,QU,WR,QA,NO
hasd,asd,qwe,end,qwer

Beklediğim şey anahtarların sırasını korumak olsa da:

WR,QU,QA,WO,NO
qwe,asd,end,hasd,qwer

Bu kitaplığı kullanarak bu sonucu almamın bir yolu var mı? Değilse, sonuçta anahtarların sırasını muhafaza etme yeteneği sağlayacak başka bir kitaplık var mı?


4
Sözlükler sıralanmamış. JSON'un düzeni garanti ettiğini bile sanmıyorum.
Falmarri

2
bilgi için teşekkürler. Ancak uygulamamda JSON kullanmaktan başka seçeneğim yok ve uygulamamın anahtarların sırasını tutması gerekiyor :(
Hery

Benim durumumda mesele bir düzenin olmaması değil, deterministik olmaması. Bazen anahtarı anahtardan fooönce barve bazen de barönce alırım foo. Bu, için test yazmayı zorlaştırır.
Sridhar Sarnobat

Ben de bu ihtiyaçla karşılaştım, ancak gerçek zamanlı test sırasında hızlı günlük karşılaştırması için. Yüksek verimli bir uygulama için yeni oluşturulan günlükleri önceden oluşturulmuş günlüklerle gerçek zamanlı olarak karşılaştırmam gerekiyor. Bunu yapmanın başka yolları da var, ancak günlüklerin JSON biçiminde olmasını tercih ederim. Ancak, CPU kullanımını en aza indirmek için kendi doğrudan dizeye JSON yazıcımı yazıyorum. Dahili yapıya hiç ihtiyacım yok ve günlüklerin hızlı dize karşılaştırmaları için anahtar sırasını koruyabiliyorum. Öngörülebilir düzen istemek için iyi nedenler var.
Joe Lapp

JSON'u özel olarak sıralanmış bir CSV dosyasına dönüştürmek için kendi kodunuzu yazın, böylece her iki formatın da ne olması gerektiğine saygı duyarsınız.
Martijn Scheffer

Yanıtlar:


95

Bunu yapmanın (hacky) yolları var ... ama yapmamalısın.

JSON'da bir nesne şu şekilde tanımlanır:

Bir nesne, sıralanmamış bir ad / değer çiftleri kümesidir.

Bkz http://json.org .

JSON uygulamalarının çoğu, (tanım gereği) önemli olmadığı için bir nesnenin ad / değer çiftlerinin sırasını korumak için hiçbir çaba göstermez.

Düzenin korunmasını istiyorsanız, veri yapınızı yeniden tanımlamanız gerekir; Örneğin

{
    "items":
    [
        [
            {"WR":"qwe"},
            {"QU":"asd"},
            {"QA":"end"},
            {"WO":"hasd"},
            {"NO":"qwer"}
        ],
    ]
}

veya daha basitçe:

{
    "items":
    [
        {"WR":"qwe"},
        {"QU":"asd"},
        {"QA":"end"},
        {"WO":"hasd"},
        {"NO":"qwer"}
    ]
}

TAKİP ET

Bilgi için teşekkürler, ancak uygulamamda JSON kullanmaktan başka seçeneğim yok ve uygulamamın JSON nesnesinin tanımından bağımsız olarak anahtarların sırasını tutması gerekiyor ... JSON dosyasının formatını değiştirmeme izin verilmiyor ayrıca ...

Bu dosya yapısını tasarlayan kişiyle sıkı bir konuşma yapmanız gerekir ve onu değiştirmenize izin vermezsiniz. Açıkça yanlıştır. Sen lüzum onları ikna etmek.

Onlar ise gerçekten bunu değiştirmek izin vermez:

  • Sen ısrar etmelidir değil değil mi çünkü' ... JSON olarak nitelendirdi.
  • Bu "JSON değil" biçimini işlemek için özel olarak kod yazmanız / değiştirmeniz gerekeceğini belirtmelisiniz ... sırayı koruyan bir JSON uygulaması bulamazsanız. Ödeme yapan bir müşteriyse, yapmanız gereken bu ekstra iş için ödeme yaptıklarından emin olun.
  • "JSON değil" nin başka bir araç tarafından kullanılması gerekiyorsa bunun sorunlu olacağını belirtmelisiniz. Nitekim bu sorun defalarca ortaya çıkacaktır ...

Bu tür şeyler gerçekten çok kötü. Bir yandan, yazılımınız birlikte çalışabilirliği teşvik etmek için tasarlanmış, iyi oluşturulmuş / uzun süredir devam eden bir spesifikasyonu ihlal ediyor olacaktır. Öte yandan, bu topal tasarlanmış nit-fikir (değil JSON!) Dosya biçimi muhtemelen baş edemez sistemleri çünkü diğer insanların sistemlerini vb' kapalı slagging vardır onların saçma.

GÜNCELLEME

JSON RFC'nin (RFC 7159) bu konuda söylediklerini de okumaya değer . İşte bazı alıntılar:

RFC 4627'nin yayınlanmasından bu yana geçen yıllarda JSON çok geniş bir kullanım alanı bulmuştur. Bu deneyim, spesifikasyonların izin verdiği halde birlikte çalışabilirlik sorunlarına neden olan belirli kalıpları ortaya çıkardı.

JavaScript Object Notation (JSON), yapılandırılmış verilerin serileştirilmesi için bir metin formatıdır. ...

JSON, dört ilkel türü (dizeler, sayılar, mantıksallar ve boş) ve iki yapılandırılmış türü (nesneler ve diziler) temsil edebilir.

Bir nesne, sıfır veya daha fazla ad / değer çiftinin sıralanmamış bir koleksiyonudur; burada bir ad bir dizedir ve bir değer bir dize, sayı, boole, boş, nesne veya dizidir.

JSON ayrıştırma kitaplıklarının, nesne üyelerinin sırasını çağıran yazılım için görünür kılıp kılmadıklarına göre farklılık gösterdikleri gözlemlenmiştir. Davranışı üye sıralamasına bağlı olmayan uygulamalar, bu farklılıklardan etkilenmeyecekleri için birlikte çalışabilir olacaktır.


3
@YogeshSomani - "çözüm" uygun bir JSON kitaplığı elde etmek ve anahtar sırasını korumak için onu "kesmek". Bir örnek için Gary'nin cevabına bakın. Ancak, standart bir JSON kitaplığının bunu yapmasını beklememelisiniz çünkü bu, JSON belirtiminin bu şekilde kötüye kullanımını teşvik etmek için KÖTÜ bir FİKİRdir. Gerçek çözüm, uygulamanızı JSON'u doğru kullanacak şekilde düzeltmektir.
Stephen C

10
en saf ve mutlak olmak harika, ama kendimizi kandırmayalım, bir JSON dosyasının tanımlanmış değerlerinin korunmasına ihtiyaç duyduğu gerçek dünya senaryoları vardır. Bunları herhangi bir sırayla geçirmek ve kabul etmek temel bir json yaklaşımıdır, ancak bunu bir json belgesi alıp eşitlikte serileştirme / serileştirme yeteneğinden daha farklı buluyorum. Bir json belgesi almak ve siparişin korunması gereken başka bir standart WDDX, HTML vb. Belgesini oluşturmak için kullanmak zorunda olmak yaygın bir kullanım örneğidir
Andrew Norman

3
@AndrewNorman - "İhtiyaç" hakkında söylediklerin gerçekten doğruysa, o zaman şartname değiştirilmeli ve değişmeliydi. Gerçek şu ki, JSON'da siparişi başka şekillerde temsil etmek kolaydır.
Stephen C

2
JSON yalnızca bu bilgilerin anahtar sırasına göre kodlanmamasını gerektirir; aksi takdirde JSON değil. Serileştirmenin tutarlılığı farklı bir konudur. Tek bir uygulama içinde tutarlılık genellikle ortak bir JSON kitaplığı kullanılarak garanti edilebilir, ancak tek bir çözümün birden çok platformu veya çerçeveyi kapsaması gibi istisnalar vardır. Bu durumlarda, ya tutarsızlığın üstesinden gelmenin bir yolunu bulmalısınız (verimsizliğe yol açarak) ya da tutarlılığı sağlamanın bir yolunu bulmalısınız. Her iki yaklaşım da geçerlidir.
Joe Lapp

2
"JSON yalnızca bu bilgilerin anahtar sırasına göre kodlanmamasını gerektirir; aksi takdirde JSON değildir." . Sanırım yanlış yazdın. Doğru ifade şudur: "JSON, bilgilerin anahtar sırasına göre kodlanmasını gerektirmez". Bu iki ifade arasında büyük bir fark var ....
Stephen C

47

Düzeni korumak oldukça basittir. DB katmanından UI Katmanına sırayı korumakla aynı sorunu yaşadım.

JSONObject.java dosyasını açın. Dahili olarak sırayı korumayan HashMap kullanır.

LinkedHashMap olarak değiştirin:

    //this.map = new HashMap();
    this.map = new LinkedHashMap();

Bu benim için çalıştı. Yorumlarda bana bildirin. JSON kitaplığının kendisinin, JSONOrderdObject.java gibi düzeni koruyan başka bir JSONObject sınıfına sahip olmasını öneriyorum. İsimleri seçmekte çok yetersizim.


2
svn ödeme json-basit. org.json.simple.JSONObject dosyasını değiştirin, <code> JOSNObject LinkedHashMap'i genişletir ... </code> <code> .. HashMap .. </code> 'den içe aktarımı düzeltin ve benim için çalışıyor. v1.1.1.
Marku

2
Bu, denemeyi asla düşünemeyeceğim harika bir tek satırlık çözüm. Mükemmel çalışıyor ve diğer kodumun hiçbirini değiştirmem gerekmedi. +1
DaaaahWhoosh

Harika düzeltme. Sen bir kahramansın Sir konum
Gregory Nowakowski

işe yaramadı, içe aktarımı ekledim, dediğin gibi değiştirdim, hatta şu şekilde yapmaya çalıştım: this.map = new LinkedHashMap<String, Object>();hala çalışmıyor. Lütfen yardım et ?
Tarek

4
Haha gerçekten mi? JSON kitaplığını ihtiyaçlarınızı karşılayacak şekilde değiştiriyor musunuz? Bunun şirket bilgi tabanlarında düşeceğini hayal edebiliyorum. "Mvn'nizi temiz bir şekilde kurun, jar dosyasını indirin, bulun, derleyin, ardından HashMap'i LinkedHashMap ile değiştirin". Bu, çoklu geliştirici ekipleri için harika çalışacaktır (değil).
Chris Neve

23

JSONObject.javageçtiğiniz haritayı alır. Olabilir LinkedHashMapveya olabilir TreeMapve hashmapyalnızca harita boş olduğunda sürecektir .

İşte JSONObject.javaharitanın kontrolünü yapacak sınıfın kurucusu .

 public JSONObject(Map paramMap)
  {
    this.map = (paramMap == null ? new HashMap() : paramMap);
  }

Yani bir json nesne yapısı oluşturmadan LinkedHashMapve sonra bunu kurucuya bu şekilde iletmeden önce ,

LinkedHashMap<String, String> jsonOrderedMap = new LinkedHashMap<String, String>();

jsonOrderedMap.put("1","red");
jsonOrderedMap.put("2","blue");
jsonOrderedMap.put("3","green");

JSONObject orderedJson = new JSONObject(jsonOrderedMap);

JSONArray jsonArray = new JSONArray(Arrays.asList(orderedJson));

System.out.println("Ordered JSON Fianl CSV :: "+CDL.toString(jsonArray));

Yani JSONObject.javasınıfı değiştirmeye gerek yok . Umarım birine yardımcı olur.


3
İyi cevap, normal java için çalışıyor, ancak android'de çalışmıyor. Android'deki org.json.JSONObject'i kontrol ediyorum, android'in hala dahili olarak oluşturulmuş hashmap'i kullanması üzücü. Yalnızca paramMap'ten HashMap'e isim / değer çiftlerini kopyalar ... :(
正宗 白 布鞋

JsonObject sipariş ettim ama bu nesneyi bir JsonArray'e eklemeye çalıştığımda bana sırasız bir tane veriyor. Nesneyi diziye koymam gerekiyor, dizi nesnelerine ihtiyacım var sonra diziye başlık koyup geri gönderiyorum. Ör: bir nesne; {CUSTOMER_SECTOR_ID = 611, CUSTOMER_NO = 0000003204, CUSTOMER_NAME = MARMARİS - KARAS GIDA KARAS TÜKETİM MADDELERİ GIDA LOJ.} Diziye iki nesne koyarsam şunu elde ederim: [{"CUSTOMER_NAME": "SILA GIDA PAZUSTARLAMA", " 0000003122 "," CUSTOMER_SECTOR_ID ":" 611 "}, {" CUSTOMER_NAME ":" M ":" 0013114714 "," CUSTOMER_SECTOR_ID ":" 611 "}] Gördüğünüz gibi yanlış. Nasıl düzeltirim
Sahin Yanlık

2
@Deepak Nagaraj. Çözümünüzü denedim ama işe yaramadı, JSONObjectbenim olarak sipariş edilmedi LinkedHashMap. Eğer istimal org.jsonlib?
Ismail Sen

1
Bu o değil org.json.. HashMapİçsel olarak bir tanımlıyor , Mapona ne verirseniz verin: @Deepak, kullandığınız uygulamaya işaret edebilir misiniz?
Campa

8
Bu, org.jsonkütüphanede çalışmayacaktır . Yeni bir JSONObjectnesne oluşturduğunuzda, bir haritayı bağımsız değişken olarak ilettiğinizde, her zaman bir HashMap. Yapıcı ilk olarak yeni bir harita oluşturur: this.map = new HashMap<String, Object>();ve ardından haritanızın üzerinde döngü yaparak her öğeyi kendi haritasına kopyalayın HashMap.
itachi

13

Bu tür bir soruna daha ayrıntılı, ancak geniş anlamda uygulanabilir bir çözüm, bir çift veri yapısı kullanmaktır: sıralamayı içeren bir liste ve ilişkileri içeren bir harita.

Örneğin:

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
    ],
    "itemOrder":
        ["WR", "QU", "QA", "WO", "NO"]
}

Öğe Sipariş listesini yinelersiniz ve bunları harita değerlerini aramak için kullanırsınız. Sipariş, kludges olmadan korunur.

Bu yöntemi defalarca kullandım.


Haritanız yalnızca basit anahtar / değer çiftleri değilse bu karmaşık bir hal alır ...
zfj3ub94rf576hc4eegm

10

Reflektif kullanan başka bir hacky çözümü:

JSONObject json = new JSONObject();
Field map = json.getClass().getDeclaredField("map");
map.setAccessible(true);//because the field is private final...
map.set(json, new LinkedHashMap<>());
map.setAccessible(false);//return flag

1
Cevabınızı alamadım
M. Usman Khan

1
İşin püf noktası, varsayılan HashMap yerine bir LinkedHashMap kullanmak için sınıfı dahili olarak değiştirmektir, böylece JSON nesnesinin verileri sizin koyduğunuz sıraya sahip olmasını sağlar, bu doğrudan sıralanmaz, ancak ayrıştırılan veriler zaten sıralandığı için benim için çalıştı .
fabe

iyi görünüyor, ancak map.set SONRA Json String nasıl ayrıştırılır (json, new LinkedHashMap <> ()); çünkü yapıcıda Json String geçirilir değil mi? yeni JSONObject (jsonString) gibi.
M. Usman Khan

Ayrıca bu işe yaramadı. "harita" alanı yok, zaten LinckedHashMap olan bir "nameValuePairs" alanı var ve hala çalışmıyor.
M. Usman Khan

1
JSONObject'in hangi uygulamasını kullanıyorsunuz? Org.json 20140107 sürümünü kullanıyorum ve siparişi korumam gerekiyordu ve bu benim için nasıl çalıştı.
fabe


4

Sadece aynı soruna rastladım, yazarın kullandığı nihai çözümün özel bir ContainerFactory kullanmaktan oluştuğuna inanıyorum:

public static Values parseJSONToMap(String msgData) {
    JSONParser parser = new JSONParser();
    ContainerFactory containerFactory = new ContainerFactory(){
        @Override
        public Map createObjectContainer() {
            return new LinkedHashMap();
        }

        @Override
        public List creatArrayContainer() {
            return null;
        }
    };
    try {
        return (Map<String,Object>)parser.parse(msgData, containerFactory);
    } catch (ParseException e) {
        log.warn("Exception parsing JSON string {}", msgData, e);
    }
    return null;
}  

bkz. http://juliusdavies.ca/json-simple-1.1.1-javadocs/org/json/simple/parser/JSONParser.html#parse(java.io.Reader,org.json.simple.parser.ContainerFactory)


gerçekten çok iyi ve pratik bir çözüm. ContainerFactory için yöntem yerel anonim iç sınıf yazmaya ne dersiniz?
Shailesh Saxena

3

Çözüldü.

Buradan JSON.simple kütüphanesini kullanılan https://code.google.com/p/json-simple/ tuşlarının düzeni sağlamak ve buradan JavaCSV kütüphanesini kullanmak için JSON dizesi okumak için http://sourceforge.net/ projeler / javacsv / CSV formatına dönüştürmek için.


Bunun işe yaramasına şaşırdım. JSONObject sınıfının hem kodunu hem de yorumlarını okumama göre ( code.google.com/p/json-simple/source/browse/trunk/src/main/java/… ), korumak için hiçbir şey yapmıyor anahtarların sırası.
Stephen C

1
Burada tam çözümü belirtmedim, ancak işin özü, json-simple'ın json nesnelerini depolamak için kullanılan veri yapısını belirleyebileceğiniz bir fabrika sağlamasıdır. LinkedHashMap'i kullanmayı belirtmeniz yeterlidir.
Hery

@ Hery, aynı sorunla karşı karşıyayım ama çözemedim. Kullandığım org.jsondönüştürün List<LinkedHahMap>için JSONArraybir yaratmak için CSV, CSVama benim aynı sırada oluşturulur List . Burada sunduğunuz iki kitaplığı kullanmayı denedim, ancak dönüştürme yöntemlerini bulamadım. CSVLütfen daha fazla ayrıntı verir misiniz?
Ismail Sen

2

Bunun çözüldüğünü ve sorunun uzun zaman önce sorulduğunu biliyorum, ancak benzer bir sorunla uğraşırken, buna tamamen farklı bir yaklaşım vermek istiyorum:

Diziler için "Dizi, sıralı bir değerler koleksiyonudur" der. en http://www.json.org/ - ancak nesneler ( "bir amacı, isim / değer ikilileriyle bir sırasız kümesidir.") sıralanmaz.

Bu nesnenin neden bir dizide olduğunu merak ediyorum - bu orada olmayan bir düzen anlamına geliyor.

{
"items":
[
    {
        "WR":"qwe",
        "QU":"asd",
        "QA":"end",
        "WO":"hasd",
        "NO":"qwer"
    },
]
}

Dolayısıyla bir çözüm, anahtarları "gerçek" bir diziye koymak ve verileri aşağıdaki gibi her bir anahtara nesneler olarak eklemek olacaktır:

{
"items":
[
    {"WR": {"data": "qwe"}},
    {"QU": {"data": "asd"}},
    {"QA": {"data": "end"}},
    {"WO": {"data": "hasd"}},
    {"NO": {"data": "qwer"}}
]
}

Yani bu, orijinal modellemeyi ve amacını yeniden düşünmeye çalışan bir yaklaşım. Ancak, ilgili tüm araçların bu orijinal JSON dizisinin sırasını koruyup koruyamayacağını test etmedim (ve merak ediyorum).


1
bu anahtara bakmama izin vermiyor.
mickeymoon

O zaman ne istiyorsun - hash veya sipariş edilmiş bir şey !? İkisini birleştirmek istiyorsanız, ikisini de oluşturun ve bu yapılardan birinin diğerini indekslemesini sağlayın ... Aksi takdirde, bu daha çok bir tasarım problemi veya karışık ilgi alanları gibi görünüyor.
cslotty

1
İlgi alanlarını karıştırmakla ilgili değil, oldukça makul bir kullanım örneğidir, Java gibi dillerde ekleme sırasını koruyan sıralı bir harita olan LinkedHashMap gibi yapılar tarafından işlenir. O zaman ne istiyorum, hem tuşlar üzerinde tanımlanan sırayla yineleme yapabilmeyi hem de tuşlar üzerinde hızlı bir arama yapabilmeyi istiyorum. @Robotic Pants'in cevabının biraz hile olsa da oldukça işe yarayacağını düşünüyorum.
mickeymoon

Doğru mickeymoon, bunu söylemek üzereydim! Ama JSON'da bu mevcut değil, değil mi? O zaman size böyle bir şey sağlayan dilleri / mekanizmaları dahil etmeniz gerekir.
cslotty

1

Gerçek dünyada, bir uygulama neredeyse her zaman java bean'e veya JSON'a / JSON'dan serileştirilecek / serileştirilmesi gereken alana sahip olacaktır. JSON Nesne spesifikasyonunun düzeni garanti etmediğinden ve bu davranışa yönelik herhangi bir manipülasyonun gereksinimi haklı çıkarmadığından daha önce bahsedilmiştir. Sadece okunabilirlik amacıyla siparişi korumam gereken uygulamamda aynı senaryoya sahiptim. Java çekirdeğimi JSON'a serileştirmek için standart jackson yolunu kullandım:

Object object = getObject();  //the source java bean that needs conversion
String jsonString = new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(object);

Json'u sıralı bir öğe kümesiyle yapmak için, dönüşüm için kullandığım Java çekirdeğindeki JSON özellik açıklamasını kullanıyorum. Aşağıdaki bir örnek:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({"name","phone","city","id"})
public class SampleBean implements Serializable {
    private int id;
    private String name:
    private String city;
    private String phone;

    //...standard getters and setters
}

yukarıda kullanılan getObject ():

public SampleBean getObject(){
    SampleBean bean  = new SampleBean();
    bean.setId("100");
    bean.setName("SomeName");
    bean.setCity("SomeCity");
    bean.setPhone("1234567890");
    return bean;
}

Çıktı, Json özellik sipariş açıklamasına göre gösterilir:

{
    name: "SomeName",
    phone: "1234567890",
    city: "SomeCity",
    id: 100
}

0

En güvenli yol, muhtemelen çıktı oluşturmak için kullanılan anahtar yöntemini geçersiz kılmaktır:

new JSONObject(){
  @Override
  public Iterator keys(){
    TreeSet<Object> sortedKeys = new TreeSet<Object>();
    Iterator keys = super.keys();
    while(keys.hasNext()){
      sortedKeys.add(keys.next());
    }
    return sortedKeys.iterator();
  }
};

1
Bu belirtilen sorunu çözmez. Anahtarların sıralanmasına neden olur ... ancak soru, ekleme sırasının korunmasını ister.
Stephen C

0

patchFor (yanıt @gary):

$ git diff JSONObject.java                                                         
diff --git a/JSONObject.java b/JSONObject.java
index e28c9cd..e12b7a0 100755
--- a/JSONObject.java
+++ b/JSONObject.java
@@ -32,7 +32,7 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.Collection;
 import java.util.Enumeration;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
@@ -152,7 +152,9 @@ public class JSONObject {
      * Construct an empty JSONObject.
      */
     public JSONObject() {
-        this.map = new HashMap<String, Object>();
+//      this.map = new HashMap<String, Object>();
+        // I want to keep order of the given data:
+        this.map = new LinkedHashMap<String, Object>();
     }

     /**
@@ -243,7 +245,7 @@ public class JSONObject {
      * @throws JSONException
      */
     public JSONObject(Map<String, Object> map) {
-        this.map = new HashMap<String, Object>();
+        this.map = new LinkedHashMap<String, Object>();
         if (map != null) {
             Iterator<Entry<String, Object>> i = map.entrySet().iterator();
             while (i.hasNext()) {

0

JSON Dizisinin özel SİPARİŞ EDİLMİŞ serileştirmesi ve serisini kaldırması için aşağıdaki kodu kullanabilirsiniz (Bu örnek, Dizeleri sipariş ettiğinizi varsayar, ancak tüm türlere uygulanabilir):

Serileştirme

JSONArray params = new JSONArray();
int paramIndex = 0;

for (String currParam : mParams)
{
    JSONObject paramObject = new JSONObject();
    paramObject.put("index", paramIndex);
    paramObject.put("value", currParam);

    params.put(paramObject);
    ++paramIndex;
}

json.put("orderedArray", params);

Seriyi kaldırma

JSONArray paramsJsonArray = json.optJSONArray("orderedArray");
if (null != paramsJsonArray)
{
    ArrayList<String> paramsArr = new ArrayList<>();
    for (int i = 0; i < paramsJsonArray.length(); i++)
    {
        JSONObject param = paramsJsonArray.optJSONObject(i);
        if (null != param)
        {
            int paramIndex = param.optInt("index", -1);
            String paramValue = param.optString("value", null);

            if (paramIndex > -1 && null != paramValue)
            {
                paramsArr.add(paramIndex, paramValue);
            }
        }
    }
}

0

Örneğiniz:

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
        ...
    ]
}

"öğe siparişi" öğesi ekleyin

{
    "items":
    [
        {
            "WR":"qwe",
            "QU":"asd",
            "QA":"end",
            "WO":"hasd",
            "NO":"qwer"
        },
        ...
    ],
    "itemorder":["WR","QU","QA","WO","NO"]
}

Bu kod, sütun başlık satırı olmadan istenen çıktıyı üretir:

JSONObject output = new JSONObject(json);
JSONArray docs = output.getJSONArray("data");
JSONArray names = output.getJSONArray("itemOrder");
String csv = CDL.toString(names,docs);

Bu, CSV'nin başlığını kaldırdı, şimdi sıralarım var ancak başlıksız
Pedro Joaquín

0

jsonObject kullanmak yerine CsvSchema kullanmayı deneyin, onun yolu daha kolaydır ve nesneyi doğrudan csv'ye dönüştürür

CsvSchema schema = csvMapper.schemaFor(MyClass.class).withHeader();
        csvMapper.writer(schema).writeValueAsString(myClassList);

ve sizin pojo sahiptir sipariş kimliği mentains @JsonPropertyOrder içinde


0

Underscore-java , json okurken eleman siparişlerini tutar. Ben projenin koruyucusuyum.

String json = "{\n"
      + "    \"items\":\n"
      + "    [\n"
      + "        {\n"
      + "            \"WR\":\"qwe\",\n"
      + "            \"QU\":\"asd\",\n"
      + "            \"QA\":\"end\",\n"
      + "            \"WO\":\"hasd\",\n"
      + "            \"NO\":\"qwer\"\n"
      + "        }\n"
      + "    ]\n"
      + "}";
System.out.println(U.fromJson(json));

// {items=[{WR=qwe, QU=asd, QA=end, WO=hasd, NO=qwer}]}

-1

Göz kırpma çözümünü test etti ve iyi çalışıyor:

@Test
public void testJSONObject() {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("bbb", "xxx");
    jsonObject.put("ccc", "xxx");
    jsonObject.put("aaa", "xxx");
    jsonObject.put("xxx", "xxx");
    System.out.println(jsonObject.toString());
    assertTrue(jsonObject.toString().startsWith("{\"xxx\":"));
}

@Test
public void testWinkJSONObject() throws JSONException {
    org.apache.wink.json4j.JSONObject jsonObject = new OrderedJSONObject();
    jsonObject.put("bbb", "xxx");
    jsonObject.put("ccc", "xxx");
    jsonObject.put("aaa", "xxx");
    jsonObject.put("xxx", "xxx");
    assertEquals("{\"bbb\":\"xxx\",\"ccc\":\"xxx\",\"aaa\":\"xxx\",\"xxx\":\"xxx\"}", jsonObject.toString());
}

Maven bağımlılığı: <dependency> <groupId> org.apache.wink </groupId> <artifactId> wink-json4j </artifactId> <version> 1.4 </version> </dependency>
jgpelaez

2 yıl önce gönderilen @ cypressious ile aynı cevap. Ve örnek gerçek bir değer eklemiyor.
Stephen C
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.