Наиболее подходящее "2D" представление для хранения строки и двойного значения бок о бок в Java? - PullRequest
1 голос
/ 28 октября 2019

Я ищу тип данных, который может хранить как строку, так и двойник для ведения записей. Строка - это некоторый пароль, а двойная - некоторая оценка для этого пароля, определяемая после вставки пароля в структуру данных. Какой тип данных лучше всего подойдет для такой ситуации?

До сих пор я использовал ArrayList s, по одному на каждый бит данных, но дошло до того, что мне нужно реализовать сортировку поодна часть и логистика мне не особо нравятся.

Например:

private ArrayList<String> keys = ArrayList<String>();
private ArrayList<Double> scores = ArrayList<Double>();
// n and m determined at runtime

private void generateKeys(int m, int n) {
    for (int i = 0; i < m; i++) {
        keys.add(getRandomKey(n));
    }
}

private String getRandomKey(int n) {
    String key = "";
    String charValues = "abcdefghijklmnopqrstuvwxyz";
    int randIndex;
    for (int i = 0; i < n; i++) {
        randIndex = random.nextInt(26);
        key += charValues.charAt(randIndex);
    }
    return key;
}

private void generateScores() {
    for (int i = 0; i < size(keys); i++) {
        scores.add(findScore(keys.get(i)));
    }
}

private double findScore(String k) {
    // some function
}

Примером данных будет:

    key     score
"fsuifshu", 0.950
"wowaflsa", 0.120
"woawfjff", 0.430
"fireplfd", 0.040
...

keyвставляется сначала с использованием цикла и генератора случайных символов, затем score вычисляется после того, как каждый key уже вставлен. Я хочу иметь возможность перемещать их (сортировка на основе score).

В конечном счете, я хочу иметь возможность сортировать ключи на основе их оценки. Таким образом, ожидаемый результат, основанный на вышеупомянутом, будет:

"fsuifshu"
"woawfjff"
"wowaflsa"
"fireplfd"

Сортированный ArrayList будет содержать это, например.

Ответы [ 3 ]

4 голосов
/ 28 октября 2019

Вы хотите использовать java.util.Map. Он хранит пары ключ-значение.

Map<String, Double> map = new HashMap<>();

map.put("foo", 1.0D);
2 голосов
/ 28 октября 2019

Хотя карта кажется подходящей с первого взгляда, я бы порекомендовал отдельный класс, так как вы планируете сортировать свои данные.

public class MyDataHolder{

     String pass;
     double score;
    // getters & setters
 }

Затем вы можете сохранить свои объекты в списке

List<MyDataHolder> myEntries;

И сортировать по баллам или баллам

0 голосов
/ 28 октября 2019

Я категорически не согласен с ответом Джейсона и не буду помещать данные в карту по нескольким причинам:

  1. Я считаю, что вам следует избегать использования карт в качестве ленивого способа представления вашегоданные домена. Я считаю, что гораздо лучше создавать собственные классы домена для хранения данных вашего домена. Вы можете намного лучше использовать четко определенный объект, например, легко помещать его в другие структуры данных или передавать его в качестве аргумента функции, при этом все четко понимая данные.

  2. Если в будущем вам понадобятся дополнительные метаданные о пароле, структура данных карты будет разрушена и потребуется много доработок, тогда как с классом домена вы можете просто добавить другое поле, и больше ничего не нужно менять.

  3. Карты, как правило, не предназначены для сортировки структур данных. Существуют структуры карт, которые поддерживают порядок вставки или сортировки по ключам, но сортировка по значениям особенно странна. Вы можете принудительно заставить данные сортироваться любым способом, каким вы хотите (например, здесь показано ), но я бы не стал пытаться "заковывать" структуры в то, для чего они не предназначены.

Вот пример того, что я хотел бы сделать:

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

public class Main {
    public static void main(String[] args) {
        List<PasswordWithScore> passwords = new ArrayList<>();

        int numberOfPasswords = 5;
        int lengthOfPassword = 5;

        Random rand = new Random();
        String chars = "abcdefghijklmnopqrstuvwxyz";

        for (int i = 0; i < numberOfPasswords; i++) {
            StringBuilder password = new StringBuilder();
            for (int j = 0; j < lengthOfPassword; j++) {
                password.append(chars.charAt(rand.nextInt(chars.length())));
            }
            passwords.add(new PasswordWithScore(password.toString()));
        }

        passwords.sort(Comparator.comparing(PasswordWithScore::getScore).reversed());
        System.out.println(passwords);
    }
}

/** Your domain class */
public class PasswordWithScore {
    private final String password;
    private final double score;

    public PasswordWithScore(String password) {
        this.password = password;
        this.score = findScore(password);
    }

    public String getPassword() { return password; }
    public double getScore() { return score; }

    @Override public String toString() {
        return password + ":" + score;
    }

    private static double findScore(String password) {
        // but different
        return password.chars().sum();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...