Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.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 对流使用hashmap时的索引_Java_Indexing_Hashmap_Java Stream - Fatal编程技术网

Java 对流使用hashmap时的索引

Java 对流使用hashmap时的索引,java,indexing,hashmap,java-stream,Java,Indexing,Hashmap,Java Stream,我有一个团队的散列图需要打印出来。它们需要通过一些参数(不相关)进行索引和排序。除了索引部分,其他一切都很好,我在某种程度上得到了工作,但感觉不对劲 int i=0; public void printTable() { StringBuilder sb = new StringBuilder(); i = 0; table.keySet().stream() .map(key -> table.get(key))

我有一个团队的散列图需要打印出来。它们需要通过一些参数(不相关)进行索引和排序。除了索引部分,其他一切都很好,我在某种程度上得到了工作,但感觉不对劲

int i=0;

public void printTable()
{
    StringBuilder sb = new StringBuilder();

    i = 0;

    table.keySet().stream()
                .map(key -> table.get(key))
                .sorted(Comparator.comparing(Team::getPoints).thenComparing(Team::goalDifference).reversed().thenComparing(Team::getName))
                .forEach(team -> sb.append(String.format("%2d%s %-15s%5d%5d%5d%5d%5d\n", ++i, ".", team.getName(), team.getPlayed(),
                         team.getWins(), team.getDraws(), team.getLosses(), team.getPoints())));

    System.out.print(sb.toString());
}
有更好的方法吗?我认为Intstream在这里没有帮助,因为我无法使用索引从HashMap获取对象。

更新答案 应避免使用有状态流/lambda表达式。由于这个原因,我下面的原始答案是个坏主意

更好的方法是将流和打印分开

List<Team> teams = table.values()
        .stream()
        .sorted(...)
        .collect(Collectors.toList());

StringBuilder sb = new StringBuilder();
for(int i=0; i<teams.size(); i++) {

    Team team = teams.get(i);
    sb.append(String.format("%2d. %-15s%5d%5d%5d%5d%5d\n", 
            i,
            team.getName(),
            team.getPlayed(),
            team.getWins(),
            team.getDraws(),
            team.getLosses(), 
            team.getPoints()));
}

System.out.println(sb.toString());
AtomicInteger
将在不更改引用/修改原语的情况下为您提供可变性。您不需要在映射中进行查找,您可以直接对值进行迭代

编辑


正如@Eugene在评论中指出的,如果您使用并行流,则不能使用带有
AtomicInteger
的方法。

我会将排序与打印分开

List<Team> teams = table.values()
        .stream()
        .sorted(...)
        .collect(Collectors.toList());

StringBuilder sb = new StringBuilder();
for(int i=0; i<teams.size(); i++) {

    Team team = teams.get(i);
    sb.append(String.format("%2d. %-15s%5d%5d%5d%5d%5d\n", 
            i,
            team.getName(),
            team.getPlayed(),
            team.getWins(),
            team.getDraws(),
            team.getLosses(), 
            team.getPoints()));
}

System.out.println(sb.toString());
分类:

List<Team> sorted = table.values().stream()
    .sorted(Comparator.comparing(Team::getPoints)
            .thenComparing(Team::goalDifference)
            .reversed()
            .thenComparing(Team::getName))
    .collect(Collectors.toList());
如果
团队
类有一个接受位置并返回格式化字符串的方法,则可以改进这一点:

public String formatWithPosition(int position) {
    return String.format("%2d%s %-15s%5d%5d%5d%5d%5d", 
            position, ".", 
            name, played, wins, draws, losses, points);
}
然后,您可以按如下方式使用它:

String table = IntStream.range(0, sorted.size())
    .mapToObj(Team::formatWithPosition)
    .collect(Collectors.joining("\n"));

这是错误的。简化
Stream.of(“a”、“b”、“c”、“d”).map(x->i.incrementAndGet()+“-”+x).parallel().forEach(System.out::println)
一个可能的结果
2-d
1-c
是完全可能的,但是如果您知道并行流会失败,并且您反对它,您可以使用
int[]
使用单个值而不是
AtomicInteger
这一事实是一个实现细节,即它恰好可以通过顺序流执行所需的操作。无论这里的execution mode.OP是什么,都不能保证
map
函数是按遭遇顺序计算的。我在另一个线程中看到,使用并行流会给我错误的结果,而使用AtomicInteger目前还可以,因为我不需要执行并行流。你的和@federico对我来说都很好,我选择你的是因为它更简单。只是关于另一种方法的附带问题。我知道ArrayList的get方法的复杂度为O(1),LinkedList的复杂度为O(n)。列表的获取方法复杂度是多少?如果不是O(1),那么这种方法就没有意义了,因为我们在列表中循环了n*n次。没关系。为了回答我自己的问题,在另一个线程中,我看到当我们执行
.collect(Collectors.toList())
时,“对于返回的列表的类型、可变性、序列化性或线程安全性没有保证”。为了得到我们想要的实现,我们可以执行
.collect(collector.toCollection(()->new ArrayList())
String table = IntStream.range(0, sorted.size())
    .mapToObj(Team::formatWithPosition)
    .collect(Collectors.joining("\n"));