1

I'm using www.opensubtitles.org API to get subtitles using file hash. Now, my problem is that it returns all the available subtitles for that particular file.

for example: I get this result when I select one file to download subtitles

https://i.stack.imgur.com/m2tZM.png

The whole result is here: http://privatepaste.com/download/22bb756930

The only difference between them is subtitle id and subtitle download links rest everything is same.

Now my problem is that this result is only for 1 file but I'll be using multiple files so it's not possible to get the first most result and use it.

The code to retrieve the result is given below

    Map<?, ?> result = (Map<?, ?>) rpcClient.execute("SearchSubtitles", params);
    Object[] data = (Object[]) result.get("data");
    Map<?, ?>[] results = new Map<?, ?>[data.length];
    int i = 0;
    for (Object element : data) {
        results[i] = (Map<?, ?>) element; //storing it in map
        i++;
    }

Now what I want is that when I choose let's say 12 files I want only 1 result to be stored for each of them and not 3 in the above case.

I did got it working but my code clearly is not good. I wrote this at 3 in the morning and took me 5 minutes because my only goal was to get it working.

    Map<?, ?> result = (Map<?, ?>) rpcClient.execute("SearchSubtitles", params);
    Object[] data = (Object[]) result.get("data");
    Map<?, ?>[] results = new Map<?, ?>[data.length];
    int i = 0;
    for (Object element : data) {
        System.out.println(element);
        results[i] = (Map<?, ?>) element;
        i++;
    }
    List<String> idmbIDs = new ArrayList<String>();
    for (Map<?, ?> map : results) {
        String string = (String) map.get("IDMovieImdb");
        if (!idmbIDs.contains(string))
            idmbIDs.add(string); //stores distinct idmb ids.
    }
    List<String> removedIDMBids = new ArrayList<String>();
    for (String store : idmbIDs) {
        for (Map<?, ?> map : results) {
            if (store.contains((String) map.get("IDMovieImdb")) && !removedIDMBids.contains(store)) {
                removedIDMBids.add(store);
                fileDetails.add(map);
            }
        }
    }
    for (Map<?, ?> realResult : fileDetails) {
        System.out.println(realResult); <- this does what I want
    }

I want a better way to do something like this. It would be great if I can get the most downloaded subtitles using the (map.get("SubDownloadsCnt");

Any help would be appreciated. Pardon me if I'm not able to explain it properly. and please don't neg.

Garis M Suero
  • 7,974
  • 7
  • 45
  • 68
  • Ok, well before asking us to fix your code up.... have you tried doing it yourself? What is your cleaned-up code after having spent more than fie minutes on it (at a time when you're well-rested)? – Taryn East Mar 04 '14 at 22:14
  • Secondly: Stack Overflow works best with specific technical problems. This is a very general question about refactoring your code... it doesn't fit as well. Can you perhaps reformulate your question to be a specific, technical question that has an answer, rather than "help me make my code better" ? – Taryn East Mar 04 '14 at 22:15

1 Answers1

1

I would rather create a Subtitle class with equals overriden (@Override) (re implemented), and there I will discriminate where to objects are equals or not.

Your Subtitle class will have all the properties that you get in the response, as SeriesIMDBParent, IDSubtitle, etc.

On that object you can create a constructor (or method load) that receives a Map<?, ?>[] parameter which you will use to load the values to to object. Or you can be smarter and user the Dozer Mapping, that will help you to do this job automatically.

And then your code will look something like:

    BeanMappingBuilder builder = new BeanMappingBuilder() {
        protected void configure() {
            mapping(Map.class, Subtitle.class, mapNull(false))
            .
            .
            .
        }
     }

After configuring the mapping you will have to make it possible with:

Map<String, Object> result = (Map<String, Object>) rpcClient.execute("SearchSubtitles", params);
Subtitle subtitle = new Subtitle();
mapper.map(result, subtitle)

;

After this and having implemented the equals and hashCode methods, you will be able to use a Set<Subtitle> (for example) which will force the Set to have unique objects based on the criteria you implemented to differentiate between objects.

Garis M Suero
  • 7,974
  • 7
  • 45
  • 68
  • "On that object you can create a constructor (or method load) that receives a Map, ?>[] parameter which you will use to load the values to to object." Could you please explain this again? And no, I will not be using the Dozer thing because I don't know what it is and I really don't have time to learn it. (This is project which I have to submit). Thank you so very much for answering. – user3380874 Mar 05 '14 at 00:31
  • Yes. I didn't knew about equals and hashcode Lol. Thanks! – user3380874 Mar 05 '14 at 22:47