Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
可以将Java列表拆分为三个而不循环吗?_Java_List - Fatal编程技术网

可以将Java列表拆分为三个而不循环吗?

可以将Java列表拆分为三个而不循环吗?,java,list,Java,List,给出了一个包含21个元素的Java列表 创建三个新列表的最佳方法是: A = 0, 3, 6, ... indexed elements from source B = 1, 4, 7, ... C = 2 ,5, 8, 11, 14, 17, 20 不循环是否可能?您可以编写一个包装类,该类能够在给定倍数(本例中为3)和偏移量(0、1和2)的列表上提供只读“视图”。当要求在特定索引处输入项目时,它必须乘以“倍数”并添加偏移量,然后查看原始列表。(其他操作也是如此。) 不过,循环会更简单。。

给出了一个包含21个元素的Java列表

创建三个新列表的最佳方法是:

A = 0, 3, 6, ... indexed elements from source
B = 1, 4, 7, ... 
C = 2 ,5, 8, 11, 14, 17, 20
不循环是否可能?

您可以编写一个包装类,该类能够在给定倍数(本例中为3)和偏移量(0、1和2)的列表上提供只读“视图”。当要求在特定索引处输入项目时,它必须乘以“倍数”并添加偏移量,然后查看原始列表。(其他操作也是如此。)


不过,循环会更简单。。。这里的背景是什么?你到底想达到什么目的?

不幸的是,我想不出一种方法来做到这一点,而不假装数组是列表,正在执行以下操作

String[] twentyOne = new String[21];

String[] first = new String[3];
first[0] = twentyOne[0];
first[1] = twentyOne[3];
first[2] = twentyOne[6];
//  And so on

String[] second = new String[3];
second[0] = twentyOne[1];
second[1] = twentyOne[4];
second[2] = twentyOne[7];

String[] third = new String[15];
third[0] = twentyOne[2];
// You get the picture
我在示例中只使用了数组,因为我对它们更有信心,并且不需要看什么就知道它们


我可以问你为什么要避免循环吗?

这里有一个Jon提到的例子(当然,如果你真的不想循环的话)。名字不太好。。。我不知道这样的事情会有什么好名字

public class OffsetList<E> extends AbstractList<E> {

  private final List<E> delegate;
  private final int offset;
  private final int multiple;

  public static <E> OffsetList<E> create(List<E> delegate, int offset, int multiple) {
    return new OffsetList<E>(delegate, offset, multiple);
  }

  private OffsetList(List<E> delegate, int offset, int multiple) {
    this.delegate = delegate;
    this.offset = offset;
    this.multiple= multiple;
  }

  @Override public E get(int index) {
    return delegate.get(offset + (index * multiple));
  }

  @Override public int size() {
    int offsetToEnd = delegate.size() - offset;
    return (int) Math.ceil(offsetToEnd / (double) multiple);
  }
}
公共类偏移列表扩展了抽象列表{
非公开最终名单代表;
私人最终整数偏移;
私人最终整数倍数;
公共静态偏移列表创建(列表委托、整数偏移、整数倍){
返回新的偏移列表(委托、偏移、多个);
}
专用偏移列表(列表委托、整数偏移、整数倍){
this.delegate=委托;
这个偏移量=偏移量;
这个。多=多;
}
@覆盖公共E-get(int索引){
返回delegate.get(偏移量+(索引*倍数));
}
@重写公共整型大小(){
int offsetToEnd=delegate.size()-offset;
返回(整数)数学单元(偏移结束/(双)倍数);
}
}
示例用法:

List<Integer> numbers = // the numbers 0 to 21 in order
List<Integer> first = OffsetList.create(numbers, 0, 3);
List<Integer> second = OffsetList.create(numbers, 1, 3);
List<Integer> third = OffsetList.create(numbers, 2, 3);

System.out.println(first); // [0, 3, 6, 9, 12, 15, 18, 21]
System.out.println(second); // [1, 4, 7, 10, 13, 16, 19]
System.out.println(third); // [2, 5, 8, 11, 14, 17, 20]
List number=//按顺序排列数字0到21
List first=OffsetList.create(数字0,3);
List second=OffsetList.create(数字1,3);
第三个列表=OffsetList.create(数字,2,3);
System.out.println(第一个);//[0, 3, 6, 9, 12, 15, 18, 21]
System.out.println(秒);//[1, 4, 7, 10, 13, 16, 19]
System.out.println(第三个);//[2, 5, 8, 11, 14, 17, 20]

创建每个列表是O(1),因为它们是视图。迭代每个列表是O(n),其中n是实际视图列表的大小,而不是它所基于的完整列表的大小。这假设原始列表是一个随机访问列表。。。这种方法,就像基于索引的迭代一样,对于链表来说是非常低效的。

如果你说你已经习惯了函数式编程,我会假设你想要分割列表,因为你想对每个列表做不同的事情。如果是这种情况,我会将过滤逻辑放在
迭代器
级别

您可以使用换行迭代器而不是换行
列表
。它可能看起来像这样:

public <T> Iterable<T> filter(final Iterable<T> allElements, final int offset, final int multiple) {
    return new Iterable<T> {
        public Iterator<T> iterator() {
            return new Iterator<T> {
                int index = 0;
                Iterator<T> allElementsIt = allElements.iterator();

                public boolean hasNext() {

                    while (allElementsIt.hasNext()) { 
                       if ( isDesiredIndex(index) ) {
                           return true;
                       } else {
                           allElementsIt.next();
                           index++;
                       }
                    }
                    return false;
                }

                private boolean isDesiredIndex(int index) {
                    return (index - offset) % multiple == 0;
                }

                public T next() {
                    if ( hasNext() ) {
                        return allElementsIt.next();
                    } else {
                        throw NoSuchElementException();
                    }
                }

                public void remove() {...}
            }
        }
    }
 }
下次尝试:)


也可以看到这一点。

即使您选择的抽象看起来不像循环,循环也会发生。如果是,我想知道如何发生!如果你只想要三张七张的单子(我想)是可能的。但是你为什么不想循环呢?事实上,你不能硬编码索引吗?我喜欢方便的抽象,而且我习惯于函数式编程。我知道最终需要做一个循环,但我宁愿不去想它。@Annan:“我想抽象掉这个循环”和“我不想有循环”是完全不同的事情。您可以很容易地编写一个实用方法来为您执行循环,这样您就不需要在其他地方考虑它了。@jonskeettrue!这个问题措词不当。虽然我觉得这两个问题都很有趣!我的初衷是在做我自己的之前,看看是否有一个内置的方法来做我想做的事情。@MarkPeters:我不认为
列表。subList
实际上做了我想做的事情,是吗<代码>列表。子列表(0,3)将从原始列表中包装索引0,1,2,而不是根据需要包装索引0,3,6。事实上,我没有注意到这些是索引。删除和添加将使您出错,除非它是只读的view@ratchetfreak:这就是为什么我在回答中说只读视图。即使修改了原始列表,视图也应该没有问题。“当然,它们的大小会改变的。”棘轮怪胎:我想这是预期的行为。您正在按照原始文档中的索引显式定义结果列表。@ColinD您可以提出一种方法。在我知道OP为什么要做他们要求的事情之前,我不明白为什么这不是一个解决方案;如果你重读这个问题,它会说“有可能吗”-我的答案是否定的!谢谢你的否决:((不是)很抱歉,你对我的否决感到失望,但这只是一个糟糕的解决方案。一方面,当问题是关于列表时,它使用数组。另一方面,当它实际上可以使用循环在几行内完成整个操作时,它会手动设置索引值。另外,这显然是可能的,正如Jon的回答中所描述的那样。@Colin首先,你需要我的问题使用了循环的形式,现在你们告诉我,如果我使用循环,我的答案会更好!至于数组,正如我在回答中解释的,我不经常使用列表,所以在没有IDE的情况下,它会减慢我的回答,试图准确地编写语法,这并不是说列表不能很容易地用来代替数组安迪:他说手动展开循环并不比使用循环更可取。你使用的是编译时循环,这只是一个愚蠢的解决办法,因为它会让程序员执行循环。也许科林和我更喜欢实用的解决方案,而不是开玩笑的解决方案。这一点是可以接受的。尽管这不是一个更可取的方法在我看来,这是一个很好的解决方案。我并不知道这是一种循环的形式,而且这是我能想到的最简单、最快捷的方法!虽然我不会称之为开玩笑的解决方案,但我也喜欢实际的解决方案,作为一个例子
for ( ElementType element : filter(elements, 2, 3) ) {
    //do something to every third starting with third element
}
class Mod3Comparator implements Comparator<Integer> {
    public int compare(Integer a, Integer b) {
        if (a % 3 < b % 3 || (a % 3 == b % 3 && a < b)) {
            return -1;
        }
        if (a % 3 > b % 3 || (a % 3 == b % 3 && a > b)) {
            return 1;
        }
        return 0;
    }
}
Collections.sort(list, new Mod3Comparator());
Integer[] array = new Integer[list.size()]; 
list.toArray(array);
List<Integer> A = Arrays.asList(Arrays.copyOfRange(array, 0, 7));
List<Integer> B = Arrays.asList(Arrays.copyOfRange(array, 7, 14));
...