Декартово пересечение произвольных множеств в Java

Вы можете использовать ServerHttpRequest в качестве параметра метода для получения uri:

@RestController
public class GreetingController {
  @GetMapping("/greeting")
  public Mono getGreeting(ServerHttpRequest serverHttpRequest) {
    return Mono.just(new Greeting("greeting", serverHttpRequest.getURI().toString()));
  }
}

Предпочтительно linkToCurrentResource должен понимать заголовки X-Forwarded-???, если работает за балансировщиком нагрузки.

blockquote>

Затем вы можете выставить ForwardedHeaderTransformer @Bean.

Из документации:

Извлечь значения из заголовков «Forwarded» и «X-Forwarded-*», чтобы переопределить запрос URI (то есть HttpRequest.getURI()), чтобы он отражал составленный протокол и адрес.

blockquote>
@Configuration
open class MvcConfig {
    @Bean
    open fun forwardedHeaderTransformer() = ForwardedHeaderTransformer()
}

Вот несколько тестов:

@ExtendWith(SpringExtension::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
        properties = ["server.port=4333"])
class GreetingController2Test {
    @Autowired
    private lateinit var restTemplate: TestRestTemplate

    @Test
    fun `should return uri`() {
        val responseEntity = restTemplate.getForEntity("/greeting", Greeting::class.java)
        val greeting = responseEntity.body!!
        assertEquals("http://localhost:4333/greeting", greeting.uri)
    }

    @Test
    fun `should return uri composed from forwarded-??? headers`() {
        val headers = HttpHeaders()
        headers["X-Forwarded-Host"] = "external-uri.com"
        headers["X-Forwarded-Proto"] = "https"
        headers["X-Forwarded-Prefix"] = "/prefix"

        val httpEntity = HttpEntity(null, headers)
        val responseEntity = restTemplate.exchange("/greeting", HttpMethod.GET, httpEntity, Greeting::class.java)
        val greeting = responseEntity.body!!
        assertEquals("https://external-uri.com/prefix/greeting", greeting.uri)
    }
}

И Greeting.kt:

data class Greeting(
        val g: String? = null,
        val uri: String? = null
)

45
задан Saeed Amiri 21 April 2012 в 19:44
поделиться

4 ответа

Править: Удалены предыдущие решения для двух наборов. См. историю редактирования для деталей.

Вот способ сделать это рекурсивно для произвольного числа наборов:

public static Set<Set<Object>> cartesianProduct(Set<?>... sets) {
    if (sets.length < 2)
        throw new IllegalArgumentException(
                "Can't have a product of fewer than two sets (got " +
                sets.length + ")");

    return _cartesianProduct(0, sets);
}

private static Set<Set<Object>> _cartesianProduct(int index, Set<?>... sets) {
    Set<Set<Object>> ret = new HashSet<Set<Object>>();
    if (index == sets.length) {
        ret.add(new HashSet<Object>());
    } else {
        for (Object obj : sets[index]) {
            for (Set<Object> set : _cartesianProduct(index+1, sets)) {
                set.add(obj);
                ret.add(set);
            }
        }
    }
    return ret;
}

Обратите внимание, что невозможно хранить любую универсальную информацию типа с возвращенными наборами. Если бы Вы знали заранее, из какого количества наборов Вы хотели взять продукт, Вы могли определить универсальный кортеж для содержания этого много элементов (например, Triple<A, B, C>), но нет никакого способа иметь произвольное число универсальных параметров в Java.

35
ответ дан Andrea Ligios 26 November 2019 в 21:02
поделиться

Количество наборов могло бы варьироваться так, я не могу сделать этого во вложенном цикле foreach.

Две подсказки:

  • A x B x C = A x (B x C)
  • Рекурсия
12
ответ дан Michael Borgwardt 26 November 2019 в 21:02
поделиться

Да, существует Функциональный Java.

Для набора (наборов):

s.bind (P.p2 (), s);

1
ответ дан 26 November 2019 в 21:02
поделиться

Память (и обрабатывающий) место, необходимое для Декартова произведения, может выйти из-под контроля довольно быстро. Наивная реализация может исчерпать память и занять много времени. Было бы хорошо знать операции, которые Вы планируете выполнить в таком наборе для предложения стратегии реализации.

В любом случае сделайте что-то как Наборы. SetView на наборах Google. Это - набор, который поддерживается другими наборами, поскольку они добавляются. Идея для их проблемы там состоит в том, чтобы избежать вызова addAll. Идея для Вашей проблемы состоит в том, чтобы не делать NxMxK, добавляет к набору.

Наборы Google могут быть найдены здесь, и упомянутый класс здесь

0
ответ дан H Marcelo Morales 26 November 2019 в 21:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: