简体   繁体   English

我如何抽象Java for循环的通用部分,以避免重复/重复

[英]How do i abstract the common parts of Java for loop so as to avoid repetition/duplication

I have a method that receives a list of things, iterates the list and does XYZ things on every iteration. 我有一个方法,它接收事物列表,迭代该列表,并在每次迭代中执行XYZ事物。 The definition of "XYZ things" depends on the implementation or what I'm trying to achieve. “ XYZ事物”的定义取决于实现或我要实现的目标。 For some i just want to run some SQL that hits the database and updates customer name and invoice due date. 对于某些人,我只想运行一些SQL即可访问数据库并更新客户名称和发票到期日。 For others i just want to update tax amount, days past due etc. The situation is always different. 对于其他人,我只想更新税额,过期天数等。情况总是不同的。 How do i create just one reusable method rather than duplicate this method all over which isn't so much in-the-spirit of "OnceAndOnlyOnce". 我如何只创建一个可重用的方法,而不是重复使用此方法,而这并不是“ OnceAndOnlyOnce”的全部精神。

  DaoProvider daoProvider;

  public void buildAndUpdateCustomer(List<Object> list) {
    for (Object obj : list) {
      Map<String, Object> m = (Map<String, Object>) obj;
      Map<String, Object> args = new HashMap<>();
      for (Map.Entry<String, Object> x : m.entrySet()) {
        args.put(x.getKey(), x.getValue());
      }
      //these are my XYZ things...
      daoProvider.updateCustomerName();
      daoProvider.updateAgingMia();
    }
}


  public void buildAndUpdateTax(List<Object> list) {
    for (Object obj : list) {
      Map<String, Object> m = (Map<String, Object>) obj;
      Map<String, Object> args = new HashMap<>();
      for (Map.Entry<String, Object> x : m.entrySet()) {
        args.put(x.getKey(), x.getValue());
      }
      daoProvider.updateTaxAmount();
    }
}

  public void buildAndUpdateLedgerBal(List<Object> list) {
    for (Object obj : list) {
      Map<String, Object> m = (Map<String, Object>) obj;
      Map<String, Object> args = new HashMap<>();
      for (Map.Entry<String, Object> x : m.entrySet()) {
        args.put(x.getKey(), x.getValue());
      }
      daoProvider.updateLedgerBalance();
    }
}

You can move the common code to a private helper method: 您可以将通用代码移至私有帮助器方法:

@SuppressWarnings("unchecked")
private static Map<String, Object> getArgs(Object obj) {
    Map<String, Object> m = (Map<String, Object>) obj;
    Map<String, Object> args = new HashMap<>();
    for (Map.Entry<String, Object> x : m.entrySet()) {
        args.put(x.getKey(), x.getValue());
    }
    return args;
}

public void buildAndUpdateCustomer(List<Object> list) {
    for (Object obj : list) {
        Map<String, Object> args = getArgs(obj);
        // these are my XYZ things...
        daoProvider.updateCustomerName(args);
        daoProvider.updateAgingMia(args);
    }
}

public void buildAndUpdateTax(List<Object> list) {
    for (Object obj : list) {
        Map<String, Object> args = getArgs(obj);
        daoProvider.updateTaxAmount(args);
    }
}

public void buildAndUpdateLedgerBal(List<Object> list) {
    for (Object obj : list) {
        Map<String, Object> args = getArgs(obj);
        daoProvider.updateLedgerBalance(args);
    }
}

Or with Java 8 you can do it with lambdas: 或使用Java 8,您可以使用lambdas做到这一点:

@SuppressWarnings("unchecked")
private static void buildAndUpdate(List<Object> list, Consumer<Map<String, Object>> consumer) {
    for (Object obj : list) {
        Map<String, Object> m = (Map<String, Object>) obj;
        Map<String, Object> args = new HashMap<>();
        for (Map.Entry<String, Object> x : m.entrySet()) {
            args.put(x.getKey(), x.getValue());
        }
        consumer.accept(args);
    }
}

public void buildAndUpdateCustomer(List<Object> list) {
    buildAndUpdate(list, args -> {
        daoProvider.updateCustomerName(args);
        daoProvider.updateAgingMia(args);
    });
}

public void buildAndUpdateTax(List<Object> list) {
    buildAndUpdate(list, args -> daoProvider.updateTaxAmount(args));
}

public void buildAndUpdateLedgerBal(List<Object> list) {
    buildAndUpdate(list, args -> daoProvider.updateLedgerBalance(args));
}

I'm going to assume that args needs to be passed into the methods thusly: 我将假设需要将args传递到方法中:

public void buildAndUpdateCustomer(List<Object> list) {
    for (Object obj : list) {
      Map<String, Object> m = (Map<String, Object>) obj;
      Map<String, Object> args = new HashMap<>();
      for (Map.Entry<String, Object> x : m.entrySet()) {
        args.put(x.getKey(), x.getValue());
      }
      //these are my XYZ things...
      daoProvider.updateCustomerName(args);
      daoProvider.updateAgingMia(args);
    }
}

Then we can write a method: 然后我们可以编写一个方法:

public void buildAndProcess(List<Object> list, Consumer<Object> processor) {
    for (Object obj : list) {
      Map<String, Object> m = (Map<String, Object>) obj;
      Map<String, Object> args = new HashMap<>();
      for (Map.Entry<String, Object> x : m.entrySet()) {
        args.put(x.getKey(), x.getValue());
      }
      processor.accept(args);
    }
}

And your previous method becomes: 您以前的方法变为:

public void buildAndUpdateCustomer(List<Object> list) {
    buildAndProcess(list, args -> {
      //these are my XYZ things...
      daoProvider.updateCustomerName(args);
      daoProvider.updateAgingMia(args);
    });
}

This chunk of code is odd: 这段代码很奇怪:

Map<String, Object> m = (Map<String, Object>) obj;
Map<String, Object> args = new HashMap<>();
for (Map.Entry<String, Object> x : m.entrySet()) {
    args.put(x.getKey(), x.getValue());
}

It identical to Map<String, Object> args = new HashMap<>((Map<String, Object>) obj); 它等同于Map<String, Object> args = new HashMap<>((Map<String, Object>) obj);


I will reiterate what I said in the comments: 我将重申我在评论中所说的话:

Just loooking at your code, you have far too maybe Object - Java is a strongly typed language and when someone has so many Object and so much casting this is a screaming red flag. 只是看一下代码,您可能还有Object -Java是一种强类型的语言,并且当某人拥有如此多的Object并且太多的转换时,这是一个尖叫的危险信号。 Generally, one shouldn't see much usage of Object at all 通常,根本不应该看到Object太多使用

You seem to be using List<Object> and Map<String, Object> as essentially generic arguments - this is a really nasty antipattern, it removes all of the type safety the compiler provides and even removes the name checking. 您似乎在使用List<Object>Map<String, Object>作为本质上的通用参数-这是一个非常讨厌的反模式,它删除了编译器提供的所有类型安全性,甚至删除了名称检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM