Avoiding multiple If statements in Java

后端 未结 13 783
北恋
北恋 2020-12-30 07:52

I\'ve coded a method something like this. But I guess this should undergo refactoring. Can any one suggest the best approach to avoid using this multiple if statements?

相关标签:
13条回答
  • 2020-12-30 08:03

    Just to mention it: A direct equivalent to your code would not be using a map for direct lookup (since that would require each extension to have exactly 3 characters) but a for loop:

    ...
    Map<String, String> extmap = GetExtensionMap();
    for (Map.Entry<String,String> entry: extmap.entrySet())
      if (fileName.endsWith(entry.getKey))
        return entry.getValue();
    ...
    

    This solution works with extensions of any length but is less performant than the hash lookup of course (and slightly less performant than the original solution)

    The Algorithmic-Design-Guy solution

    A more performant way would be to implement a tree structure starting with the last character of the extension and storing the appropriate MIME types at the respective nodes. You could then walk down the tree starting with the last character of the file name. But this is probably an overkill ...

    0 讨论(0)
  • 2020-12-30 08:05

    How about mapping the extensions to MIME types, then using a loop? Something like:

    Map<String,String> suffixMappings = new HashMap<String,String>();
    suffixMappings.put(".pdf", "application/pdf");
    ...
    
    private String getMimeType(String fileName){
        if (fileName == null) {
            return "";   
        }
        String suffix = fileName.substring(fileName.lastIndexOf('.'));
        // If fileName might not have extension, check for that above!
        String mimeType = suffixMappings.get(suffix); 
        return mimeType == null ? "text/plain" : mimeType;
     } 
    
    0 讨论(0)
  • 2020-12-30 08:06

    There is no way to evade that in general. In your case - if there is a set of allowed extensions - you could create an Enum, convert the extension to the Enum type via valueOf(), and then you can switch over your enum.

    0 讨论(0)
  • 2020-12-30 08:08

    Using a HashMap perhaps?

    This way you could do myMap.get(mystr);

    0 讨论(0)
  • 2020-12-30 08:09

    Command pattern is the way to go. Here is one example using java 8:

    1. Define the interface:

    public interface ExtensionHandler {
      boolean isMatched(String fileName);
      String handle(String fileName);
    }
    

    2. Implement the interface with each of the extension:

    public class PdfHandler implements ExtensionHandler {
      @Override
      public boolean isMatched(String fileName) {
        return fileName.endsWith(".pdf");
      }
    
      @Override
      public String handle(String fileName) {
        return "application/pdf";
      }
    }
    

    and

    public class TxtHandler implements ExtensionHandler {
      @Override public boolean isMatched(String fileName) {
        return fileName.endsWith(".txt");
      }
    
      @Override public String handle(String fileName) {
        return "txt/plain";
      }
    }
    

    and so on .....

    3. Define the Client:

    public class MimeTypeGetter {
      private List<ExtensionHandler> extensionHandlers;
      private ExtensionHandler plainTextHandler;
    
      public MimeTypeGetter() {
        extensionHandlers = new ArrayList<>();
    
        extensionHandlers.add(new PdfHandler());
        extensionHandlers.add(new DocHandler());
        extensionHandlers.add(new XlsHandler());
    
        // and so on
    
        plainTextHandler = new PlainTextHandler();
        extensionHandlers.add(plainTextHandler);
      }
    
      public String getMimeType(String fileExtension) {
        return extensionHandlers.stream()
          .filter(handler -> handler.isMatched(fileExtension))
          .findFirst()
          .orElse(plainTextHandler)
          .handle(fileExtension);
      }
    }
    

    4. And this is the sample result:

      public static void main(String[] args) {
        MimeTypeGetter mimeTypeGetter = new MimeTypeGetter();
    
        System.out.println(mimeTypeGetter.getMimeType("test.pdf")); // application/pdf
        System.out.println(mimeTypeGetter.getMimeType("hello.txt")); // txt/plain
        System.out.println(mimeTypeGetter.getMimeType("my presentation.ppt")); // "application/vnd.ms-powerpoint"
      }
    
    0 讨论(0)
  • 2020-12-30 08:11

    You can always use a Groovy class here as it allows for switch-case on Strings :)

    0 讨论(0)
提交回复
热议问题