JSONArray bauen

niclasburger

Mitglied
Hallo,

ich habe eine Methode welche aus verschiedene Datenbank Tabellen verschiedene Daten liefert (Systeme und die dazugehörigen Stationen ). Das Problem ist das ein System mehrer Stationen beherbergen kann. Dadurch wird mein JSONArray falsch zusammengebaut.

Ich weiß jedoch noch nicht so recht wie ich das Umbauen kann.
Zuerst dachte ich das ich mir immer das JSONObject hole und schaue ob es das schon gibt aber dann muss ich jedesmal durch alle JSONObjecte durchgehen und schauen ob es das schon gibt.
Vielleicht habt ihr ja Ideen oder Vorschläge.

So sieht mein JSON, für ein einzelnes System derzeit aus:
Code:
[
  {
    "Stations": [
      {
        "StationName": "Galileo",
        "LandingPadSize": "L",
        "MarketUpdatet": 1549594652,
        "DistandeToStar": 501,
        "Planetary": false,
        "Supply": 81738,
        "BuyPrice": 9079
      }
    ],
    "CommodityID": 42,
    "SystemName": "Sol",
    "NeedsPermit": true,
    "Distance": 0
  },
  {
    "Stations": [
      {
        "StationName": "Daedalus",
        "LandingPadSize": "L",
        "MarketUpdatet": 1549597578,
        "DistandeToStar": 211,
        "Planetary": false,
        "Supply": 123797,
        "BuyPrice": 9079
      }
    ],
    "CommodityID": 42,
    "SystemName": "Sol",
    "NeedsPermit": true,
    "Distance": 0
  },
  {
    "Stations": [
      {
        "StationName": "Columbus",
        "LandingPadSize": "L",
        "MarketUpdatet": 1549587077,
        "DistandeToStar": 2490,
        "Planetary": false,
        "Supply": 879,
        "BuyPrice": 9828
      }
    ],
    "CommodityID": 42,
    "SystemName": "Sol",
    "NeedsPermit": true,
    "Distance": 0
  },
  {
    "Stations": [
      {
        "StationName": "Titan City",
        "LandingPadSize": "L",
        "MarketUpdatet": 1549555633,
        "DistandeToStar": 5041,
        "Planetary": false,
        "Supply": 157,
        "BuyPrice": 10044
      }
    ],
    "CommodityID": 42,
    "SystemName": "Sol",
    "NeedsPermit": true,
    "Distance": 0
  },
  {
    "Stations": [
      {
        "StationName": "Burnell Station",
        "LandingPadSize": "M",
        "MarketUpdatet": 1549575902,
        "DistandeToStar": 359,
        "Planetary": false,
        "Supply": 433,
        "BuyPrice": 9571
      }
    ],
    "CommodityID": 42,
    "SystemName": "Sol",
    "NeedsPermit": true,
    "Distance": 0
  }
]

Allerdings sollte es so aussehen:
Code:
[
  {
    "Stations": [
      {
        "StationName": "Galileo",
        "LandingPadSize": "L",
        "MarketUpdatet": 1549594652,
        "DistandeToStar": 501,
        "Planetary": false,
        "Supply": 81738,
        "BuyPrice": 9079
      },
      {
        "StationName": "Daedalus",
        "LandingPadSize": "L",
        "MarketUpdatet": 1549597578,
        "DistandeToStar": 211,
        "Planetary": false,
        "Supply": 123797,
        "BuyPrice": 9079
      },
      {
        "StationName": "Columbus",
        "LandingPadSize": "L",
        "MarketUpdatet": 1549587077,
        "DistandeToStar": 2490,
        "Planetary": false,
        "Supply": 879,
        "BuyPrice": 9828
      },
      {
        "StationName": "Titan City",
        "LandingPadSize": "L",
        "MarketUpdatet": 1549555633,
        "DistandeToStar": 5041,
        "Planetary": false,
        "Supply": 157,
        "BuyPrice": 10044
      },
      {
        "StationName": "Burnell Station",
        "LandingPadSize": "M",
        "MarketUpdatet": 1549575902,
        "DistandeToStar": 359,
        "Planetary": false,
        "Supply": 433,
        "BuyPrice": 9571
      }
    ],
    "CommodityID": 42,
    "SystemName": "Sol",
    "NeedsPermit": true,
    "Distance": 0
  }
 
  //Nächstes System
]


