用Java正确处理最后一块数据.布尔标记或带外索引



我有一个数组列表,其中包含(I)ndex、(C)ategory、(S)ubcategory和(V)value。

I C S V
0 1 1 A
1 1 1 B
2 1 2 C
3 1 3 D
4 1 3 E
5 2 1 F
6 2 1 G
7 2 2 H
8 2 J

我需要处理AB,然后是C,然后是DE。然后处理AB+C+DE,重复操作2,依此类推。最后用写一个输出文件

 AB+C+DE
 FG+HJ

请不要将*+字面上解释为乘积和总和。

public void translate(List<String[]> raw) {
    int oldCategory = 0;
    int newCategory = 0;
    int oldSubCategory = 0;
    int newSubCategory = 0;        
    boolean keepWorking = true;     
    do {        
        oldCategory = newCategory;
        newCategory = getNewCategory(oldCategory, raw); //get end of category. Now it returns 5, then 9.            
         do {               
            oldSubCategory = newSubCategory;    
            newSubCategory = getNewSubCategory(oldSubCategory, raw);            
            List<String> products = doFirstOperation(raw, oldCategory, newCategory, oldSubCategory, newSubCategory); //A*B, D*E, etc.
            } while (newSubCategory< newCategory);              
            doSecondOperation(products); // compute "A*B+C+D*E" and append it to file
        }   while (newCategory < raw.size());           
    }           

如果当前类别是最后一个,则getNewCategory(oldCategory, raw)返回新类别或数组.size()中第一个元素的索引。在当前的设置中,我通常在Category的范围之外设置newSubCategory。这是在请求一个ArrayIndexOutOfBoundsException。我可以使用令牌boolean isLastCategory、dowhile(!isLastCategory)并返回newCategory作为给定类别中最后一个元素的索引,但这看起来很庞大。

组织这样的代码的好方法是什么?

这种模式在某些地方被称为"级联报告中断"。这里有一种可能的方法,在伪代码中:

curCat = null
curSub = null
while rec = read()
    if (rec.cat != curCat)
        if (curCat != null)
            endCat()
        startCat()
    else if (rec.sub != curSub)
        endSub()
        startSub()
    accumulate rec
end while
if (curCat != null)
    endCat()
function startCat()
    curCat = rec.cat
    initialize cat accumulator
    startSub()
function startSub()
    curSub = rec.sub
    initialize sub accumulator
function endSub()
    finalize subcategory
function endCat()
    endSub()
    finalize category

如果你不喜欢空检查浪费(它们只适用于文件的开头),你可以使用以下替代方法:

rec = read()
if (!EOF)   
    startCat() 
    while rec = read()
        if (rec.cat != curCat)
            endCat()
            startCat()
        else if (rec.sub != curSub)
            endSub()
            startSub()
        accumulate rec
    end while
    endCat()

根据OOP的性质和封装需要进行调整。

顺便说一句,这可以追溯到20世纪60年代和COBOL报告编写程序,但仍然是将嵌套中断和累积概念化的一种巧妙方式。

如果您使用Java8,以下是实现的方法

    List<Model> models = new ArrayList<>();
    models.add(new Model("0", "1", "1", "A"));
    models.add(new Model("1", "1", "1", "B"));
    models.add(new Model("2", "1", "2", "C"));
    models.add(new Model("3", "1", "3", "D"));
    models.add(new Model("4", "1", "3", "E"));
    models.add(new Model("5", "2", "1", "F"));
    models.add(new Model("6", "2", "1", "G"));
    models.add(new Model("7", "2", "2", "H"));
    models.add(new Model("8", "2", "2", "J"));
    Map<String, Map<String, List<Model>>> map = models.stream()
            .collect(groupingBy(Model::getCategory, groupingBy(Model::getSubCategory)));
    List<String> strings = map.values().stream()
            .map(submap -> submap.values().stream()
                    .map(list -> list.stream().map(Model::getValue).collect(joining("*"))).collect(joining("+")))
            .collect(toList());
    System.out.println(strings);

输出

[A*B+C+D*E, F*G+H*J]

最新更新