Mein Code:
Java:
    public void getAllData( String currentSystemName, int radius, boolean inkSystemsWithPermissions,
            boolean inkPlanetaryStations,
            String commodityName, int count, double multiplayer, int maxAge )
    {
        JSONArray jsonArray = new JSONArray();

        double demand = count * multiplayer;
        int minDemand = (int)demand;

        //TODO UnixTime soll nicht von jetzt sondern von 00:00 zählen.
        long unixTime = System.currentTimeMillis() / 1000L;
        long maxCommodityAge = unixTime - TimeUnit.DAYS.toSeconds( maxAge );


        int commodityID =  commodityMapping.mapping( commodityName );

        String sqlOtherSystems = null;

        if( inkSystemsWithPermissions == true && inkPlanetaryStations == true )
        {
            sqlOtherSystems = SQL_SELECT_OTHER_SYSTEMS_TRUE_TRUE;
        }

        if( inkSystemsWithPermissions == true && inkPlanetaryStations == false )
        {
            sqlOtherSystems = SQL_SELECT_OTHER_SYSTEMS_TRUE_FALSE;
        }

        if( inkSystemsWithPermissions == false && inkPlanetaryStations == false )
        {
            sqlOtherSystems = SQL_SELECT_OTHER_SYSTEMS_FALSE_FALSE;
        }

        if( inkSystemsWithPermissions == false && inkPlanetaryStations == true )
        {
            sqlOtherSystems = SQL_SELECT_OTHER_SYSTEMS_FALSE_TRUE;
        }

        Connection connection = databaseHandler.connect();

        try (PreparedStatement pscs = connection.prepareStatement( SQL_SELECT_CURRENT_SYSTEM ))
        {
            pscs.setString( 1, currentSystemName );

            ResultSet rscs = pscs.executeQuery();

            float x_pos = rscs.getFloat( "x_pos" );
            float y_pos = rscs.getFloat( "y_pos" );
            float z_pos = rscs.getFloat( "z_pos" );

            try (PreparedStatement psos = connection.prepareStatement( sqlOtherSystems ))
            {
                psos.setInt( 1, commodityID );
                psos.setInt( 2, minDemand );
                psos.setLong( 3, maxCommodityAge );

                ResultSet rsos = psos.executeQuery();
                while( rsos.next() )
                {
                    float x_pos2 = rsos.getFloat( "x_pos" );
                    float y_pos2 = rsos.getFloat( "y_pos" );
                    float z_pos2 = rsos.getFloat( "z_pos" );


                    double x = x_pos - x_pos2;
                    double y = y_pos - y_pos2;
                    double z = z_pos - z_pos2;

                    double result = Math.sqrt( Math.pow( x, 2 ) + Math.pow( y, 2 ) + Math.pow( z, 2 ) );

                    if( result <= radius )
                    {
                        JSONObject jsonObject = new JSONObject();
                        JSONObject jsonObjectStation = new JSONObject();

                        JSONArray jsonArrayStations = new JSONArray();

                        jsonObject.put( "SystemName", rsos.getString( "system_name" ) );
                        jsonObject.put( "Distance", result );
                        jsonObject.put( "NeedsPermit", rsos.getBoolean( "needs_permit" ) );
                        jsonObject.put( "CommodityID", rsos.getInt( "commodity_id" ) );

                        jsonObjectStation.put( "StationName", rsos.getString( "station_name" ) );
                        jsonObjectStation.put( "LandingPadSize", rsos.getString( "max_landing_pad_size" ) );
                        jsonObjectStation.put( "DistandeToStar", rsos.getLong( "distance_to_star" ) );
                        jsonObjectStation.put( "MarketUpdatet", rsos.getLong( "market_updated_at" ) );
                        jsonObjectStation.put( "Planetary", rsos.getBoolean( "is_planetary" ) );
                        jsonObjectStation.put( "Supply", rsos.getLong( "supply" ) );
                        jsonObjectStation.put( "BuyPrice", rsos.getInt( "buy_price" ) );

                        jsonArrayStations.put( jsonObjectStation );
                        jsonArray.put( jsonObject );
                        jsonObject.put( "Stations", jsonArrayStations );

                    }
                }
            }
            catch( SQLException e )
            {
                e.printStackTrace();
            }
        }
        catch( SQLException e )
        {
            systemLogger.info( className, e.getMessage() );
        }

        SortSystems sortSystems = new SortSystems();
        List<JSONObject> sortedList =  sortSystems.sortSystems( jsonArray );
        systemLogger.info( className, sortedList.toString() );
    }



Ich hoffe ihr versteht was ich meine und könnt mir helfen.
Wenn etwas Fehlt schreibt einfach.

Mit freundlichen Grüßen

Niclas
 

mihe7

Top Contributor
Ich weiß jedoch noch nicht so recht wie ich das Umbauen kann.

Möglichkeit 1: Systems und Stations separat aus der DB abrufen.
Möglichkeit 2: Systems und Stations geordnet aus der DB abrufen.
Möglichkeit 3: via Map.

Unabhängig davon:
  1. Du darfst auch mehr als eine Methode schreiben.
  2. Du darfst auch eigene Klassen verwenden
  3. Du darfst die Suche nach passenden Systemen auch der DB überlassen (Radius)
 

niclasburger

Mitglied
Hi,
Danke für Deine Antwort.

Methode 1:
Das Problem ist die Datenmenge. Das soll eine RestApi werden. Das war jedoch zu langsam und hat über 10 Sekunden gedauert. Sind immerhin 20.000 Einträge Einträge in Systems.
Und 6 Millionen in den anderen zusammen.

Methode 2:
Dort ist das Problem das es keine fortlaufende Nummern oder sonst was gibt.

Methode 3:
Könntest du das bitte näher erklären ?

1: So hatte ich es vorher hat dadurch auch länger gedauert. Als jetzt so. Weiß jedoch nicht warum. Könnte mir denke weil ich ein Riesen Array immer übergeben musste. Weiß aber nicht genau ob es daran lag.
Aber ich kann es auch gerne nochmal versuchen.

2: Das ganze ist in einer einzelnen Klasse :)

3: Wie kann die Datenbank den Radius berrechnen ?


Danke schon mal für deine Antwort.
Sobald ich Zuhause bin kann ich mal ein paar Bilder von der Datenbank machen vielleicht hilft das weiter.

Niclas
 

httpdigest

Top Contributor
Die meisten Datenbankmanagementsysteme unterstützen in ihrem SQL-Dialekt auch beliebige Funktionen, z.B. MySQL, PostgreSQL und H2 (und wahrscheinlich alle) unterstützen die Quadratwurzel-Funktion (meist 'SQRT'):
Im SQL:
SQL:
... WHERE SQRT((x_pos-?)*(x_pos-?)+(y_pos-?)*(y_pos-?)+(z_pos-?)*(z_pos-?)) <= ?
In Java (gibt leider keine Named Parameter in Standard JDBC):
Java:
int param = ...;
for (int i = 0; i < 2; i++)
  psos.setDouble(param++, x_pos); // <- kommt aus rscs
for (int i = 0; i < 2; i++)
  psos.setDouble(param++, y_pos);
for (int i = 0; i < 2; i++)
  psos.setDouble(param++, z_pos);
psos.setDouble(param++, radius);

Da du aber anscheinend "spatial"/räumliche Daten verarbeitest, solltest du mal darüber nachdenken, eine Datenbankmanagementsystem mit spatial-index support zu nutzen (z.B. PostGIS für PostgreSQL).
 
Zuletzt bearbeitet:

mihe7

Top Contributor
@httpdigest hat Punkt 3. schon beantwortet. Wobei man sich im WHERE-Clause die Wurzel sparen kann.

Da ich mich in Eurer DB nicht auskenne, nehme ich im Folgenden einfach mal an, dass der Systemname eindeutig ist (bitte durch den richtigen Schlüssel ersetzen).

Methode 2:
Dort ist das Problem das es keine fortlaufende Nummern oder sonst was gibt.
Du kannst Dir die Systeme nach Systemname sortiert ausgeben lassen. Beim Iterieren schaust Du nach, ob der aktuelle Satz dem alten entspricht.

Pseudocode
Java:
String last = "";
JSONArray arr = new JSONArray();
while (rs.next()) {
    String key = rs.getString("SystemName");
    if (last.equals(key)) {
        // station zu arr hinzufügen
    } else {
        // arr ausgeben, dann
        arr = new JSONArray();
        last = key;
    }
}

Methode 3:
Könntest du das bitte näher erklären ?
Pseudocode
Java:
Map<String, JSONArray> systemStations = new HashMap<>();
while (rs.next()) {
    String key = rs.getString("SystemName");
    JSONArray arr = systemStations.computeIfAbsent(key, k -> new JSONArray());
    // arr ist das zu SystemName gehörende Station-Array
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
F 2 JsonArray vergleichen, geht es auch einfacher ? Allgemeine Java-Themen 3
Thallius JSONArray - the method length() is undefined for JSONArray Allgemeine Java-Themen 4
B Sehr großen Graph mit Verbindungen bauen und minimieren? Allgemeine Java-Themen 35
N 3D-Grafik 3D Grafik selber bauen Allgemeine Java-Themen 0
B Millionen bit lange zahl bauen? Allgemeine Java-Themen 7
B Simpler Eventlistener für Tastaturtaste bauen? Allgemeine Java-Themen 13
J Builder Klasse mit Lombok bauen Allgemeine Java-Themen 2
perlenfischer1984 Lombok Builder soll andere Klasse bauen Allgemeine Java-Themen 4
C Windows RCP Application unter Linux bauen lassen Allgemeine Java-Themen 3
R Zählvariable in String bauen Allgemeine Java-Themen 2
B einen color-chooser bauen, ähnliche Farben vermeiden Allgemeine Java-Themen 5
O JSON String bauen aus Liste Allgemeine Java-Themen 2
B k-d Tree in Java bauen Allgemeine Java-Themen 2
M Konstruktoraufruf dynamisch auswerten und SQL bauen Allgemeine Java-Themen 10
B In Anwendung jar file bauen Allgemeine Java-Themen 2
G Messenger bauen Allgemeine Java-Themen 4
M PlugIn für Klasse bauen Allgemeine Java-Themen 6
O grafisches Programm "bauen" Allgemeine Java-Themen 15
T Objekte eindeutig zerlegen und wieder zusammen bauen? Allgemeine Java-Themen 6
P Ansatz?: EncoderWrapper Klasse bauen? Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben